drawing_tools.helpers.visualization package#

Production overlays (overlays/)#

drawing_tools.helpers.visualization.overlays.featured module#

Overlay builders for featured views and sheets.

Single home for the diagnostic overlays of FeaturedView / FeaturedSheet (balloons, bonding symbols, balloon flags, section lines, titles, auxiliary view indicators, aircraft reference lines, aircraft orientation indicators, tables, sets, view indexes). Every function receives the featured object and reads its public data; the dependency points from this visualization module to the featured classes, never the other way around. FeaturedView / FeaturedSheet keep only their @plot_data_view methods (platform display selectors), each delegating to the builders here.

DETECTION_VIEW_FRAME_LINE_WIDTH is the stroke width of the view frame build_detection_view_frame_primitive() draws in a detected element’s own color.

drawing_tools.helpers.visualization.overlays.featured.build_detection_view_frame_primitive(featured_view: FeaturedView, color: str, tooltip: str | None = None) → list#

Outline a view’s bounding rectangle in the color of an element detected inside it.

Ties an element to its view by color: reading the same color on the element’s box and on the frame around the view is what confirms the element was detected in THAT view, which a sheet-level overlay cannot otherwise show. Outline only, no fill, so the drawing underneath stays readable.

Parameters:
  • featured_view – The view to outline.

  • color – The color of the element detected in it.

  • tooltip – Optional tooltip shown when the frame is clicked.

Returns:

One rectangle primitive, empty when the view has no bounding rectangle.

drawing_tools.helpers.visualization.overlays.featured.collect_view_index_overlay_primitives(featured_view: FeaturedView, view_index: int = 0, color: str | None = None) → list#

Build the view-index overlay for a featured view (rectangle + sheet/view label).

Delegates to dessia_drawing’s overlays.annotation.collect_view_index_overlay_primitives.

drawing_tools.helpers.visualization.overlays.featured.collect_balloon_overlay_primitives(featured_view: FeaturedView) → list#

Build balloon overlay primitives for a featured view (reuses cached balloons).

drawing_tools.helpers.visualization.overlays.featured.collect_balloon_flags_overlay_primitives(featured_view: FeaturedView) → list#

Build balloon flag overlay primitives (multiplicators, FM symbols) for a featured view.

drawing_tools.helpers.visualization.overlays.featured.collect_bonding_symbol_overlay_primitives(featured_view: FeaturedView, color_offset: int = 0) → list#

Build bonding symbol overlay primitives for a featured view, one palette color per symbol.

Parameters:
  • featured_view – The view whose cached bonding_symbols are drawn.

  • color_offset – Palette index to start at, so symbols keep distinct colors when the views of a whole sheet are drawn together.

Returns:

List of plot_data primitives.

drawing_tools.helpers.visualization.overlays.featured.collect_aircraft_orientation_overlay_primitives(featured_view: FeaturedView, color_offset: int = 0) → list#

Build aircraft orientation overlay primitives for a featured view, one palette color per indicator.

Parameters:
  • featured_view – The view whose cached aircraft_orientation_indicators are drawn.

  • color_offset – Palette index to start at, so indicators keep distinct colors when the views of a whole sheet are drawn together.

Returns:

List of plot_data primitives.

drawing_tools.helpers.visualization.overlays.featured.collect_section_line_overlay_primitives(featured_view: FeaturedView) → list#

Build section line indicator overlay primitives for a featured view (one color per indicator).

drawing_tools.helpers.visualization.overlays.featured.collect_aircraft_reference_line_overlay_primitives(featured_view: FeaturedView, color_offset: int = 0) → list#

Build aircraft reference line overlay primitives for a featured view, one palette color per line.

Parameters:
  • featured_view – The view whose cached aircraft_reference_lines are drawn.

  • color_offset – Palette index to start at, so reference lines keep distinct colors when the views of a whole sheet are drawn together.

Returns:

List of plot_data primitives.

drawing_tools.helpers.visualization.overlays.featured.collect_title_overlay_primitives(featured_view: FeaturedView, color: str | None = None) → list#

Build title overlay primitives for a featured view (empty if no title).

drawing_tools.helpers.visualization.overlays.featured.collect_auxiliary_view_indicator_overlay_primitives(featured_view: FeaturedView) → list#

Build overlay primitives for a featured view’s auxiliary view indicators.

Each indicator gets a colored bounding rectangle and labels showing its identifier and optional cross-reference.

drawing_tools.helpers.visualization.overlays.featured.collect_all_identifier_overlay_primitives(featured_view: FeaturedView) → list#

Build overlay primitives for all identifier-bearing objects of a featured view.

Combines title, section line indicators and auxiliary view indicators.

drawing_tools.helpers.visualization.overlays.featured.collect_sheet_title_overlay_primitives(featured_sheet: FeaturedSheet) → list#

Build title overlay primitives for all views of the sheet, each in a different color.

drawing_tools.helpers.visualization.overlays.featured.collect_sheet_section_line_overlay_primitives(featured_sheet: FeaturedSheet) → list#

Build section line indicator overlay primitives for all views of the sheet.

drawing_tools.helpers.visualization.overlays.featured.collect_sheet_aircraft_reference_line_overlay_primitives(featured_sheet: FeaturedSheet) → list#

Build aircraft reference line overlay primitives for all views of the sheet, one color per line.

The palette offset is carried from one view to the next, so two reference lines of the same sheet do not come out in the same color merely because they sit in different views.

drawing_tools.helpers.visualization.overlays.featured.collect_sheet_table_overlay_primitives(featured_sheet: FeaturedSheet) → list#

Build table overlay primitives for all detected tables in the sheet.

Uses the sheet’s shared table_detector, so the overlay reflects that detector’s configuration and reuses its memoized detection.

drawing_tools.helpers.visualization.overlays.featured.collect_sheet_balloon_overlay_primitives(featured_sheet: FeaturedSheet) → list#

Build balloon overlay primitives for all views, plus the color legend when balloons exist.

drawing_tools.helpers.visualization.overlays.featured.collect_sheet_bonding_symbol_overlay_primitives(featured_sheet: FeaturedSheet) → list#

Build bonding symbol overlay primitives for all views of the sheet, one color per symbol.

drawing_tools.helpers.visualization.overlays.featured.collect_sheet_aircraft_orientation_overlay_primitives(featured_sheet: FeaturedSheet) → list#

Build aircraft orientation overlay primitives for all views of the sheet, one color per indicator.

The palette offset is carried from one view to the next, so two indicators of the same sheet do not come out in the same color merely because they sit in different views.

drawing_tools.helpers.visualization.overlays.featured.collect_sheet_balloon_flags_overlay_primitives(featured_sheet: FeaturedSheet) → list#

Build balloon flag overlay primitives (multiplicators, FM symbols) for the whole sheet.

drawing_tools.helpers.visualization.overlays.featured.collect_sheet_sets_overlay_primitives(featured_sheet: FeaturedSheet) → list#

Build set-region overlay primitives for all detected sets of the sheet.

Draws each set’s colored region (tooltip listing its attributed views) plus an outline around every view, colored by its assigned set — orphan views are outlined in red dashed.

drawing_tools.helpers.visualization.overlays.featured.collect_sheet_auxiliary_view_indicator_overlay_primitives(featured_sheet: FeaturedSheet) → list#

Build auxiliary view indicator overlay primitives for all views of the sheet.

drawing_tools.helpers.visualization.overlays.featured.collect_sheet_all_identifier_overlay_primitives(featured_sheet: FeaturedSheet) → list#

