drawing_tools.helpers.dimension package#

Submodules#

drawing_tools.helpers.dimension.attachments module#

What a dimension is measured FROM: the end of it landing on given edges.

A dimension carries no link to what it measures – no leader, no grouping. What ties it to an element is one of its two ends landing on the element’s own geometry, which get_dimension_ends() supplies the point of.

One attachment is made per END sitting on the target edges: none when the dimension measures something else, one normally, two when both of its ends land on them. DIMENSION_END_COUNT is the two ends every dimension has – a definition, not a threshold.

class drawing_tools.helpers.dimension.attachments.DimensionAttachment(dimension: Dimension, end_on_target: DimensionEnd, other_end: DimensionEnd, target_edge: Edge)#

Bases: object

One END of a dimension landing on a target edge, with the other end it is measured from.

Parameters:
  • dimension – The dimension of the view, as the export carries it.

  • end_on_target – Its end on the target, whose measured_point is where it touches.

  • other_end – Its other end, on the target or on anything else – no attribute says which, a second attachment of the same dimension does.

  • target_edge – The edge of the target that end landed on, which identifies WHICH target was reached when several were searched at once.

dimension: Dimension#
end_on_target: DimensionEnd#
other_end: DimensionEnd#
target_edge: Edge#
__init__(dimension: Dimension, end_on_target: DimensionEnd, other_end: DimensionEnd, target_edge: Edge) → None#
drawing_tools.helpers.dimension.attachments.find_dimension_attachments(dimension: Dimension, dimension_ends: list[DimensionEnd], target_edges: list[Edge], max_distance: float) → list[DimensionAttachment]#

Return one attachment per end of dimension landing on target_edges, in the export’s order.

A dimension whose ends could not both be read is left out: telling an end from the other is what the attachment is for.

The end is placed by WHICH edge its measured point lands on – find_edge_at_point() – never by how near a box is, so the geometry around the target cannot be mistaken for it.

Parameters:
  • dimension – The dimension read.

  • dimension_ends – Its ends, from DimensionAnalyzer.get_dimension_ends.

  • target_edges – The edges of everything searched at once.

  • max_distance – Slack between a measured point and an edge, in drawing units.

Returns:

Zero, one or two attachments.

drawing_tools.helpers.dimension.constraint_points module#

Dimension constraint point extraction and analysis.

class drawing_tools.helpers.dimension.constraint_points.DimensionConstraintPoint(point: Point2D, source_type: Literal['extension_line', 'leader'], source_object: Edge | Leader, source_index: int, direction_vector: Vector2D | None = None)#

Bases: object

Represents a constraint point extracted from a dimension with metadata.

This class provides context about where the constraint point came from (extension line or leader), which specific line/leader it was extracted from, and the direction vector at that point.

This metadata is crucial for proper edge matching in angular dimensions, where we need to ensure edges align with the extension line directions.

point: Point2D#

The actual constraint point location

source_type: Literal['extension_line', 'leader']#

Whether this point came from an extension line or a leader

source_object: Edge | Leader#

Reference to the actual extension line Edge or Leader object

source_index: int#

Index of the source in the dimension’s extension_lines or leaders list

direction_vector: Vector2D | None = None#

Direction vector at the constraint point. - For extension lines: the unit direction vector of the extension line - For leaders: the direction vector of the leader at the arrow tip

__post_init__()#

Compute direction vector if not provided.

matches_direction(edge: Edge, angular_tolerance: float = 0.001) → bool#

Check if an edge’s direction at this constraint point matches the source direction.

This is particularly useful for angular dimensions where we need to match edges based on their alignment with extension lines.

Parameters:
  • edge – Edge to check

  • angular_tolerance – Angular tolerance in radians (default ~2.6 degrees)

Returns:

True if edge direction matches (parallel or anti-parallel)

