From e23ccdc4547b152069f7466fce6ca13f577bfa73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20N=C3=A4slund?= Date: Fri, 27 Apr 2018 20:45:53 +0200 Subject: [PATCH] Add logic to the close() command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit b281a4c6ca4f85b62cc26f2bc0293c6be5c708f4 Author: Gustav Näslund Date: Fri Apr 27 07:17:39 2018 +0200 Fix converting to global coords in threePointArc Add more elaborate testcases with workplane origin moved and comparing the result of volumes created by threePointArc and sagittaArc. commit 679eb215296630803cb253da904a0e3077e798e9 Author: Gustav Näslund Date: Thu Apr 26 22:21:06 2018 +0200 Use local coordinates and not global coordinates in close() When getting the endPoint in close() ; use local coordinates and not global coordinates. It does matter when the origin of the workplane is moved. commit d458dcb22ce338e342f4e22b8b3d84f7a358ffaa Author: Gustav Näslund Date: Wed Apr 25 17:47:02 2018 +0200 Add logic to the close command If start and end point of a set of 2d edges coincide; create a wire directly. If there is a distance between start and end point; add a line segment before creating the wire. --- cadquery/cq.py | 15 ++++++++++----- tests/TestCadQuery.py | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/cadquery/cq.py b/cadquery/cq.py index ba82d31..9ed9d16 100644 --- a/cadquery/cq.py +++ b/cadquery/cq.py @@ -1321,10 +1321,8 @@ def threePointArc(self, point1, point2, forConstruction=False): """ startPoint = self._findFromPoint(False) - if not isinstance(point1, Vector): - point1 = self.plane.toWorldCoords(point1) - if not isinstance(point2, Vector): - point2 = self.plane.toWorldCoords(point2) + point1 = self.plane.toWorldCoords(point1) + point2 = self.plane.toWorldCoords(point2) arc = Edge.makeThreePointArc(startPoint, point1, point2) @@ -1800,7 +1798,14 @@ def close(self): s = Workplane().lineTo(1,0).lineTo(1,1).close().extrude(0.2) """ - self.lineTo(self.ctx.firstPoint.x, self.ctx.firstPoint.y) + endPoint = self._findFromPoint(True) + startPoint = self.ctx.firstPoint + + # Check if there is a distance between startPoint and endPoint + # that is larger than what is considered a numerical error. + # If so; add a line segment between endPoint and startPoint + if endPoint.sub(startPoint).Length > 1e-6: + self.lineTo(self.ctx.firstPoint.x, self.ctx.firstPoint.y) # Need to reset the first point after closing a wire self.ctx.firstPoint=None diff --git a/tests/TestCadQuery.py b/tests/TestCadQuery.py index 57d19b1..64cadd0 100644 --- a/tests/TestCadQuery.py +++ b/tests/TestCadQuery.py @@ -1605,3 +1605,36 @@ def testExtrude(self): self.assertTupleAlmostEquals(delta.toTuple(), (0.,0.,2.*h), decimal_places) + + def testClose(self): + # Close without endPoint and startPoint coincide. + # Create a half-circle + a = Workplane(Plane.XY()).sagittaArc((10, 0), 2).close().extrude(2) + + # Close when endPoint and startPoint coincide. + # Create a double half-circle + b = Workplane(Plane.XY()).sagittaArc((10, 0), 2).sagittaArc((0, 0), 2).close().extrude(2) + + # The b shape shall have twice the volume of the a shape. + self.assertAlmostEqual(a.val().wrapped.Volume * 2.0, b.val().wrapped.Volume) + + # Testcase 3 from issue #238 + thickness = 3.0 + length = 10.0 + width = 5.0 + + obj1 = Workplane('XY', origin=(0, 0, -thickness / 2)) \ + .moveTo(length / 2, 0).threePointArc((0, width / 2), (-length / 2, 0)) \ + .threePointArc((0, -width / 2), (length / 2, 0)) \ + .close().extrude(thickness) + + os_x = 8.0 # Offset in X + os_y = -19.5 # Offset in Y + + obj2 = Workplane('YZ', origin=(os_x, os_y, -thickness / 2)) \ + .moveTo(os_x + length / 2, os_y).sagittaArc((os_x -length / 2, os_y), width / 2) \ + .sagittaArc((os_x + length / 2, os_y), width / 2) \ + .close().extrude(thickness) + + # The obj1 shape shall have the same volume as the obj2 shape. + self.assertAlmostEqual(obj1.val().wrapped.Volume, obj2.val().wrapped.Volume)