Build all identifier overlay primitives for all views of the sheet.

drawing_tools.helpers.visualization.overlays.featured.collect_composite_arrow_leaders(featured_view: FeaturedView) → list#

Return the leaders dessia_drawing cannot see: those reconstructed from geometry.

Section line indicators detected through CompositeEntity geometry own no Leader in the model, so drawing_tools reconstructs theirs from geometry. Indicators from the symbols branch are skipped: dessia_drawing already sees their real leaders, and including them here would draw and count them twice.

drawing_tools.helpers.visualization.overlays.featured.collect_view_arrow_head_overlay_primitives(featured_view: FeaturedView) → list#

Build the terminator plate of a featured view, composite arrows reconstructed from geometry included.

drawing_tools.helpers.visualization.overlays.featured.collect_view_leader_overlay_primitives(featured_view: FeaturedView) → list#

Build the leader plate of a featured view, composite arrows reconstructed from geometry included.

drawing_tools.helpers.visualization.overlays.featured.collect_sheet_composite_arrow_leaders(featured_sheet: FeaturedSheet) → list#

Return the leaders reconstructed from geometry of every view of a featured sheet.

drawing_tools.helpers.visualization.overlays.featured.collect_sheet_arrow_head_overlay_primitives(featured_sheet: FeaturedSheet) → list#

Build the terminator plate of a whole featured sheet, under a single legend.

drawing_tools.helpers.visualization.overlays.featured.collect_sheet_leader_overlay_primitives(featured_sheet: FeaturedSheet) → list#

Build the leader plate of a whole featured sheet, under a single legend.

drawing_tools.helpers.visualization.overlays.verdict module#

Reusable OK/NOK “verdict” visualization vocabulary for drawing sheets.

Promoted from scripts/demo_scenarios/viz_helpers.py so that demo scenarios AND external consumers (e.g. drawing_tools_ai display_* tools) can import it from the installable package.

Design principles#

  • Unified coord/anchor API — each drawing helper (rectangle, text, arrow, status_symbol) accepts EITHER raw coordinates OR an anchor (around= / near= / at= / from_= / to=). Anchors can be a dessia_drawing entity (anything with .bounding_rectangle), a BoundingRectangle, OR a Viz returned by a previous helper call — so primitives chain naturally.

  • Offsets always explicit — rectangles/frames accept per-side offsets (left, right, top, bottom); all default to 0.

  • No new concepts unless necessary — a single tiny Viz class is added purely so helpers can return “list of primitives + final bbox” in a single object that extras += viz knows how to extend.

  • Stay minimal on top of what exists — where dessia_drawing.helpers.visualization.overlays.base already provides a primitive (build_rectangle_primitive), this module delegates rather than re-implements. The remaining local implementations (per-side offsets, text-bbox estimation, corner anchoring, arrow geometry) stay here on purpose: no dessia_drawing extension for now.

Three flagship compositions build on the primitives:

  • verdict_overlay() — green/red box around an anchor + optional label beside it + ✓/✗ glyph at a configurable corner, all colored by the ok verdict.

  • callout() — a label block placed AWAY from a target + an arrow to the target’s edge (+ optional glyph and box), in one free color.

  • link() — two boxed elements connected edge-to-edge by an arrow, with an optional ✓/✗/⚠ glyph over the arrow (“X references Y” verdicts).

class drawing_tools.helpers.visualization.overlays.verdict.CalloutArrowConfig(line_width: float = 1.5, head_length: float = 3.5, head_half_angle_deg: float = 22.0, start_gap: float = 1.0, end_gap: float = 1.0)#

Bases: object

Geometry of the callout arrow, drawn from the label block to the target.

Parameters:
  • line_width – Stroke width of the arrow segments

  • head_length – Length of each of the two head segments

  • head_half_angle_deg – Half-opening angle of the head, in degrees

  • start_gap – Distance between the label block’s edge and the arrow tail

  • end_gap – Distance between the arrow tip and the target’s edge

line_width: float = 1.5#
head_length: float = 3.5#
head_half_angle_deg: float = 22.0#
start_gap: float = 1.0#
end_gap: float = 1.0#
__init__(line_width: float = 1.5, head_length: float = 3.5, head_half_angle_deg: float = 22.0, start_gap: float = 1.0, end_gap: float = 1.0) → None#
class drawing_tools.helpers.visualization.overlays.verdict.VerdictBoxConfig(left: float = 0.0, right: float = 0.0, top: float = 0.0, bottom: float = 0.0, fill_color: str | None = None, opacity: float = 0.25, line_width: float = 2.0)#

Bases: object

Appearance of the verdict box drawn around the anchor.

Per-side offsets grow the box outward from the anchor’s bbox (same convention as rectangle()).

Parameters:
  • left – Extra outward growth to the left of the anchor’s bbox

  • right – Extra outward growth to the right of the anchor’s bbox

  • top – Extra outward growth above the anchor’s bbox

  • bottom – Extra outward growth below the anchor’s bbox

  • fill_color – Fill color of the box; when None, defaults to the composite’s drawing color (the green/red verdict color in verdict_overlay, color in callout)

  • opacity – Fill opacity of the box, 0 to 1

  • line_width – Stroke width of the box outline

left: float = 0.0#
right: float = 0.0#
top: float = 0.0#
bottom: float = 0.0#
fill_color: str | None = None#
opacity: float = 0.25#
line_width: float = 2.0#
__init__(left: float = 0.0, right: float = 0.0, top: float = 0.0, bottom: float = 0.0, fill_color: str | None = None, opacity: float = 0.25, line_width: float = 2.0) → None#
class drawing_tools.helpers.visualization.overlays.verdict.VerdictGlyphConfig(corner: Literal['top-left', 'top-right', 'bottom-left', 'bottom-right', 'middle-left', 'middle-right', 'top-center', 'bottom-center'] = 'middle-right', gap: float = 1.5, height: float = 2.8, font_size: float = 7.0, on: Literal['box', 'label'] = 'box')#

Bases: object

Placement and typography of the ✓/✗ glyph.

Parameters:
  • corner – Which corner/edge of its anchor the glyph is placed outside of (see Corner)

  • gap – Distance between the anchor’s bbox and the glyph

  • height – Glyph height in drawing units

  • font_size – plot_data font size of the glyph

  • on – The glyph’s anchor — the verdict box ("box", default) or the label ("label"), falling back to the box when no label is rendered

corner: Literal['top-left', 'top-right', 'bottom-left', 'bottom-right', 'middle-left', 'middle-right', 'top-center', 'bottom-center'] = 'middle-right'#
gap: float = 1.5#
height: float = 2.8#
font_size: float = 7.0#
on: Literal['box', 'label'] = 'box'#
__init__(corner: Literal['top-left', 'top-right', 'bottom-left', 'bottom-right', 'middle-left', 'middle-right', 'top-center', 'bottom-center'] = 'middle-right', gap: float = 1.5, height: float = 2.8, font_size: float = 7.0, on: Literal['box', 'label'] = 'box') → None#
class drawing_tools.helpers.visualization.overlays.verdict.VerdictLabelConfig(side: Literal['right', 'left', 'above', 'below'] = 'right', gap: float = 3.0, height: float = 2.2, font_size: float = 7.0, bold: bool = True, line_gap: float = 1.5)#

Bases: object

Placement and typography of the optional label beside the box.