__init__(point: Point2D, source_type: Literal['extension_line', 'leader'], source_object: Edge | Leader, source_index: int, direction_vector: Vector2D | None = None) → None#
class drawing_tools.helpers.dimension.constraint_points.DimensionConstraintPointsProcessor(dimension: Dimension, tolerance: float = 0.001, point_mapper: Any | None = None)#

Bases: object

Processor for extracting geometric constraint reference points from dimensions.

This processor implements multiple strategies to identify the precise points where a dimension constrains the underlying geometry. It uses smart extension line analysis, leader arrow evaluation, and geometric heuristics to determine optimal constraint points.

The processor follows a strategy pattern with fallback mechanisms: 1. Smart extension line analysis (most reliable for linear/length dimensions) 2. Leader arrow analysis (reliable for radius/diameter dimensions) 3. Related geometric elements analysis 4. Dimension frame fallback

__init__(dimension: Dimension, tolerance: float = 0.001, point_mapper: Any | None = None) → None#

Initialize the processor with a dimension object.

Parameters:
  • dimension – The dimension object to process

  • tolerance – Distance tolerance for point matching

  • point_mapper – Optional PointToEdgeMapper instance for edge finding

property constraint_points: list[DimensionConstraintPoint]#

Extract constraint points with metadata where the dimension constrains the geometry.

This property implements multiple strategies with smart extension line analysis that selects the optimal constraint points and enriches them with metadata about their source (extension line or leader), direction vectors, and indices.

Returns:

List of dimension constraint point objects

property constraint_points_simple: list[Point2D]#

Extract constraint points as simple Point2D objects (backward compatibility).

Returns:

List of constraint points (Point2D only, no metadata)

property geometry_constraint_points: list[Point2D]#

Extract the actual geometry points that the dimension constrains.

This method uses the same strategy as _get_edges_at_points - finding the nearest edges to constraint points using the point mapper, then extracting the closest points on those edges. This accounts for the typical 1-2mm offset between extension lines and geometry in technical drawings.

Returns:

List of actual geometry constraint points (Point2D objects)

drawing_tools.helpers.dimension.corridor module#

Directional search for the geometry an extension line measures.

A corridor is a rectangle swept from the extension line’s end ALONG that line, its length a maximum reach and its width the room a feature has to sit off that line. The edges it reaches are ranked by distance off its axis, then distance into it, then how closely each runs along it – an extension line being the prolongation of the feature it measures.

class drawing_tools.helpers.dimension.corridor.CorridorHit(point: volmdlr.Point2D, edge: Edge, along: float, lateral: float)#

Bases: NamedTuple

A point the corridor reached, the edge carrying it, and where it sits in the corridor.

point: volmdlr.Point2D#

Alias for field number 0

edge: Edge#

Alias for field number 1

along: float#

Distance down the corridor’s axis, from its start.

lateral: float#

Distance off that axis.

class drawing_tools.helpers.dimension.corridor.SearchCorridor(length: float = 2.0, width: float = 0.2, tolerance: float = 0.001)#

Bases: object

A rectangle swept from a point along a direction, to find the geometry that lies ahead.

TRAP: the shape has to stay directional. Whatever lies to the SIDE of the sweep is never reached, and that is what separates the edge measured from a stray merely passing by – at one reference end strays sit 1.442 away while the edge measured is at 2.000, so anything reaching the second by distance alone has already taken the first.

Parameters:
  • length – How far ahead to look. A maximum reach, never a step: gaps run from 0.00 to 2.00.

  • width – Total width, so a feature is tolerated width / 2 off the axis. Answers hold from 0.01 to 1.0; at 2.0 an end starts finding a neighbouring edge 0.80 off its own extension line.

  • tolerance – Precision below which two distances count as equal.

length: float = 2.0#
width: float = 0.2#
tolerance: float = 0.001#
__post_init__() → None#

Refuse a corridor with no extent, which would silently reach nothing.

Raises:

ValueError – On a length, width or tolerance that is not strictly positive.

property half_width: float#

Distance from the corridor axis to either of its long sides.

