Aircraft Reference Lines#

from pathlib import Path
from dessia_drawing.core import Drawing
from drawing_tools.config.default_language_configs import DEFAULT_ENGLISH_CONFIG, DEFAULT_FRENCH_CONFIG
from drawing_tools.featured_drawing import FeaturedDrawing

_DATA_DIR = Path("data/json")
_LANGUAGE_CONFIGS = [DEFAULT_FRENCH_CONFIG, DEFAULT_ENGLISH_CONFIG]

formation_drawing = Drawing.from_json(
    str(_DATA_DIR / "condor/condor_TEMP_332P641283_--A_DRW01_FORMATION_LIGHT_ASSY.json")
)
formation = FeaturedDrawing(formation_drawing, language_configs=_LANGUAGE_CONFIGS)
featured_sheet = formation.sheets[1]
featured_sheet.plot_data_aircraft_reference_lines().plot()

An assembly drawing states where the drawn part sits in the aircraft with reference lines: dash-dot lines drawn along a drawing axis, each carrying a label that names an aircraft axis and a coordinate — X 6815, Y-670, Z 1565.8. They are the coordinate grid of the positioning rule (structural elements helping positioning), and the subject of tickets DERY-3760 (the grid itself) and DERY-3761 (the text bound to each line).

See also

  • Aircraft Orientation Indicators — the other element of the positioning rule, detected in the same view/annotations/aircraft/ subpackage.

  • Section Line Indicators — the other family of lines a rule reads across the views of a sheet.

  • The script scripts/detect_aircraft_features.py in the repository, which reports this detection together with the orientation indicators, view by view, and opens both overlays.

What is a Reference Line?#

Two conventions hold on every drawing of the reference corpus, and they are what the detection keys on:

  • the label reads along its own line: a horizontal line carries a horizontal label, a vertical line a label rotated by a quarter turn;

  • the label sits against its line, within about one font size of it, somewhere along its length.

The label does the claiming. Its box, inflated by the tolerances — by the overhang along the text, by the gap across it — is the zone within which a dash-dot line of the same orientation is its line. A dash-dot line no label claims is not a reference line: it is an axis, a symmetry line, a hidden edge, and it takes no part.

A label is a reference label only when it reads as an uppercase axis letter followed by a signed number. Uppercase is what separates X 6815 from a quantity x10. Surrounding whitespace is absorbed by the pattern itself.

Accessing Reference Lines#

Reference lines are detected on each FeaturedView and aggregated at sheet and drawing level, like every other detection:

for featured_view in featured_sheet.views:
    for reference_line in featured_view.aircraft_reference_lines:
        print(featured_view.name, reference_line.axis, reference_line.value, reference_line.orientation)

all_lines_of_the_sheet = featured_sheet.aircraft_reference_lines

ReferenceLine Properties#

Property

Description

axis

The aircraft axis the line stands for: "X", "Y" or "Z".

value

The coordinate along that axis, as a signed float read from the label (6815.0, -670.0, 1565.8).

orientation

How the line is drawn on the sheet, "horizontal" or "vertical". Not to be confused with axis: on a top view a horizontal line may carry an X value, on a front view a Z value.

source_entity

The dash-dot Edge drawn on the sheet — also where drawing_address comes from.

label_entity

The Text primitive that claims the line; its raw content is label_entity.get_text_content().

bounding_rectangle

The box covering both the drawn line and its label, the one the overlay draws.

Tuning the Detection#

Every distance is expressed in font sizes of the label being tested, so the detection reads the same on an A4 detail and on an A0 assembly. The parameters live in ReferenceLineDetectionConfig:

Parameter

Meaning

dash_dot_curve_type

The curve_type an entity must declare to be a candidate ("DOTTED_DASHED").

orientation_tolerance

Aperture, as a sine, within which a direction counts as horizontal or vertical; applied to the lines and to the labels alike. Anything further off from both axes is oblique and takes no part.

max_label_gap_in_font_sizes

How far across the text a label may sit from its line and still claim it.

max_label_overhang_in_font_sizes

How far past a line’s end a label may sit and still run alongside it.

label_pattern

The compiled grammar of a label, capturing the axis letter and the value.

from drawing_tools.view.annotations.aircraft import ReferenceLineDetectionConfig, ViewReferenceLineDetector