Parameters:
  • side – Which side of the verdict box the label goes on ("right" / "left" / "above" / "below")

  • gap – Distance between the verdict box and the label

  • height – Label text height in drawing units

  • font_size – plot_data font size of the label

  • bold – Whether the label is bold

  • line_gap – Vertical spacing between line slots when the label has several lines (see stacked_texts()); unused for a single-string label

side: Literal['right', 'left', 'above', 'below'] = 'right'#
gap: float = 3.0#
height: float = 2.2#
font_size: float = 7.0#
bold: bool = True#
line_gap: float = 1.5#
__init__(side: Literal['right', 'left', 'above', 'below'] = 'right', gap: float = 3.0, height: float = 2.2, font_size: float = 7.0, bold: bool = True, line_gap: float = 1.5) → None#
class drawing_tools.helpers.visualization.overlays.verdict.Viz(primitives: list, bounding_rectangle: BoundingRectangle)#

Bases: list

Extras-extendable list of plot_data primitives, with a bbox for chaining.

Exposes .bounding_rectangle under the SAME name as drawing_tools / dessia_drawing entities, so any helper’s anchor parameter can receive:

  • a drawing entity (has .bounding_rectangle)

  • a BoundingRectangle directly

  • a previously-built Viz (has .bounding_rectangle)

__init__(primitives: list, bounding_rectangle: BoundingRectangle) → None#

Wrap a primitive list with the bounding rectangle of what it renders.

Parameters:
  • primitives – The plot_data primitives making up the rendered element

  • bounding_rectangle – The bbox of what those primitives render, exposed for chaining (the Viz can be passed as the anchor of the next helper)

bounding_rectangle: BoundingRectangle#
drawing_tools.helpers.visualization.overlays.verdict.arrow(x_from: float | None = None, y_from: float | None = None, x_to: float | None = None, y_to: float | None = None, *, from_: object = None, to: object = None, color: str, line_width: float = 1.5, head_length: float = 3.5, head_half_angle_deg: float = 22.0) → Viz#

Build a straight arrow from (x_from, y_from) to (x_to, y_to).

When from_ / to anchors are given, the shaft endpoints become the centers of the respective bboxes. Callers who want a specific side/corner can pass explicit coords instead.

Parameters:
  • x_from – X coordinate of the arrow tail (raw-coords mode)

  • y_from – Y coordinate of the arrow tail (raw-coords mode)

  • x_to – X coordinate of the arrow tip (raw-coords mode)

  • y_to – Y coordinate of the arrow tip (raw-coords mode)

  • from_ – Anchor (entity / BoundingRectangle / Viz) whose bbox center becomes the tail — alternative to x_from/y_from

  • to – Anchor whose bbox center becomes the tip — alternative to x_to/y_to

  • color – Stroke color of the shaft and head segments

  • line_width – Stroke width of the three segments

  • head_length – Length of each of the two head segments

  • head_half_angle_deg – Half-opening angle of the head, in degrees, between the shaft and each head segment

Returns:

A Viz of three pld.LineSegment2D — [shaft, head_left, head_right] — whose bbox encloses the whole arrow

Raises:
  • ValueError – If any endpoint is left undefined (neither anchor nor raw coordinates)

  • TypeError – If from_ / to cannot be resolved to a bounding rectangle

drawing_tools.helpers.visualization.overlays.verdict.callout(target: object, label: str | Sequence[str], *, color: str, status: Literal['OK', 'NOK', 'WARN'] | None = None, near: object = None, tooltip: str | None = None, with_box: bool = False, with_arrow: bool = True, box_config: VerdictBoxConfig | None = None, label_config: VerdictLabelConfig | None = None, glyph_config: VerdictGlyphConfig | None = None, arrow_config: CalloutArrowConfig | None = None) → Viz#

Annotate a target with a label block and an arrow pointing at it.

Complements verdict_overlay(): instead of decorating the anchor in place, the label block sits AWAY from the target (on label_config.side of near, which defaults to the target itself) and an arrow runs from the block’s edge to the closest point of the target’s edge (both computed with closest_edge_point(), shortened by the arrow config’s gaps). The block’s edge is its ESTIMATED bbox (see estimate_text_bbox()), so the tail placement inherits the heuristic’s imprecision on wide labels. Everything is drawn in one free color — informational callouts are often orange or blue, so the color is NOT derived from an ok/nok verdict.

Composition order is box → label lines → glyph → arrow.

Parameters:
  • target – What the arrow points at — an entity, a BoundingRectangle, or a Viz

  • label – The label text — a single string, or several lines in top-down reading order (stacked via stacked_texts())

  • color – Color shared by every component (box, label, glyph, arrow)

  • status – Optional "OK" / "NOK" / "WARN" glyph drawn in color on the label block; no glyph when None

  • near – Anchor the label block is placed next to; defaults to the target (its box when with_box)

  • tooltip – Optional tooltip attached to the box (unused when with_box is False)

  • with_box – Whether to draw a box around the target (the same component as verdict_overlay’s box)

  • with_arrow – Whether to draw the arrow; the arrow is also skipped when the gap-shortened shaft would be shorter than the arrow head (no readable arrow fits)

  • box_config – Box appearance (offsets, fill, opacity, stroke); defaults to VerdictBoxConfig()

  • label_config – Label-block placement and typography; defaults to VerdictLabelConfig()

  • glyph_config – Glyph placement and typography; its on field is ignored (the glyph always anchors on the label block); defaults to VerdictGlyphConfig()

  • arrow_config – Arrow geometry and end gaps; defaults to CalloutArrowConfig()

Returns:

A Viz of all rendered primitives, whose bbox is the boxed target (or the target’s bbox without box) for chaining

Raises:
  • ValueError – If label is empty, status is unknown, or a config’s side/corner is not a supported value

  • TypeError – If target / near cannot be resolved to a bounding rectangle

drawing_tools.helpers.visualization.overlays.verdict.closest_edge_point(bbox: BoundingRectangle, x: float, y: float) → tuple[float, float]#

Return the point on the bbox edge closest to (x, y).

Clamps (x, y) into the bbox range, then picks the nearest of its four edge projections — for a point outside the bbox this is the closest point of the bbox boundary, generally a mid-edge point. Used to anchor arrow endpoints cleanly on an element’s outline (see callout()).

Parameters:
  • bbox – The bounding rectangle whose edge is targeted

  • x – X coordinate of the reference point

  • y – Y coordinate of the reference point

Returns:

The (x, y) of the closest point on the bbox edge

drawing_tools.helpers.visualization.overlays.verdict.estimate_text_bbox(content: str, x: float, y: float, height: float, align_x: str, align_y: str) → BoundingRectangle#

Estimate a text primitive’s bbox from content length and alignment.

plot_data does not expose the rendered bbox, so we use the same heuristic the demo scenarios have always used (char_w = 2 * height, box_h = 1.4 * height). Good enough for anchoring labels and symbols that follow. If the estimate is off, per-side offsets on the caller’s side (e.g. highlight_text’s left/right/top/bottom) allow per-use correction.

Parameters:
  • content – The text string whose rendered footprint is estimated

  • x – X coordinate the text is anchored at

  • y – Y coordinate the text is anchored at

  • height – Text height in drawing units (as passed to pld.Text)

  • align_x – Horizontal alignment of the text on x: "left", "right", or anything else for centered

  • align_y – Vertical alignment of the text on y: "top", "bottom", or anything else for middle

Returns:

The estimated bounding rectangle of the rendered text