first_hit(start: volmdlr.Point2D, direction: volmdlr.Vector2D, edges: list[Edge]) → CorridorHit | None#

Return the first point the corridor reaches, on the edge carrying it.

Sweep, keep those closest to the axis, keep those met first, take the one whose edge runs most along the corridor.

Parameters:
  • start – Point the corridor starts from, an extension line’s far end.

  • direction – Unit vector the corridor runs along.

  • edges – Edges to search, typically the solid edges of the view.

Returns:

The first hit, or None when the corridor reaches no edge.

corners(start: Point2D, direction: Vector2D) → list[Point2D]#

Return the four corners of the corridor, walked in order so joining them closes it.

Parameters:
  • start – Point the corridor starts from.

  • direction – Unit vector the corridor runs along.

Returns:

The corners.

bounding_rectangle(start: Point2D, direction: Vector2D) → BoundingRectangle#

Return the axis-aligned box enclosing the corridor, grown by tolerance.

The growth is load-bearing: is_intersecting is strict, so a corridor ending exactly on the edge it measures would be sifted out.

Parameters:
  • start – Point the corridor starts from.

  • direction – Unit vector the corridor runs along.

Returns:

The box.

__init__(length: float = 2.0, width: float = 0.2, tolerance: float = 0.001) → None#

drawing_tools.helpers.dimension.ends module#

The two ends of a dimension, each with the three positions a drawing gives it.

SEARCHED_DIMENSION_TYPES lists the entity_type values whose ends are searched for the geometry they measure – DistanceDimension, LengthDimension and LinearDimension. Those are the kinds that cross a deliberate gap: a radius or diameter arrow already touches its arc, and an angular dimension’s ends sit on the legs it measures.

DEGENERATE_EXTENSION_LINE_LENGTH is the length below which an extension line runs in no direction at all, and AMBIGUOUS_ARROW_OFFSET the difference below which an arrow is equidistant from both of its ends, so which one faces the geometry cannot be told. Both are in drawing units, and both make the end unsearchable rather than pointing the search at random.

class drawing_tools.helpers.dimension.ends.DimensionEnd(arrow_head: ArrowHead | None, extension_line_end_point: volmdlr.Point2D | None, measured_point: volmdlr.Point2D, measured_edge: Edge | None, search_direction: volmdlr.Vector2D | None, distance_ahead: float | None = None, distance_off_axis: float | None = None)#

Bases: object

One end of a dimension, and the three distinct positions it holds.

Their values on the reference dimension “26” of condor_ETIQUETTES.json:

arrow_head.location       (795.57, 730.28)  on the dimension line, the arrow tip
extension_line_end_point  (795.57, 629.35)  where the export stops the extension line
measured_point            (795.57, 627.35)  on the part, what the end actually measures

The first two are 100.93 apart, the last two 2.00 – a small error, but enough to name the wrong feature.

Nothing is written back onto the Dimension, so an end is re-derived unless the analyzer that built it is reused.

arrow_head: ArrowHead | None#

The arrow of this end, on the dimension line. Native, read from the end’s own leader.

extension_line_end_point: volmdlr.Point2D | None#

Where the export stops the extension line. Native. None on an end drawn without one.

measured_point: volmdlr.Point2D#

The point on the geometry this end measures. Falls back to extension_line_end_point both when no search ran – see SEARCHED_DIMENSION_TYPES – and when one ran and reached nothing; was_searched and reached_geometry tell the two apart.

measured_edge: Edge | None#

The edge measured_point was found on. None when the search reached nothing.

search_direction: volmdlr.Vector2D | None#

Unit vector the search ran along, from the arrow towards the geometry. None on an end that was not searched.

distance_ahead: float | None = None#

How far down the extension line the measured point was reached. None when unsearched or when the search reached nothing.

distance_off_axis: float | None = None#

How far the measured point sits off that line, which is what the corridor’s width has to cover. None when unsearched or when the search reached nothing.

