Balloon Analysis#

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")
drawing = Drawing.from_json(str(_DATA_DIR / "2902060102_--A_DEF01_LH SUPPORT ACCUMULATOR ASSEMBLY.json"))
featured_drawing = FeaturedDrawing(drawing, language_configs=[DEFAULT_FRENCH_CONFIG, DEFAULT_ENGLISH_CONFIG])
featured_sheet = featured_drawing.sheets[1]
featured_view = featured_sheet.views[2]
featured_view.plot_data_balloons().plot()
featured_view.plot_data_balloon_flags().plot()
featured_sheet.plot_data_balloons().plot()
featured_sheet.plot_data_balloon_flags().plot()

Analyze balloon symbols (callouts) in technical drawings: detect parent/child groups, identify multiplicator and for-info flags, and extract view repetitions.

Access#

Balloons are analyzed at the view level and exposed as cached_property:

# Per view
featured_view.balloons        # list[Balloon]
featured_view.balloon_count   # int

# Aggregated across all views of a sheet
featured_sheet.balloons       # list[Balloon]

Visualization is available at both levels:

featured_view.plot_data_balloons().plot()       # single view
featured_view.plot_data_balloon_flags().plot()   # flag symbols highlighted

featured_sheet.plot_data_balloons().plot()       # all views on the sheet
featured_sheet.plot_data_balloon_flags().plot()   # flag symbols highlighted

Note

All visualization methods shown in this guide at the view level (plot_data_balloons, plot_data_balloon_flags) have an equivalent at the sheet level on FeaturedSheet. See Display & Report Methods for the complete list of display and report methods.

Pipeline#

The ViewBalloonAnalyzer runs a four-step pipeline per view:

  1. Extract: Collect TypeBalloon symbols from the view annotations — plus circular, numerically-labelled TypeNote symbols that some drawings use as balloons (see Circled Notes Detected as Balloons below)

  2. Group: Build a proximity graph and assign parent/child/isolated roles

  3. Assign flags: Detect multiplicator (X3) and for-info (PM/FM) symbols, assign to nearest balloon

  4. Assign repetitions: Read the view title’s repetition count (e.g. “VALABLE 6 FOIS”)

Circled Notes Detected as Balloons#

Some drawings draw a balloon as a TypeNote symbol with a circular (CIRCLE) frame instead of a genuine TypeBalloon. ViewBalloonAnalyzer recovers these circular, numerically-labelled notes, but only when they group with a genuine balloon, so unrelated notes are not picked up. Each balloon exposes its origin via balloon.type_symbol ("TypeBalloon" or "TypeNote").

The sheet below mixes both: two genuine balloons and four balloons recovered from circled notes.

Source: condor_TEMP_332P641283_--A_DRW01_FORMATION_LIGHT_ASSY.json, sheet [3] (PL.04)

In this sheet:

  • Genuine balloons (type_symbol == "TypeBalloon"): 116 (parent), 117 (isolated)

  • Recovered from circled notes (type_symbol == "TypeNote", CIRCLE frame): 105, 106, 110, 111 (all children)

The overlay colors encode the group status (parent / child / isolated), not the symbol origin; the origin is read from balloon.type_symbol.

Grouping#

Balloons are grouped based on spatial proximity. Visualizations use color-coded highlights:

  • Blue: parent balloon (has leader arrows)

  • Green: child balloon (no arrows, linked to a parent)

  • Orange: isolated balloon (standalone)

Grouping Criteria#

Two balloons are considered groupable if they meet all three criteria:

  1. Similar size: Diameter difference < 10%

  2. Close enough: Distance between centers < 3 x average radius

  3. Almost aligned: Horizontal OR vertical misalignment < 1 x average radius

Group Status#

Each balloon receives a group status after analysis:

  • “parent”: Has leader arrows and is the group’s reference balloon

  • “child”: No leader arrows, linked to a parent (inherits the parent’s leaders via effective_leader_count)

  • “isolated”: Standalone balloon, not part of any group

  • “undefined”: Edge case — group has 0 or multiple parents

View Repetition#

When a view title contains a repetition count (e.g. “VALABLE 2 FOIS”, “VALID 2 TIMES”), all balloons in that view inherit this value via balloon.repetition. The plot_data_balloons() visualization shows this as a “Rep” label below each balloon.

Source: 2902060102 LH SUPPORT ACCUMULATOR ASSEMBLY, Sheet 1 — COUPE C2-C2 REDRESSEE (5 balloons, all with Rep 2)

Flag Detection#

Multiplicator (X3) and for-info (PM/FM) flags are detected and assigned to their nearest balloon. The plot_data_balloons() view shows the flags on each balloon.

Multiplicator Flags#

Indicate that a balloon reference appears multiple times in the assembly.

  • Pattern: X3, x12, 14X, 21x (letter X + digits, case-insensitive)

  • Filtering: Only horizontal text; must be within 3x the nearest balloon’s diameter

  • Properties: balloon.multiplicator (int | None), balloon.multiplicator_symbol (Symbol | None)

For-Info Flags (PM/FM)#

Mark balloons as informational — different verification rules apply.

  • PM = Pour Memoire / FM = For Memory

  • Detection: Two text elements “PM”+”FM”, or single element “PM”, “PM/FM”, “PR/FM”

  • Properties: balloon.has_for_info_flag (bool), balloon.for_info_flag_symbol (Symbol | None)

Balloon Properties#

Property

Type

Description

text_content

str

The balloon’s text (e.g. “024”, “101”)

type_symbol

str

Underlying symbol type: “TypeBalloon”, or “TypeNote” for a balloon recovered from a circled note

center

Point2D

Center position

diameter / radius

float

Balloon size

leader_count

int

Number of leader arrows directly attached

effective_leader_count

int

Effective leaders (own for parent/isolated, parent’s for children)

group_status

str

“parent”, “child”, “isolated”, or “undefined”

parent_balloon

Balloon | None

Reference to parent (None for parent/isolated)

multiplicator

int | None

Multiplier value (e.g. 3 for “X3”)

has_for_info_flag

bool

True if PM/FM flag is attached

repetition

int | None

Repetition count from the view title

drawing_address

str

Drawing grid address

Examples#

Access balloons per view:

from drawing_tools.sheet.featured_sheet import FeaturedSheet

for featured_view in featured_sheet.views:
    if featured_view.balloons:
        print(f"{featured_view.view.name} ({featured_view.balloon_count} balloons):")
        for balloon in featured_view.balloons:
            print(f"  '{balloon.text_content}' — {balloon.group_status}")

Find parent/child groups:

for featured_view in featured_sheet.views:
    parents = [b for b in featured_view.balloons if b.group_status == "parent"]
    for parent in parents:
        children = [
            b for b in featured_view.balloons
            if b.group_status == "child" and b.parent_balloon is parent
        ]
        if children:
            print(f"Parent '{parent.text_content}': {[c.text_content for c in children]}")

Find flagged balloons:

with_mult = [b for b in featured_sheet.balloons if b.multiplicator is not None]
for_info = [b for b in featured_sheet.balloons if b.has_for_info_flag]

Visualization Script#

python scripts/balloons.py