From 19a71b994446e6419d4e1f8e7fb92aeb293e3489 Mon Sep 17 00:00:00 2001 From: adam-urbanczyk <13981538+adam-urbanczyk@users.noreply.github.com> Date: Wed, 17 Jun 2026 21:03:38 +0200 Subject: [PATCH 1/3] Fix startPoint and endPoint for reversed edges --- cadquery/occ_impl/shapes.py | 37 +++++++++++++++++++++++++++++-------- tests/test_cadquery.py | 10 +++++----- tests/test_shapes.py | 9 +++++++++ 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/cadquery/occ_impl/shapes.py b/cadquery/occ_impl/shapes.py index bc03818af..bbaa4579f 100644 --- a/cadquery/occ_impl/shapes.py +++ b/cadquery/occ_impl/shapes.py @@ -281,6 +281,7 @@ ShapeAnalysis_Edge, ShapeAnalysis_Wire, ShapeAnalysis_Surface, + ShapeAnalysis, ) from OCP.TopTools import TopTools_HSequenceOfShape @@ -2112,10 +2113,10 @@ def startPoint(self: Mixin1DProtocol) -> Vector: Note, circles may have the start and end points the same """ - curve = self._geomAdaptor() - umin = curve.FirstParameter() + v1, _ = TopoDS_Vertex(), TopoDS_Vertex() + ShapeAnalysis.FindBounds_s(self.wrapped, v1, _) - return Vector(curve.Value(umin)) + return Vertex(v1).Center() def endPoint(self: Mixin1DProtocol) -> Vector: """ @@ -2125,10 +2126,10 @@ def endPoint(self: Mixin1DProtocol) -> Vector: Note, circles may have the start and end points the same """ - curve = self._geomAdaptor() - umax = curve.LastParameter() + _, v2 = TopoDS_Vertex(), TopoDS_Vertex() + ShapeAnalysis.FindBounds_s(self.wrapped, _, v2) - return Vector(curve.Value(umax)) + return Vertex(v2).Center() def _approxCurve(self: Mixin1DProtocol) -> Geom_BSplineCurve: """ @@ -7032,6 +7033,8 @@ def offset2D( ctx: Shape | None = None, kind: Literal["arc", "intersection", "tangent"] = "arc", closed: bool = True, + history: History | None = None, + name: str | None = None, ) -> Shape: """ 2D offset edges or wires. ctx face might be needed for ambiguous wires/edges. @@ -7065,10 +7068,18 @@ def offset2D( bldr.Perform(t) + _update_history(history, name, [s,], bldr) + return _compound_or_shape(bldr.Shape()) -def chamfer2D(s: Shape, verts: Shape, d: float): +def chamfer2D( + s: Shape, + verts: Shape, + d: float, + history: History | None = None, + name: str | None = None, +) -> Shape: """ Apply a 2D chamfer to a planar face. """ @@ -7091,10 +7102,18 @@ def chamfer2D(s: Shape, verts: Shape, d: float): bldr.Build() + _update_history(history, name, [f, verts], bldr) + return _compound_or_shape(bldr.Shape()) -def fillet2D(s: Shape, verts: Shape, r: float): +def fillet2D( + s: Shape, + verts: Shape, + r: float, + history: History | None = None, + name: str | None = None, +) -> Shape: """ Apply a 2D fillet to a planar face. """ @@ -7108,6 +7127,8 @@ def fillet2D(s: Shape, verts: Shape, r: float): bldr.Build() + _update_history(history, name, [f, verts], bldr) + return _compound_or_shape(bldr.Shape()) diff --git a/tests/test_cadquery.py b/tests/test_cadquery.py index 23cc6386b..09875368f 100644 --- a/tests/test_cadquery.py +++ b/tests/test_cadquery.py @@ -313,12 +313,12 @@ def testRotate(self): startPoint = box.faces("Z").edges(">X").first().val().startPoint().toTuple() + point = result.faces(">Z").edges(">X").first().val().endPoint().toTuple() self.assertTupleAlmostEquals( point, (0.707106781, 1.414213562, 1.0), decimal_places ) diff --git a/tests/test_shapes.py b/tests/test_shapes.py index bb34fdce5..3309093d6 100644 --- a/tests/test_shapes.py +++ b/tests/test_shapes.py @@ -475,3 +475,12 @@ def test_set_ops(simple_box): assert (simple_box.faces(">Z") | simple_box.faces("Z") & simple_box.faces(" Date: Thu, 18 Jun 2026 19:55:38 +0200 Subject: [PATCH 2/3] Revert unwanted changes --- cadquery/occ_impl/shapes.py | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/cadquery/occ_impl/shapes.py b/cadquery/occ_impl/shapes.py index bbaa4579f..e8c35e799 100644 --- a/cadquery/occ_impl/shapes.py +++ b/cadquery/occ_impl/shapes.py @@ -7073,13 +7073,7 @@ def offset2D( return _compound_or_shape(bldr.Shape()) -def chamfer2D( - s: Shape, - verts: Shape, - d: float, - history: History | None = None, - name: str | None = None, -) -> Shape: +def chamfer2D(s: Shape, verts: Shape, d: float,) -> Shape: """ Apply a 2D chamfer to a planar face. """ @@ -7102,18 +7096,10 @@ def chamfer2D( bldr.Build() - _update_history(history, name, [f, verts], bldr) - return _compound_or_shape(bldr.Shape()) -def fillet2D( - s: Shape, - verts: Shape, - r: float, - history: History | None = None, - name: str | None = None, -) -> Shape: +def fillet2D(s: Shape, verts: Shape, r: float,) -> Shape: """ Apply a 2D fillet to a planar face. """ @@ -7127,8 +7113,6 @@ def fillet2D( bldr.Build() - _update_history(history, name, [f, verts], bldr) - return _compound_or_shape(bldr.Shape()) From 3c31b75a1cd6d2bdb91d777e42211ebc0e7adf0c Mon Sep 17 00:00:00 2001 From: adam-urbanczyk <13981538+adam-urbanczyk@users.noreply.github.com> Date: Thu, 18 Jun 2026 20:00:43 +0200 Subject: [PATCH 3/3] Revert unwanted changes --- cadquery/occ_impl/shapes.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/cadquery/occ_impl/shapes.py b/cadquery/occ_impl/shapes.py index e8c35e799..862cbe354 100644 --- a/cadquery/occ_impl/shapes.py +++ b/cadquery/occ_impl/shapes.py @@ -7033,8 +7033,6 @@ def offset2D( ctx: Shape | None = None, kind: Literal["arc", "intersection", "tangent"] = "arc", closed: bool = True, - history: History | None = None, - name: str | None = None, ) -> Shape: """ 2D offset edges or wires. ctx face might be needed for ambiguous wires/edges. @@ -7068,8 +7066,6 @@ def offset2D( bldr.Perform(t) - _update_history(history, name, [s,], bldr) - return _compound_or_shape(bldr.Shape())