__init__(arrow_head: ArrowHead | None, extension_line_end_point: volmdlr.Point2D | None, measured_point: volmdlr.Point2D, measured_edge: Edge | None, search_direction: volmdlr.Vector2D | None, distance_ahead: float | None = None, distance_off_axis: float | None = None) → None#
property measured_gap: float | None#

Return the gap the drawing left between the extension line and what it measures.

Runs from 0.00, where the extension line already starts on the geometry, up to 2.00. A value far from the drawing’s own standard is itself a signal a check can act on.

None rather than 0.00 on an end no search ran on: the two are not the same fact, and a fabricated zero would read as “this drawing left no gap here”.

Returns:

The gap, or None on an end drawn without an extension line or never searched.

property was_searched: bool#

Whether a search ran on this end at all – see SEARCHED_DIMENSION_TYPES.

property reached_geometry: bool#

Whether the search found geometry, as opposed to falling back to the extension line.

drawing_tools.helpers.dimension.ends.dimension_ends(dimension: Dimension, constraint_points: list[DimensionConstraintPoint], edges: list[Edge], corridor: SearchCorridor) → list[DimensionEnd]#

Return one DimensionEnd per constraint point of a dimension.

The arrow of an end and its constraint point are paired by IDENTITY, not by distance. Which object carries that identity depends on where the point came from: a point read off an extension line names the very Edge a leader carries as its extension_line, while a point read off a leader – a radius or a diameter, which have no extension line at all – names that Leader itself.

Parameters:
  • dimension – The dimension whose ends are wanted.

  • constraint_points – Its constraint points, carrying which extension line produced each.

  • edges – Edges the measured point is searched among, typically the view’s solid edges.

  • corridor – The directional search to run from each extension line end.

Returns:

One end per constraint point, in the order the export gives them.

drawing_tools.helpers.dimension.geometry module#

Utility functions for finding edges near points.

drawing_tools.helpers.dimension.geometry.find_edges_near_points(point_mapper: Any, points: list[Point2D], tolerance: float) → dict[Point2D, list[Edge]]#

Standalone utility function to find edges near given points using a point mapper.

This function can be used by any class that needs to find edges near points, avoiding tight coupling between processors and analyzers.

Parameters:
  • point_mapper – PointToEdgeMapper instance

  • points – List of points to find edges near

  • tolerance – Distance tolerance for point matching

Returns:

Dictionary mapping each point to its nearby edges

Module contents#

Dimension analysis utilities and helpers.

The way in is DimensionAnalyzer.get_dimension_ends(dimension), which builds the corridor, runs it over the view’s own edges and memoizes the result. DimensionEnd is what it returns, SearchCorridor the search it runs, and SEARCHED_DIMENSION_TYPES the dimension kinds an end of which is searched at all.

find_dimension_attachments() reads those ends the other way round: given the edges of an element, it returns the end of a dimension landing on it and the end it is measured from. find_extension_line_alignments() needs no end: it returns the edges of an element lying on the line of an extension line, whether or not that line reaches them.

class drawing_tools.helpers.dimension.DimensionAttachment(dimension: Dimension, end_on_target: DimensionEnd, other_end: DimensionEnd, target_edge: Edge)#

Bases: object

One END of a dimension landing on a target edge, with the other end it is measured from.

Parameters:
  • dimension – The dimension of the view, as the export carries it.

  • end_on_target – Its end on the target, whose measured_point is where it touches.

  • other_end – Its other end, on the target or on anything else – no attribute says which, a second attachment of the same dimension does.

  • target_edge – The edge of the target that end landed on, which identifies WHICH target was reached when several were searched at once.

dimension: Dimension#
end_on_target: DimensionEnd#
other_end: DimensionEnd#
target_edge: Edge#
__init__(dimension: Dimension, end_on_target: DimensionEnd, other_end: DimensionEnd, target_edge: Edge) → None#
class drawing_tools.helpers.dimension.DimensionConstraintPoint(point: Point2D, source_type: Literal['extension_line', 'leader'], source_object: Edge | Leader, source_index: int, direction_vector: Vector2D | None = None)#