drawing_tools.helpers.visualization.overlays.verdict.highlight(anchor: object, *, color: str, padding: float = 0.0, opacity: float = 0.25, line_width: float = 1.5) → Viz#

Highlight an entity with symmetric padding and a single color.

Delegates to dessia_drawing.helpers.visualization.overlays.base.build_rectangle_primitive. For asymmetric offsets or split edge/fill colors, use rectangle(around=...) instead.

Parameters:
  • anchor – What to highlight — an entity, a BoundingRectangle, or a Viz

  • color – Single color used for both the outline and the fill

  • padding – Symmetric outward growth applied on all four sides

  • opacity – Fill opacity, 0 (transparent) to 1 (opaque)

  • line_width – Stroke width of the outline

Returns:

A Viz holding the highlight rectangle and its padded bbox

Raises:

TypeError – If anchor cannot be resolved to a bounding rectangle

drawing_tools.helpers.visualization.overlays.verdict.highlight_text(content: str, x: float, y: float, *, height: float, align_x: str = 'center', align_y: str = 'middle', edge_color: str | None = None, fill_color: str | None = None, opacity: float = 1.0, line_width: float = 1.0, left: float = 0.0, right: float = 0.0, top: float = 0.0, bottom: float = 0.0) → Viz#

Highlight a text in color, hugging the text’s estimated bounding box.

Estimates where the text’s edge sits via estimate_text_bbox() (the text itself is NOT rendered — only the colored box over where it sits), then draws a rectangle over it with per-side offsets.

Used by text() for its background frame (hence, transitively, by verdict_overlay() labels), and directly available to highlight an already-placed text whose position/height/alignment are known.

Parameters:
  • content – The text whose edge is found; it is not drawn by this helper

  • x – X coordinate the text is anchored at

  • y – Y coordinate the text is anchored at

  • height – Text height in drawing units, driving the bbox estimate

  • align_x – Horizontal alignment of the text on x ("left" / "center" / "right")

  • align_y – Vertical alignment of the text on y ("top" / "middle" / "bottom")

  • edge_color – Stroke color of the highlight; defaults to fill_color when omitted

  • fill_color – Fill color of the highlight; defaults to edge_color when omitted

  • opacity – Fill opacity, 0 (transparent) to 1 (opaque)

  • line_width – Stroke width of the highlight outline

  • left – Extra growth to the left beyond the estimated text edge

  • right – Extra growth to the right beyond the estimated text edge

  • top – Extra growth upward beyond the estimated text edge

  • bottom – Extra growth downward beyond the estimated text edge

Returns:

A Viz holding the highlight rectangle and its final bbox

Raises:

ValueError – If neither edge_color nor fill_color is given

Connect a source and a target with boxes and an edge-to-edge arrow.

Both elements are boxed with the same box_config, then an arrow runs from the source box’s edge to the target box’s edge (both endpoints computed with closest_edge_point(), shortened by the arrow config’s gaps). When status is given, its glyph is drawn just above the middle of the arrow. Like callout() the color is free — but for the common pass/fail case it can be omitted and is then derived from status (GREEN/RED/ORANGE for "OK"/"NOK"/"WARN").

Composition order is source box → target box → arrow → glyph.

Parameters:
  • source – The referencing element — an entity, a BoundingRectangle, or a Viz; the arrow starts on its box

  • target – The referenced element — an entity, a BoundingRectangle, or a Viz; the arrow points at its box

  • color – Color shared by every component (boxes, arrow, glyph); defaults from status when omitted

  • status – Optional "OK" / "NOK" / "WARN" glyph drawn in color above the arrow’s middle; no glyph when None

  • tooltip – Optional tooltip attached to the source box (unused when with_boxes is False)

  • with_boxes – Whether to box the two elements; when False the arrow runs between the raw bboxes

  • with_arrow – Whether to draw the arrow; the arrow (and the glyph riding on it) is also skipped when the gap-shortened shaft would be shorter than the arrow head (no readable arrow fits, e.g. when the two boxes touch or overlap)

  • box_config – Appearance shared by BOTH boxes (offsets, fill, opacity, stroke); defaults to VerdictBoxConfig()

  • glyph_config – Glyph typography (height, font_size) and gap = distance between the arrow shaft and the glyph bottom; its corner and on fields are ignored (the glyph always rides the arrow’s middle); defaults to VerdictGlyphConfig()

  • arrow_config – Arrow geometry and end gaps; defaults to CalloutArrowConfig()

Returns:

A Viz of all rendered primitives, whose bbox is the union of the two (boxed) elements for chaining

Raises:
  • ValueError – If both color and status are omitted, or status is unknown

  • TypeError – If source / target cannot be resolved to a bounding rectangle

drawing_tools.helpers.visualization.overlays.verdict.rectangle(xmin: float | None = None, xmax: float | None = None, ymin: float | None = None, ymax: float | None = None, *, around: object = None, left: float = 0.0, right: float = 0.0, top: float = 0.0, bottom: float = 0.0, edge_color: str, fill_color: str | None = None, opacity: float = 0.25, line_width: float = 1.5, tooltip: str | None = None) → Viz#

Build a colored rectangle, either from raw coordinates or around an anchor.

Provide one input mode:
  • xmin/xmax/ymin/ymax for direct coords, OR

  • around=<entity|bbox|Viz> to wrap an anchor (takes precedence when both modes are given).

Per-side offsets apply in both modes (see _apply_offsets() for the grow-outward convention).

Parameters:
  • xmin – Left bound — raw-coords mode, requires the three other bounds

  • xmax – Right bound (raw-coords mode)

  • ymin – Bottom bound (raw-coords mode)

  • ymax – Top bound (raw-coords mode)

  • around – Anchor to wrap (entity / BoundingRectangle / Viz) — alternative to the four raw coordinates, takes precedence when given

  • left – Extra outward growth to the left

  • right – Extra outward growth to the right

  • top – Extra outward growth upward

  • bottom – Extra outward growth downward

  • edge_color – Stroke color of the rectangle outline

  • fill_color – Fill color; defaults to edge_color when omitted

  • opacity – Fill opacity, 0 (transparent) to 1 (opaque)

  • line_width – Stroke width of the outline

  • tooltip – Optional tooltip shown when the rectangle is clicked

Returns:

A Viz holding the single pld.Rectangle, its bbox being the final (offset-grown) rectangle

Raises:
  • ValueError – If neither around nor all four raw coordinates are given

  • TypeError – If around cannot be resolved to a bounding rectangle

drawing_tools.helpers.visualization.overlays.verdict.stacked_texts(lines: Sequence[str], *, near: object, side: Literal['right', 'left', 'above', 'below'] = 'right', gap: float = 3.0, color: str, height: float = 2.2, font_size: float = 7.0, bold: bool = True, line_gap: float = 1.5) → Viz#

Stack several text lines next to an anchor, as one block.

The block is placed like a single text() anchored with near/side/gap — to the right/left of the anchor (block vertically centered) or above/below it (block horizontally centered) — and lines read top-down. Each line occupies a slot of 1.4 * height (the estimated bbox of one line), consecutive slots separated by line_gap.

Parameters:
  • lines – The text lines, in top-down reading order

  • near – Anchor (entity / BoundingRectangle / Viz) the block is placed next to

  • side – Which side of near the block goes on

  • gap – Distance between near’s bbox and the block

  • color – Text color of every line

  • height – Text height of every line, in drawing units

  • font_size – plot_data font size of every line

  • bold – Whether the lines are bold

  • line_gap – Vertical spacing between consecutive line slots