permissive = ReferenceLineDetectionConfig(max_label_gap_in_font_sizes=2.0)
detector = ViewReferenceLineDetector(featured_sheet.views[3].view, config=permissive)
reference_lines = detector.reference_lines

Visualizing Reference Lines#

The companion overlay boxes each detected line with its label in one palette color per line, and states the axis, the value and the orientation in the caption. It is available on FeaturedView, FeaturedSheet and FeaturedDrawing under the selector Aircraft Reference Lines, and stacked into All Overlays with the other detections:

featured_view.plot_data_aircraft_reference_lines().plot()
featured_sheet.plot_data_aircraft_reference_lines().plot()
formation.plot_data_aircraft_reference_lines().plot()

On a whole sheet#

Called on a FeaturedSheet, the overlay covers every view at once: each reference line keeps its own color from one view to the next, so two lines of the same sheet never share a color merely because they sit in different views. On this sheet the left view carries the two X stations and a Z level of its assembly, the top view the same X stations and the Y 0 plane.

Source: condor_TEMP_332P641283_–A_DRW01_FORMATION_LIGHT_ASSY.json, Sheet 3 (6 reference lines)

formation.sheets[3].plot_data_aircraft_reference_lines().plot()

On a single view#

Called on a FeaturedView, the same overlay is drawn at the scale of that view, where the label, its claim zone and the dash-dot line it claims can be read one by one.

A top view of the assembly carries both horizontal and vertical lines: three Y planes read across, two X stations read up.

Source: condor_TEMP_332P641283_–A_DRW01_FORMATION_LIGHT_ASSY.json, Sheet 2, view VUE DE DESSUS APPAREIL (5 reference lines)

formation.sheets[2].views[3].plot_data_aircraft_reference_lines().plot()

An auxiliary view looks at the assembly from another side, so the same Y planes come back with two Z levels instead of the X stations — orientation says how each line is drawn on the sheet, axis what it stands for in the aircraft.

Source: condor_TEMP_332P641283_–A_DRW01_FORMATION_LIGHT_ASSY.json, Sheet 1, view VUE SUIVANT F1- (5 reference lines)

formation.sheets[1].views[7].plot_data_aircraft_reference_lines().plot()

See also

Display & Report Methods shows the sheet-level overlay among every other FeaturedSheet rendering, with its download link.

Going Further: Inside the Detection#

For readers who want to see how the detector works

Two classes carry this feature, both in view/annotations/aircraft/:

  • the featureReferenceLine (reference_lines.py), the value object described above, alongside ReferenceLineDetectionConfig and parse_reference_label;

  • the detectorViewReferenceLineDetector (view_reference_line_detector.py), which holds the recipe. FeaturedView.aircraft_reference_lines builds one per view and the sheet and drawing properties concatenate the results.

The recipe is short: every dash-dot entity of the view is tested, one criterion per guard, cheapest first.

def _identify_reference_line_from_entity(self, line: Entity) -> ReferenceLine | None:
    """Identify the reference line a dash-dot entity carries, if any.

    One criterion per guard, cheapest first: the entity must be a straight segment
    drawn horizontally or vertically, then a label of the same orientation must claim
    it.

    :param line: A dash-dot entity of the view.
    :return: The reference line, or ``None`` when a criterion eliminates the entity.
    """
    line_orientation = self._identify_line_orientation(line)
    if line_orientation is None:
        return None
    label = self._identify_claiming_label(line, line_orientation)
    if label is None:
        return None
    return ReferenceLine(
        axis=label.axis,
        value=label.value,
        orientation=line_orientation,
        source_entity=line,
        label_entity=label.entity,
    )

The two guards read as follows, each a method of its own:

  • _identify_line_orientation — a straight segment running along a drawing axis (helpers.geometry.orientation_from_direction), or nothing;

  • _identify_claiming_label — among the view’s reference labels of the same orientation (_reference_labels, computed once: uppercase axis letter, signed number, reading along an axis), the one whose claim zone reaches the line. The claim zone (_claim_zone) is the label’s box inflated by the two tolerances of the config, along the text and across it.

Everything else is bookkeeping: _dash_dot_entities selects the candidates by their declared curve type, and detect_all maps the guard over them.