Bases: object

Represents a constraint point extracted from a dimension with metadata.

This class provides context about where the constraint point came from (extension line or leader), which specific line/leader it was extracted from, and the direction vector at that point.

This metadata is crucial for proper edge matching in angular dimensions, where we need to ensure edges align with the extension line directions.

point: Point2D#

The actual constraint point location

source_type: Literal['extension_line', 'leader']#

Whether this point came from an extension line or a leader

source_object: Edge | Leader#

Reference to the actual extension line Edge or Leader object

source_index: int#

Index of the source in the dimension’s extension_lines or leaders list

direction_vector: Vector2D | None = None#

Direction vector at the constraint point. - For extension lines: the unit direction vector of the extension line - For leaders: the direction vector of the leader at the arrow tip

__post_init__()#

Compute direction vector if not provided.

matches_direction(edge: Edge, angular_tolerance: float = 0.001) → bool#

Check if an edge’s direction at this constraint point matches the source direction.

This is particularly useful for angular dimensions where we need to match edges based on their alignment with extension lines.

Parameters:
  • edge – Edge to check

  • angular_tolerance – Angular tolerance in radians (default ~2.6 degrees)

Returns:

True if edge direction matches (parallel or anti-parallel)

__init__(point: Point2D, source_type: Literal['extension_line', 'leader'], source_object: Edge | Leader, source_index: int, direction_vector: Vector2D | None = None) → None#
class drawing_tools.helpers.dimension.DimensionConstraintPointsProcessor(dimension: Dimension, tolerance: float = 0.001, point_mapper: Any | None = None)#

Bases: object

Processor for extracting geometric constraint reference points from dimensions.

This processor implements multiple strategies to identify the precise points where a dimension constrains the underlying geometry. It uses smart extension line analysis, leader arrow evaluation, and geometric heuristics to determine optimal constraint points.

The processor follows a strategy pattern with fallback mechanisms: 1. Smart extension line analysis (most reliable for linear/length dimensions) 2. Leader arrow analysis (reliable for radius/diameter dimensions) 3. Related geometric elements analysis 4. Dimension frame fallback

__init__(dimension: Dimension, tolerance: float = 0.001, point_mapper: Any | None = None) → None#

Initialize the processor with a dimension object.

Parameters:
  • dimension – The dimension object to process

  • tolerance – Distance tolerance for point matching

  • point_mapper – Optional PointToEdgeMapper instance for edge finding

property constraint_points: list[DimensionConstraintPoint]#

Extract constraint points with metadata where the dimension constrains the geometry.

This property implements multiple strategies with smart extension line analysis that selects the optimal constraint points and enriches them with metadata about their source (extension line or leader), direction vectors, and indices.

Returns:

List of dimension constraint point objects

property constraint_points_simple: list[Point2D]#

Extract constraint points as simple Point2D objects (backward compatibility).

Returns:

List of constraint points (Point2D only, no metadata)

property geometry_constraint_points: list[Point2D]#

Extract the actual geometry points that the dimension constrains.

This method uses the same strategy as _get_edges_at_points - finding the nearest edges to constraint points using the point mapper, then extracting the closest points on those edges. This accounts for the typical 1-2mm offset between extension lines and geometry in technical drawings.

Returns:

List of actual geometry constraint points (Point2D objects)

class drawing_tools.helpers.dimension.DimensionEnd(arrow_head: ArrowHead | None, extension_line_end_point: volmdlr.Point2D | None, measured_point: volmdlr.Point2D, measured_edge: Edge | None, search_direction: volmdlr.Vector2D | None, distance_ahead: float | None = None, distance_off_axis: float | None = None)#

Bases: object

One end of a dimension, and the three distinct positions it holds.

Their values on the reference dimension “26” of condor_ETIQUETTES.json:

arrow_head.location       (795.57, 730.28)  on the dimension line, the arrow tip
extension_line_end_point  (795.57, 629.35)  where the export stops the extension line
measured_point            (795.57, 627.35)  on the part, what the end actually measures