Returns:

A Viz of the line primitives (top line first), whose bbox is the union of the estimated line bboxes

Raises:
  • ValueError – If lines is empty or side is unknown

  • TypeError – If near cannot be resolved to a bounding rectangle

drawing_tools.helpers.visualization.overlays.verdict.status_symbol(status: Literal['OK', 'NOK', 'WARN'], x: float | None = None, y: float | None = None, *, at: object = None, corner: Literal['top-left', 'top-right', 'bottom-left', 'bottom-right', 'middle-left', 'middle-right', 'top-center', 'bottom-center'] = 'top-right', gap: float = 1.5, height: float = 2.8, color: str | None = None, bold: bool = True, font_size: float = 7.0) → Viz#

Place a ✓ ("OK"), ✗ ("NOK") or ⚠ ("WARN") glyph.

Positioning:
  • x, y for raw coords (aligned left/middle; corner is ignored), OR

  • at=<entity|bbox|Viz> + corner to anchor on a bbox corner/edge.

Parameters:
  • status – The verdict to draw: "OK" (✓), "NOK" (✗) or "WARN" (⚠)

  • x – X coordinate of the glyph (raw-coords mode)

  • y – Y coordinate of the glyph (raw-coords mode)

  • at – Anchor (entity / BoundingRectangle / Viz) whose corner/edge the glyph sits at — alternative to raw coordinates, takes precedence

  • corner – Which corner/edge of at’s bbox the glyph is placed OUTSIDE of (see _corner_anchor()); ignored in raw-coords mode

  • gap – Distance between the bbox corner/edge and the glyph; ignored in raw-coords mode

  • height – Glyph height in drawing units

  • color – Glyph color; defaults to GREEN for "OK", RED for "NOK", ORANGE for "WARN"

  • bold – Whether the glyph is bold

  • font_size – plot_data font size of the glyph

Returns:

A Viz holding the glyph text primitive and its estimated bbox

Raises:
  • ValueError – If status is unknown, or if neither at nor both x/y are given, or if corner is unknown

  • TypeError – If at cannot be resolved to a bounding rectangle

drawing_tools.helpers.visualization.overlays.verdict.text(content: str, x: float | None = None, y: float | None = None, *, near: object = None, side: Literal['right', 'left', 'above', 'below'] = 'right', gap: float = 3.0, color: str, height: float = 2.2, align_x: str | None = None, align_y: str | None = None, bold: bool = True, font_size: float = 7.0, frame_edge_color: str | None = None, frame_fill: str | None = None, frame_opacity: float = 1.0, frame_line_width: float = 1.0, frame_left: float = 0.0, frame_right: float = 0.0, frame_top: float = 0.0, frame_bottom: float = 0.0) → Viz#

Build a text primitive, with optional background frame.

Positioning mode:
  • x, y + optional align_x/align_y for raw coordinates.

  • near=<entity|bbox|Viz>, side, gap to anchor next to another element. Default side="right" puts the text to the right of near’s bbox, vertically centered.

Frame:
  • Drawn only when frame_edge_color or frame_fill is given (delegates to highlight_text()). Its rectangle wraps the text bbox with per-side offsets (frame_left/right/top/ bottom), all default 0 for a tight hug; those offsets have no effect unless a frame color is set.

Parameters:
  • content – The text to render

  • x – X coordinate of the text anchor (raw-coords mode)

  • y – Y coordinate of the text anchor (raw-coords mode)

  • near – Anchor (entity / BoundingRectangle / Viz) to place the text next to — alternative to raw coordinates, takes precedence when given

  • side – Which side of near the text goes on: "right", "left", "above" or "below"; ignored in raw-coords mode

  • gap – Distance between near’s bbox and the text anchor point; ignored in raw-coords mode

  • color – Text color

  • height – Text height in drawing units (rendered with text_scaling=True)

  • align_x – Horizontal alignment on the anchor point; when omitted, a sensible default is derived from the positioning mode (e.g. "left" for side="right", "center" in raw-coords mode)

  • align_y – Vertical alignment on the anchor point; same defaulting behaviour as align_x

  • bold – Whether the text is bold

  • font_size – plot_data font size of the text

  • frame_edge_color – Stroke color of the optional background frame; enables the frame when given

  • frame_fill – Fill color of the optional background frame; enables the frame when given

  • frame_opacity – Frame fill opacity, 0 to 1

  • frame_line_width – Frame stroke width

  • frame_left – Extra frame growth to the left beyond the text bbox

  • frame_right – Extra frame growth to the right beyond the text bbox

  • frame_top – Extra frame growth upward beyond the text bbox

  • frame_bottom – Extra frame growth downward beyond the text bbox

Returns:

A Viz — [text] with the estimated text bbox when no frame is requested, else [frame, text] (frame first so the text renders on top) with the frame’s bbox for chaining

Raises:
  • ValueError – If neither near nor both x/y are given, or if side is not one of the four supported values

  • TypeError – If near cannot be resolved to a bounding rectangle

drawing_tools.helpers.visualization.overlays.verdict.verdict_overlay(anchor: object, *, ok: bool, label: str | Sequence[str] | None = None, tooltip: str | None = None, with_box: bool = True, with_glyph: bool = True, box_config: VerdictBoxConfig | None = None, label_config: VerdictLabelConfig | None = None, glyph_config: VerdictGlyphConfig | None = None) → Viz#

Render an OK/NOK verdict over an anchor: green/red box + ✓/✗ (+ label).

GREEN/✓ when ok else RED/✗. Composition order is box → label → glyph. The optional label is placed beside the box on label_config.side; the glyph sits at glyph_config.corner of the box, or of the label when glyph_config.on == "label".

Parameters:
  • anchor – What is being judged — an entity, a BoundingRectangle, or a Viz; the verdict box wraps its bbox

  • ok – The verdict: True renders in GREEN with ✓, False in RED with ✗

  • label – Optional text placed beside the box, in the verdict color — a single string, or several lines in top-down reading order (stacked via stacked_texts(), spaced by label_config.line_gap)

  • tooltip – Optional tooltip attached to the verdict box

  • with_box – Whether to draw the box around the anchor; when False the label/glyph anchor directly on the anchor’s bbox

  • with_glyph – Whether to draw the ✓/✗ glyph

  • box_config – Box appearance (offsets, fill, opacity, stroke); defaults to VerdictBoxConfig() when omitted

  • label_config – Label placement and typography; defaults to VerdictLabelConfig() when omitted

  • glyph_config – Glyph placement and typography; defaults to VerdictGlyphConfig() when omitted

Returns:

A Viz of all rendered primitives, whose bbox is the verdict box (or the anchor’s bbox when with_box is False) for chaining

Raises:

drawing_tools.helpers.visualization.overlays.sheet_sets module#

SheetSet visualization helpers.

class drawing_tools.helpers.visualization.overlays.sheet_sets.ViewWithAssignedSet(view_name: str, bounding_rectangle: BoundingRectangle, set_name: str | None, set_color: tuple[float, float, float] | None, ratio: float, contained_edges: int)#

Bases: NamedTuple

How a single view relates to the sheet’s sets, for visualization.

