build123d
build123d copied to clipboard
ExtensionLine / DimensionLine complain that start > end
This code is adapted from docs/objects_2d.py:
std = Draft()
# [ExtensionLine]
with BuildSketch() as e_line:
with BuildLine():
l1 = Polyline((20, 40), (-40, 40), (-40, -40), (20, -40))
RadiusArc(l1 @ 0, l1 @ 1, 50)
make_face()
edg = e_line.edges().sort_by(Axis.X)[0]
ExtensionLine(border=edg, offset=10, draft=std)
outside_curve = e_line.edges().sort_by(Axis.X)[-1]
ExtensionLine(border=outside_curve, offset=10, label_angle=True, draft=std)
# [TechnicalDrawing]
with BuildSketch() as tech_drawing:
with Locations((0, 20)):
add(e_line)
TechnicalDrawing()
Returns:
ValueError Traceback (most recent call last)
24 ExtensionLine(border=edg, offset=10, draft=std)
25 outside_curve = e_line.edges().sort_by(Axis.X)[-1]
---> 26 ExtensionLine(border=outside_curve, offset=10, label_angle=True, draft=std)
28 # [TechnicalDrawing]
29 with BuildSketch() as tech_drawing:
File c:\Users\someuser\.conda\envs\ocp_vscode\Lib\site-packages\build123d\drafting.py:562, in ExtensionLine.__init__(self, border, offset, draft, sketch, label, arrows, tolerance, label_angle, project_line, mode)
560 e_line_shape = sweep(line_pen, extension_line, mode=Mode.PRIVATE)
561 e_lines.append(e_line_shape)
--> 562 d_line = DimensionLine(
563 dimension_path,
564 draft,
565 sketch,
566 label,
567 arrows,
568 tolerance,
569 label_angle,
570 mode=Mode.PRIVATE,
571 )
572 self.dimension = d_line.dimension #: length of the dimension
574 e_line_sketch = Sketch(children=e_lines + d_line.faces())
File c:\Users\someuser\.conda\envs\ocp_vscode\Lib\site-packages\build123d\drafting.py:410, in DimensionLine.__init__(self, path, draft, sketch, label, arrows, tolerance, label_angle, mode)
406 if label_length + arrows.count(True) * draft.arrow_length < path_length:
407 shaft_length = (path_length - label_length) / 2 - draft.pad_around_text
408 shaft_pair = [
409 path_obj.trim(0.0, shaft_length / path_length),
--> 410 path_obj.trim(1.0 - shaft_length / path_length, 1.0),
411 ]
412 else:
413 shaft_length = 2 * draft.arrow_length
File c:\Users\someuser\.conda\envs\ocp_vscode\Lib\site-packages\build123d\topology.py:7785, in Wire.trim(self, start, end)
7783 u_start = edge.param_at_point(trim_start_point)
7784 u_end = edge.param_at_point(trim_end_point)
-> 7785 edge = edge.trim(u_start, u_end)
7786 elif contains_start:
7787 u_value = edge.param_at_point(trim_start_point)
File c:\Users\someuser\.conda\envs\ocp_vscode\Lib\site-packages\build123d\topology.py:4609, in Edge.trim(self, start, end)
4594 """trim
4595
4596 Create a new edge by keeping only the section between start and end.
(...)
4606 Edge: trimmed edge
4607 """
4608 if start >= end:
-> 4609 raise ValueError(f"start ({start}) must be less than end ({end})")
4611 new_curve = BRep_Tool.Curve_s(
4612 copy.deepcopy(self).wrapped, self.param_at(0), self.param_at(1)
4613 )
4614 parm_start = self.param_at(start)
ValueError: start (0.8165271836783728) must be less than end (0.0)
I have also observed some non-repeatable sporadic behavior in which this fails on the first call to ExtensionLine (in the same way as above). Perhaps the line is reversed at some point?
Running the exact same code, I get a different error. MacOS and build123d 0.7.0:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[61], line 12
10 #ExtensionLine(border=edg, offset=10, draft=std)
11 outside_curve = e_line.edges().sort_by(Axis.X)[-1]
---> 12 ExtensionLine(border=outside_curve, offset=10, label_angle=True, draft=std)
14 # [TechnicalDrawing]
15 with BuildSketch() as tech_drawing:
File ~/miniconda3/envs/default/lib/python3.12/site-packages/build123d/drafting.py:562, in ExtensionLine.__init__(self, border, offset, draft, sketch, label, arrows, tolerance, label_angle, project_line, mode)
560 e_line_shape = sweep(line_pen, extension_line, mode=Mode.PRIVATE)
561 e_lines.append(e_line_shape)
--> 562 d_line = DimensionLine(
563 dimension_path,
564 draft,
565 sketch,
566 label,
567 arrows,
568 tolerance,
569 label_angle,
570 mode=Mode.PRIVATE,
571 )
572 self.dimension = d_line.dimension #: length of the dimension
574 e_line_sketch = Sketch(children=e_lines + d_line.faces())
File ~/miniconda3/envs/default/lib/python3.12/site-packages/build123d/drafting.py:409, in DimensionLine.__init__(self, path, draft, sketch, label, arrows, tolerance, label_angle, mode)
406 if label_length + arrows.count(True) * draft.arrow_length < path_length:
407 shaft_length = (path_length - label_length) / 2 - draft.pad_around_text
408 shaft_pair = [
--> 409 path_obj.trim(0.0, shaft_length / path_length),
410 path_obj.trim(1.0 - shaft_length / path_length, 1.0),
411 ]
412 else:
413 shaft_length = 2 * draft.arrow_length
File ~/miniconda3/envs/default/lib/python3.12/site-packages/build123d/topology.py:8020, in Wire.trim(self, start, end)
8017 if v_edge != 1:
8018 new_edges.append(e.trim(v_edge, 1))
-> 8020 return Wire(new_edges)
File ~/miniconda3/envs/default/lib/python3.12/site-packages/build123d/topology.py:7819, in Wire.__init__(self, *args, **kwargs)
7817 obj = wire.wrapped
7818 elif edges:
-> 7819 obj = Wire._make_wire(edges, False if sequenced is None else sequenced)
7821 super().__init__(
7822 obj=obj,
7823 label="" if label is None else label,
7824 color=color,
7825 parent=parent,
7826 )
File ~/miniconda3/envs/default/lib/python3.12/site-packages/build123d/topology.py:8115, in Wire._make_wire(cls, edges, sequenced)
8113 raise RuntimeError("Wire is empty")
8114 elif wire_builder.Error() == BRepBuilderAPI_DisconnectedWire:
-> 8115 raise ValueError("Edges are disconnected")
8117 return wire_builder.Wire()
ValueError: Edges are disconnected
Changing the problematic code from ExtensionLine to DimensionLine works, but doesn’t generate the desired output, of course:
DimensionLine(path=outside_curve, label_angle=True, draft=std)
@tshead I can confirm that the error message has changed. I am seeing the same error message as you but I am running
a slightly newer development version 0.7.1.dev4+g043629e. There have been some changes to edges/wire trim since this issue was created so I am not surprised the error has changed a bit.
Alright, doing some more investigation, an internal object after being offset is producing a wire with three edges from a wire with one edge. The trim function is having trouble processing the three edge wire, after looking I have determined that running Wire.clean() will reduce the numbers of edges back down to one at which point ExtensionLine will run just fine. I am not sure this is the best general solution and I suspect that the issue may actually lie in the offset_2d method.
@jdegenstein I appreciate you looking into this, but I’m not following you on how to use Wire.clean() in this case - could you expound on that a bit?
Many thanks, Tim