The first two are 100.93 apart, the last two 2.00 – a small error, but enough to name the wrong feature.

Nothing is written back onto the Dimension, so an end is re-derived unless the analyzer that built it is reused.

arrow_head: ArrowHead | None#

The arrow of this end, on the dimension line. Native, read from the end’s own leader.

extension_line_end_point: volmdlr.Point2D | None#

Where the export stops the extension line. Native. None on an end drawn without one.

measured_point: volmdlr.Point2D#

The point on the geometry this end measures. Falls back to extension_line_end_point both when no search ran – see SEARCHED_DIMENSION_TYPES – and when one ran and reached nothing; was_searched and reached_geometry tell the two apart.

measured_edge: Edge | None#

The edge measured_point was found on. None when the search reached nothing.

search_direction: volmdlr.Vector2D | None#

Unit vector the search ran along, from the arrow towards the geometry. None on an end that was not searched.

distance_ahead: float | None = None#

How far down the extension line the measured point was reached. None when unsearched or when the search reached nothing.

distance_off_axis: float | None = None#

How far the measured point sits off that line, which is what the corridor’s width has to cover. None when unsearched or when the search reached nothing.

__init__(arrow_head: ArrowHead | None, extension_line_end_point: volmdlr.Point2D | None, measured_point: volmdlr.Point2D, measured_edge: Edge | None, search_direction: volmdlr.Vector2D | None, distance_ahead: float | None = None, distance_off_axis: float | None = None) → None#
property measured_gap: float | None#

Return the gap the drawing left between the extension line and what it measures.

Runs from 0.00, where the extension line already starts on the geometry, up to 2.00. A value far from the drawing’s own standard is itself a signal a check can act on.

None rather than 0.00 on an end no search ran on: the two are not the same fact, and a fabricated zero would read as “this drawing left no gap here”.

Returns:

The gap, or None on an end drawn without an extension line or never searched.

property was_searched: bool#

Whether a search ran on this end at all – see SEARCHED_DIMENSION_TYPES.

property reached_geometry: bool#

Whether the search found geometry, as opposed to falling back to the extension line.

class drawing_tools.helpers.dimension.ExtensionLineAlignment(dimension: Dimension, extension_line: Edge, target_edge: Edge)#

Bases: object

One target edge lying on the line of one extension line of a dimension.

Parameters:
  • dimension – The dimension, as the export carries it.

  • extension_line – The extension line of that dimension.

  • target_edge – The target edge lying on its line.

dimension: Dimension#
extension_line: Edge#
target_edge: Edge#
__init__(dimension: Dimension, extension_line: Edge, target_edge: Edge) → None#
class drawing_tools.helpers.dimension.SearchCorridor(length: float = 2.0, width: float = 0.2, tolerance: float = 0.001)#

Bases: object

A rectangle swept from a point along a direction, to find the geometry that lies ahead.

TRAP: the shape has to stay directional. Whatever lies to the SIDE of the sweep is never reached, and that is what separates the edge measured from a stray merely passing by – at one reference end strays sit 1.442 away while the edge measured is at 2.000, so anything reaching the second by distance alone has already taken the first.

Parameters:
  • length – How far ahead to look. A maximum reach, never a step: gaps run from 0.00 to 2.00.

  • width – Total width, so a feature is tolerated width / 2 off the axis. Answers hold from 0.01 to 1.0; at 2.0 an end starts finding a neighbouring edge 0.80 off its own extension line.

  • tolerance – Precision below which two distances count as equal.

length: float = 2.0#
width: float = 0.2#
tolerance: float = 0.001#
__post_init__() → None#

Refuse a corridor with no extent, which would silently reach nothing.

Raises:

ValueError – On a length, width or tolerance that is not strictly positive.

property half_width: float#

Distance from the corridor axis to either of its long sides.