Parameters:
  • view_name – Display name of the view.

  • bounding_rectangle – The view’s bounding rectangle.

  • set_name – Name of the set the view was assigned to, or None if unattributed (orphan).

  • set_color – RGB color of the assigned set, or None for an orphan view.

  • ratio – Containment ratio of the assigned set when attributed; ratio of the highest-ratio candidate set when orphaned.

  • contained_edges – Contained-edge count of the assigned set when attributed; that of the highest-ratio candidate set when orphaned.

view_name: str#

Alias for field number 0

bounding_rectangle: BoundingRectangle#

Alias for field number 1

set_name: str | None#

Alias for field number 2

set_color: tuple[float, float, float] | None#

Alias for field number 3

ratio: float#

Alias for field number 4

contained_edges: int#

Alias for field number 5

class drawing_tools.helpers.visualization.overlays.sheet_sets.SheetSetsSketcher(sheet_set: SheetSet)#

Bases: object

Handles visualization for a single SheetSet.

__init__(sheet_set: SheetSet)#

Initialize the sketcher with a SheetSet instance.

plot_data_primitives(fill_color: tuple[float, float, float] = (0.6, 0.8, 1.0), opacity: float = 0.15, view_names: list[str] | None = None) → list[PlotDataObject]#

Return plot_data primitives that visualize the set region.

Parameters:
  • fill_color – RGB tuple in [0, 1] range for the region fill.

  • opacity – Fill opacity.

  • view_names – When provided, the attributed-view count is appended to the set label.

Returns:

List of plot_data primitives (rectangle + label).

drawing_tools.helpers.visualization.overlays.sheet_sets.get_sets_plot_data_primitives(sets: list[SheetSet], opacity: float = 0.15, views_by_set: dict[str, list[str]] | None = None) → list[PlotDataObject]#

Return plot_data primitives for a list of sets, each with a distinct color.

Parameters:
  • sets – The sets to visualize.

  • opacity – Fill opacity for the set regions.

  • views_by_set – Optional mapping of set name to attributed view names, added to tooltips.

Returns:

Combined list of plot_data primitives.

drawing_tools.helpers.visualization.overlays.sheet_sets.get_view_assigned_set_primitives(view_assigned_sets: list[ViewWithAssignedSet], min_containment_ratio: float, min_contained_edges: int) → list[PlotDataObject]#

Return outline rectangles for views, colored by their assigned set.

Assigned views are outlined with their set’s color; unassigned (orphan) views are outlined with a red dashed line so they stand out. Each outline carries a tooltip with the view name, its set (or “no set”), the best containment ratio and contained-edge count, and the thresholds that decided the assignment.

Parameters:
  • view_assigned_sets – One ViewWithAssignedSet per view to draw.

  • min_containment_ratio – The ratio threshold applied during assignment (shown in tooltip).

  • min_contained_edges – The contained-edge threshold applied during assignment (shown in tooltip).

Returns:

List of outline rectangle primitives.

drawing_tools.helpers.visualization.overlays.detected_table module#

DetectedTable methods for visualization.

Colors come from drawing_tools.helpers.visualization.palette: OVERLAY_COLORS is cycled per cell, a cell’s texts taking the color as-is and its background the same color lightened, pairing text and cell at a glance; CONTAINER_OVERLAY_COLORS tells one detected table from the next, except the title block, which is always magenta.

drawing_tools.helpers.visualization.overlays.detected_table.DEFAULT_CELL_FILL_RGB = (1.0, 0.0, 0.0)#

Fill of a cell drawn without a palette color (bare single-cell rendering).

class drawing_tools.helpers.visualization.overlays.detected_table.TableCellSketcher(cell: TableCell)#

Bases: object

Handles visualization and debugging display for TableCell.

This class encapsulates all plotting and visualization logic, keeping the TableCell class focused on core functionality.

__init__(cell: TableCell)#

Initialize the visualizer with a TableCell instance.

Parameters:

cell – The TableCell to visualize

plot_data_primitives(opacity: float = 0.4, detailed: bool = False, cell_color: Color | None = None) → list[PlotDataObject]#

Get the plot data representation of the table cell.

Parameters:
  • opacity – The opacity of the cell region.

  • detailed – If activated, add the cell information label (with the merge ranges when the cell spans several grid positions).

  • cell_color – When given, unified cell color: the cell’s text content is drawn in this color and the cell background in the same color lightened, pairing text and cell at a glance.

class drawing_tools.helpers.visualization.overlays.detected_table.DetectedTableSketcher(detected_table: DetectedTable)#

Bases: object

Handles visualization and debugging display for DetectedTable.

This class encapsulates all plotting and visualization logic, keeping the DetectedTable class focused on core functionality.

__init__(detected_table: DetectedTable)#

Initialize the visualizer with a DetectedTable instance.

Parameters:

detected_table – The DetectedTable to visualize

property bounds: BoundingRectangle#

Mirror DetecedTable bounds attribute.

plot_data_primitives(extra_primitives: list[PlotDataObject] | None = None, opacity: float = 0.4, detailed: bool = False) → list[PlotDataObject]#

Get the plot data representation for the detected table.

Each cell cycles through OVERLAY_COLORS: texts in the cell color, background in the same color lightened — showing at a glance which text was attached to which cell (a colored cell with no text of its color is empty).

Parameters:
  • extra_primitives – Optional plot data primitives to be integrated in the table plot

  • opacity – The opacity of the table regions.

  • detailed – If activated, add cells information texts (position and, for merged cells, the spanned grid ranges).

cells_primitives(detailed: bool = False, opacity: float = 0.4) → list[PlotDataObject]#

Generate plot data primitives for all table cells, one palette color per cell.

drawing_tools.helpers.visualization.overlays.detected_table.TABLE_FRAME_LINE_WIDTH = 2.0#

slightly thicker than the cell lines (1).

Type:

Frame line width for detected tables

drawing_tools.helpers.visualization.overlays.detected_table.TABLE_LABEL_HEIGHT_RATIO = 0.002380952380952381#

Summary label height as a fraction of the sheet height, so labels keep the same apparent size whatever the sheet format (calibrated: 1 drawing unit on an A2).

drawing_tools.helpers.visualization.overlays.detected_table.collect_table_overlay_primitives(detector: SheetTableDetector) → list[PlotDataObject]#

Build overlay primitives for all detected tables and the title block of a sheet.

Reconstructed tables (DetectedTable) are rendered in full: per-cell unified colors (texts in the cell color, backgrounds in the same color lightened), a frame in the table color slightly thicker than the cell lines, and the summary label in the same color. Native Table annotations — whose drawing is already in the sheet base layer — keep the soft colored rectangle + label. The title block table is highlighted in magenta with a [Title Block] tag.

Parameters:

detector – The sheet’s table detector (its tables and title block are memoized).

Returns:

List of plot_data primitives.

Other modules#

drawing_tools.helpers.visualization.palette module#

The rotating color palettes the per-element and per-container overlays cycle through.

Single home for those two sequences, so that adding a detection does not add a fourth permutation of the same eight colors. They are distinguished by what they tell apart rather than by which detection uses them:

  • OVERLAY_COLORS gives one color per detected ELEMENT, so that CONSECUTIVE balloons, section lines, bonding symbols or reference lines do not share a color;

  • CONTAINER_OVERLAY_COLORS gives one color per CONTAINER, so the views of a sheet or the tables of a drawing are told apart from one another.

Two limits worth knowing. The guarantee is local: it holds between consecutive ranks, not across a whole sheet, so a collector that restarts the cycle for each view repeats its colors unless it carries an offset over. And the two sequences are permutations of the same eight colors, so they still coincide at ranks 3, 4 and 7; a container and an element are told apart by shape, never by color alone.