first_hit(start: volmdlr.Point2D, direction: volmdlr.Vector2D, edges: list[Edge]) → CorridorHit | None#

Return the first point the corridor reaches, on the edge carrying it.

Sweep, keep those closest to the axis, keep those met first, take the one whose edge runs most along the corridor.

Parameters:
  • start – Point the corridor starts from, an extension line’s far end.

  • direction – Unit vector the corridor runs along.

  • edges – Edges to search, typically the solid edges of the view.

Returns:

The first hit, or None when the corridor reaches no edge.

corners(start: Point2D, direction: Vector2D) → list[Point2D]#

Return the four corners of the corridor, walked in order so joining them closes it.

Parameters:
  • start – Point the corridor starts from.

  • direction – Unit vector the corridor runs along.

Returns:

The corners.

bounding_rectangle(start: Point2D, direction: Vector2D) → BoundingRectangle#

Return the axis-aligned box enclosing the corridor, grown by tolerance.

The growth is load-bearing: is_intersecting is strict, so a corridor ending exactly on the edge it measures would be sifted out.

Parameters:
  • start – Point the corridor starts from.

  • direction – Unit vector the corridor runs along.

Returns:

The box.

__init__(length: float = 2.0, width: float = 0.2, tolerance: float = 0.001) → None#
drawing_tools.helpers.dimension.dimension_ends(dimension: Dimension, constraint_points: list[DimensionConstraintPoint], edges: list[Edge], corridor: SearchCorridor) → list[DimensionEnd]#

Return one DimensionEnd per constraint point of a dimension.

The arrow of an end and its constraint point are paired by IDENTITY, not by distance. Which object carries that identity depends on where the point came from: a point read off an extension line names the very Edge a leader carries as its extension_line, while a point read off a leader – a radius or a diameter, which have no extension line at all – names that Leader itself.

Parameters:
  • dimension – The dimension whose ends are wanted.

  • constraint_points – Its constraint points, carrying which extension line produced each.

  • edges – Edges the measured point is searched among, typically the view’s solid edges.

  • corridor – The directional search to run from each extension line end.

Returns:

One end per constraint point, in the order the export gives them.

drawing_tools.helpers.dimension.find_dimension_attachments(dimension: Dimension, dimension_ends: list[DimensionEnd], target_edges: list[Edge], max_distance: float) → list[DimensionAttachment]#

Return one attachment per end of dimension landing on target_edges, in the export’s order.

A dimension whose ends could not both be read is left out: telling an end from the other is what the attachment is for.

The end is placed by WHICH edge its measured point lands on – find_edge_at_point() – never by how near a box is, so the geometry around the target cannot be mistaken for it.

Parameters:
  • dimension – The dimension read.

  • dimension_ends – Its ends, from DimensionAnalyzer.get_dimension_ends.

  • target_edges – The edges of everything searched at once.

  • max_distance – Slack between a measured point and an edge, in drawing units.

Returns:

Zero, one or two attachments.

drawing_tools.helpers.dimension.find_edges_near_points(point_mapper: Any, points: list[Point2D], tolerance: float) → dict[Point2D, list[Edge]]#

Standalone utility function to find edges near given points using a point mapper.

This function can be used by any class that needs to find edges near points, avoiding tight coupling between processors and analyzers.

Parameters:
  • point_mapper – PointToEdgeMapper instance

  • points – List of points to find edges near

  • tolerance – Distance tolerance for point matching

Returns:

Dictionary mapping each point to its nearby edges

drawing_tools.helpers.dimension.find_extension_line_alignments(dimensions: list[Dimension], target_edges: list[Edge], max_offset: float) → list[ExtensionLineAlignment]#

Return one alignment per (extension line, target edge lying on its line) pair.

Parameters:
  • dimensions – The dimensions read, typically every dimension of a view.

  • target_edges – The edges of everything searched at once.

  • max_offset – How far each end of a target edge may sit from the line, in drawing units.

Returns:

The alignments, dimensions and their extension lines in the order given, then target edges in the order given.