overlays/sheet_sets.SET_COLORS stays outside this module: it holds raw RGB tuples rather than plot_data colors, and merging the two needs a decision, not a move.

This module holds no domain type and imports nothing from the package, which is what lets both the domain detectors and the overlay builders import it without creating the cycle the layering forbids.

drawing_tools.helpers.visualization.palette.cycle_color(index: int, palette: Sequence[Color]) → Color#

Pick the color of rank index, wrapping around once the palette is exhausted.

The palette is required rather than defaulted: the whole point of this module is the distinction between coloring an element and coloring a container, and a default would let a call site lose it by omission.

Parameters:
  • index – Rank of the element or container being colored; any integer, negative included, since the modulo wraps.

  • palette – Sequence to cycle, OVERLAY_COLORS or CONTAINER_OVERLAY_COLORS.

Raises:

ZeroDivisionError – When the palette is empty.

Returns:

The color to draw that item with.

drawing_tools.helpers.visualization.edge_constraint_graph module#

Edge Constraint Graph Visualizer for Technical Drawings.

This module provides visualization tools for EdgeConstraintGraph and EdgeRelationship objects detected by EdgeRelationshipDetector using plot_data.

class drawing_tools.helpers.visualization.edge_constraint_graph.LabelParameters(symbol: str, point_key: str, offset_x: float, offset_y: float, tooltip: str | None = None)#

Bases: object

Parameters for creating point-based labels.

symbol: str#
point_key: str#
offset_x: float#
offset_y: float#
tooltip: str | None = None#
__init__(symbol: str, point_key: str, offset_x: float, offset_y: float, tooltip: str | None = None) → None#
class drawing_tools.helpers.visualization.edge_constraint_graph.RelationshipVisualizationConfig#

Bases: object

Configuration for relationship visualization appearance.

RELATIONSHIP_COLORS: ClassVar = {GeometricRelationType.ANGULAR: <plot_data.colors.Color object>, GeometricRelationType.COINCIDENT: <plot_data.colors.Color object>, GeometricRelationType.COLLINEAR: <plot_data.colors.Color object>, GeometricRelationType.CONCENTRIC: <plot_data.colors.Color object>, GeometricRelationType.OFFSET: <plot_data.colors.Color object>, GeometricRelationType.PARALLEL: <plot_data.colors.Color object>, GeometricRelationType.PERPENDICULAR: <plot_data.colors.Color object>, GeometricRelationType.SYMMETRIC: <plot_data.colors.Color object>, GeometricRelationType.TANGENT: <plot_data.colors.Color object>}#
RELATIONSHIP_LINE_STYLES: ClassVar = {GeometricRelationType.ANGULAR: [8, 3, 3, 3], GeometricRelationType.COINCIDENT: [], GeometricRelationType.COLLINEAR: [5, 5], GeometricRelationType.CONCENTRIC: [20, 5], GeometricRelationType.OFFSET: [12, 3], GeometricRelationType.PARALLEL: [10, 5], GeometricRelationType.PERPENDICULAR: [], GeometricRelationType.SYMMETRIC: [12, 3, 3, 3, 3, 3], GeometricRelationType.TANGENT: [15, 5, 5, 5]}#
CONNECTION_POINT_SIZE = 6.0#
EDGE_LINE_WIDTH = 2.0#
RELATIONSHIP_LINE_WIDTH = 1.5#
SYMBOL_SIZE = 1.0#
TEXT_SIZE = 10.0#
HIGHLIGHT_WIDTH = 3.0#
ANNOTATION_OFFSET = 0.5#
LEGEND_START_X = 50#
LEGEND_START_Y = 50#
LEGEND_ROW_HEIGHT = 25#
LEGEND_LINE_LENGTH = 30#
LEGEND_TEXT_OFFSET = 40#
TITLE_FONT_SIZE = 16#
TITLE_OFFSET_Y = 50#
DEFAULT_TITLE_X = 400#
DEFAULT_TITLE_Y = 50#
SYMMETRY_AXIS_EXTENT = 10#
SYMMETRY_AXIS_PATTERN: ClassVar[list[int]] = [10, 5, 2, 5]#
ARROW_SIZE_FACTOR = 0.3#
ARROW_HEAD_SIZE_FACTOR = 0.5#
ARROW_PERPENDICULAR_FACTOR = 0.3#
INTERSECTION_TOLERANCE = 0.001#
class drawing_tools.helpers.visualization.edge_constraint_graph.BaseRelationshipVisualizer(config: RelationshipVisualizationConfig | None = None)#

Bases: ABC

Abstract base class for relationship visualizers.

__init__(config: RelationshipVisualizationConfig | None = None)#

Initialize the visualizer with configuration.

visualize_relationship(relationship: EdgeRelationship, show_edges: bool = True, show_symbols: bool = True, show_labels: bool = True) → list[PlotDataObject]#

Template method that orchestrates the visualization process.

Parameters:
  • relationship – The EdgeRelationship to visualize

  • show_edges – Whether to highlight relationship edges

  • show_symbols – Whether to show relationship symbols

  • show_labels – Whether to show relationship labels

Returns:

List of plot data objects

class drawing_tools.helpers.visualization.edge_constraint_graph.CoincidentRelationshipVisualizer(config: RelationshipVisualizationConfig | None = None)#

Bases: BaseRelationshipVisualizer

Visualizer for coincident (connection point) relationships.

class drawing_tools.helpers.visualization.edge_constraint_graph.TangentRelationshipVisualizer(config: RelationshipVisualizationConfig | None = None)#

Bases: BaseRelationshipVisualizer

Visualizer for tangent (connection point) relationships.

class drawing_tools.helpers.visualization.edge_constraint_graph.ConcentricRelationshipVisualizer(config: RelationshipVisualizationConfig | None = None)#

Bases: BaseRelationshipVisualizer

Visualizer for concentric relationships.

class drawing_tools.helpers.visualization.edge_constraint_graph.ParallelRelationshipVisualizer(config: RelationshipVisualizationConfig | None = None)#

Bases: BaseRelationshipVisualizer

Visualizer for parallel relationships.

class drawing_tools.helpers.visualization.edge_constraint_graph.PerpendicularRelationshipVisualizer(config: RelationshipVisualizationConfig | None = None)#

Bases: BaseRelationshipVisualizer

Visualizer for perpendicular relationships.

class drawing_tools.helpers.visualization.edge_constraint_graph.SymmetricRelationshipVisualizer(config: RelationshipVisualizationConfig | None = None)#

Bases: BaseRelationshipVisualizer

Visualizer for symmetric relationships.

class drawing_tools.helpers.visualization.edge_constraint_graph.EdgeConstraintGraphVisualizer(config: RelationshipVisualizationConfig | None = None)#

Bases: object

Main visualizer for EdgeConstraintGraph objects.

__init__(config: RelationshipVisualizationConfig | None = None)#

Initialize the graph visualizer.

visualize_graph(graph: EdgeConstraintGraph, show_edges: bool = True, show_symbols: bool = True, show_labels: bool = True, relationship_filter: list[GeometricRelationType] | None = None) → list[PlotDataObject]#

Visualize the entire constraint graph.

Parameters:
  • graph – EdgeConstraintGraph to visualize

  • show_edges – Whether to highlight relationship edges

  • show_symbols – Whether to show relationship symbols

  • show_labels – Whether to show relationship labels

  • relationship_filter – Optional filter for relationship types

Returns:

List of plot data objects

create_relationship_legend(relationship_types: list[GeometricRelationType]) → list[PlotDataObject]#

Create a legend for relationship types.

plot_constraint_graph(graph: EdgeConstraintGraph, show_background_edges: bool = True, show_edges: bool = True, show_symbols: bool = True, show_labels: bool = True, show_legend: bool = True, relationship_filter: list[GeometricRelationType] | None = None, filename: str | None = None) → None#

Create a complete constraint graph visualization plot.

Parameters:
  • graph – EdgeConstraintGraph to visualize

  • show_background_edges – Whether to show all edges as background

  • show_edges – Whether to highlight relationship edges

  • show_symbols – Whether to show relationship symbols

  • show_labels – Whether to show relationship labels

  • show_legend – Whether to show relationship type legend

  • relationship_filter – Optional filter for relationship types

  • filename – Optional filename to save plot

drawing_tools.helpers.visualization.edge_constraint_graph.visualize_view_constraint_graph(view: View, tolerance: float = 0.5, angle_tolerance: float = 0.01, relationship_filter: list[GeometricRelationType] | None = None, filename: str | None = None) → None#

Complete workflow to build and visualize constraint graph for a view.

Parameters:
  • view – View to analyze

  • tolerance – Distance tolerance for relationships

  • angle_tolerance – Angular tolerance for relationships

  • relationship_filter – Optional filter for specific relationship types

  • filename – Optional filename to save visualization

drawing_tools.helpers.visualization.edge_constraint_graph.analyze_constraint_graph_patterns(constraint_graph: EdgeConstraintGraph) → dict[str, Any]#

Analyze patterns in the constraint graph.

Parameters:

constraint_graph – EdgeConstraintGraph to analyze

Returns:

Dictionary with pattern analysis results

Developer diagnostics (debug/)#

drawing_tools.helpers.visualization.debug.sheet_table_detector module#

Visualization helpers for debugging SheetTableDetector operations.

This module provides visualization classes for different aspects of table detection: - ConnectivityFilterVisualizer: Debug connectivity density filtering

class drawing_tools.helpers.visualization.debug.sheet_table_detector.VisualizationColors#

Bases: object

Centralized color scheme for all table detection visualizations.

KEPT_LINE = <plot_data.colors.Color object>#
REJECTED_LINE = <plot_data.colors.Color object>#
PROCESSED_LINE = <plot_data.colors.Color object>#
NEIGHBORHOOD = <plot_data.colors.Color object>#
CONNECTION = <plot_data.colors.Color object>#
CLUSTER = <plot_data.colors.Color object>#
TEXT = <plot_data.colors.Color object>#
BORDER = <plot_data.colors.Color object>#
BACKGROUND = <plot_data.colors.Color object>#
class drawing_tools.helpers.visualization.debug.sheet_table_detector.VisualizationLayout#

Bases: object

Layout constants for visualization elements.

PANEL_MARGIN_X = 100#
PANEL_MARGIN_Y = 50#
PANEL_SPACING_Y = 250#
LINE_HEIGHT = 15#
LABEL_OFFSET_Y = 5#
HEADER_FONT_SIZE = 12#
NORMAL_FONT_SIZE = 10#
INFO_FONT_SIZE = 11#
ELLIPSE_SEGMENTS = 36#
KEPT_LINE_WIDTH = 3#
REJECTED_LINE_WIDTH = 2#
NEIGHBORHOOD_LINE_WIDTH = 2#
CONNECTION_LINE_WIDTH = 0.5#
CENTER_MARKER_WIDTH = 2#
NEIGHBORHOOD_DASH: ClassVar[list[int]] = [10, 5]#
CONNECTION_DASH: ClassVar[list[int]] = [3, 3]#
STATS_HEADER = 'Connectivity Density Filter Analysis'#
STATS_SEPARATOR = '========================================'#
class drawing_tools.helpers.visualization.debug.sheet_table_detector.ConnectivityFilterVisualizer(debug_info: dict, use_elliptical: bool = True)#

Bases: object

Visualizer for debugging connectivity density filtering operations.

Provides comprehensive visualization of: - LineSegment filtering results (kept vs rejected) - Neighborhood boundaries - Connection analysis - Statistical information

__init__(debug_info: dict, use_elliptical: bool = True)#

Initialize the connectivity filter visualizer.

Parameters:
  • debug_info – Debug information from connectivity filtering

  • use_elliptical – Whether elliptical neighborhoods were used

generate_plot(output_path: str = 'connectivity_filter_debug.html') → None#

Generate the complete connectivity filter visualization.

Parameters:

output_path – Path to save the visualization

draw_lines() → list[PlotDataObject]#

Draw all lines with color coding and labels.

draw_neighborhoods() → list[PlotDataObject]#

Draw neighborhood boundaries for representative lines.

draw_connections() → list[PlotDataObject]#

Draw connection lines between neighboring lines.

add_statistics_panel() → list[PlotDataObject]#

Add comprehensive statistics panel.

add_color_legend() → list[PlotDataObject]#

Add color coding legend above the content, to the right of the statistics panel.

The debug canvas already carries the “Connectivity Density Filter Analysis” header on the statistics panel (left), so the legend is drawn without its own title and anchored to the right to avoid overlapping that panel.

add_rejected_lines_info() → list[PlotDataObject]#

Add information about rejected lines.

drawing_tools.helpers.visualization.debug.table_detection_pipeline module#

Visualization of the table detection pipeline.

Provides TableDetectionVisualizer which takes a TableDetectionData instance (populated by SheetTableDetector with store_detection_data=True) and exposes one _build_* method per pipeline step.

Usage:

detector = SheetTableDetector(sheet=sheet, store_detection_data=True)
detector.detect_all_tables()

viz = TableDetectionVisualizer(
    sheet=sheet,
    detection_data=detector.detection_data,
    prefix="MyDrawing — Sheet 0",
    background_view_index=detector.background_view_index,
)
viz.visualize_step("full_sheet")
viz.visualize_step("validated_tables")

# Or get primitives without displaying:
for name, prims in viz.get_step_primitives("validated_tables"):
    pld.plot_canvas(plot_data_object=pld.PrimitiveGroup(primitives=prims), filepath="out.html")
class drawing_tools.helpers.visualization.debug.table_detection_pipeline.TableDetectionVisualizer(sheet: Sheet, detection_data: TableDetectionData, prefix: str, background_view_index: int)#

Bases: object

Visualize individual steps of the table detection pipeline.

Parameters:
  • sheet – The Sheet being processed.

  • detection_data – The TableDetectionData populated by SheetTableDetector(store_detection_data=True).

  • prefix – Title prefix (e.g. "condor_BEAM_ASSY — Sheet 0").

  • background_view_index – Index of the background view.

__init__(sheet: Sheet, detection_data: TableDetectionData, prefix: str, background_view_index: int)#

Initialize the visualizer with sheet data and detection results.

property step_names: list[str]#

Available step names, derived from _STEP_BUILDERS.

get_step_primitives(step_name: str) → list[tuple[str, list]]#

Build primitives for step_name without displaying.

Parameters:

step_name – One of step_names.

Returns:

List of (display_name, primitives) tuples.

Raises:

ValueError – If step_name is not recognized.

visualize_step(step_name: str)#

Build and display primitives for step_name.

Parameters:

step_name – One of step_names.

Raises:

ValueError – If step_name is not recognized.

Module contents#

Package initialization.