From a140d1035c5ef058a5c89554ef7390873e10c370 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Urba=C5=84czyk?= Date: Wed, 6 May 2020 08:58:35 +0200 Subject: [PATCH] Add support for slicing (#339) * Allow constructing infinite planes * Preliminary section implementation * Better error message * Section related tests --- cadquery/cq.py | 21 +++++++++++++++++++++ cadquery/occ_impl/shapes.py | 11 +++++++---- tests/test_cadquery.py | 15 +++++++++++++++ 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/cadquery/cq.py b/cadquery/cq.py index c987c9b42..cfd4eee7b 100644 --- a/cadquery/cq.py +++ b/cadquery/cq.py @@ -3420,6 +3420,27 @@ def text( newS = newS.clean() return newS + def section(self, height=0.0): + """ + Slices current solid at the given height. + + :param float height: height to slice at (default: 0) + :return: a CQ object with the resulting face(s). + """ + + solidRef = self.findSolid(searchStack=True, searchParents=True) + + if solidRef is None: + raise ValueError("Cannot find solid to slice") + + plane = Face.makePlane( + basePnt=self.plane.origin + self.plane.zDir * height, dir=self.plane.zDir + ) + + r = solidRef.intersect(plane) + + return self.newObject([r]) + def _repr_html_(self): """ Special method for rendering current object in a jupyter notebook diff --git a/cadquery/occ_impl/shapes.py b/cadquery/occ_impl/shapes.py index dfe0f2421..f9b6d46c0 100644 --- a/cadquery/occ_impl/shapes.py +++ b/cadquery/occ_impl/shapes.py @@ -1208,17 +1208,20 @@ def makeNSidedSurface( return cls.cast(face).fix() @classmethod - def makePlane(cls, length, width, basePnt=(0, 0, 0), dir=(0, 0, 1)): + def makePlane(cls, length=None, width=None, basePnt=(0, 0, 0), dir=(0, 0, 1)): basePnt = Vector(basePnt) dir = Vector(dir) pln_geom = gp_Pln(basePnt.toPnt(), dir.toDir()) - return cls( - BRepBuilderAPI_MakeFace( + if length and width: + pln_shape = BRepBuilderAPI_MakeFace( pln_geom, -width * 0.5, width * 0.5, -length * 0.5, length * 0.5 ).Face() - ) + else: + pln_shape = BRepBuilderAPI_MakeFace(pln_geom).Face() + + return cls(pln_shape) @classmethod def makeRuledSurface(cls, edgeOrWire1, edgeOrWire2, dist=None): diff --git a/tests/test_cadquery.py b/tests/test_cadquery.py index c1c17bc93..628a35851 100644 --- a/tests/test_cadquery.py +++ b/tests/test_cadquery.py @@ -3395,3 +3395,18 @@ def testUnionCompound(self): obj = Workplane("XY").newObject(list_of_shapes).cut(shape_to_cut) assert obj.val().isValid() + + def testSection(self): + + box = Workplane("XY", origin=(1, 2, 3)).box(1, 1, 1) + + s1 = box.section() + s2 = box.section(0.5) + + self.assertAlmostEqual(s1.faces().val().Area(), 1) + self.assertAlmostEqual(s2.faces().val().Area(), 1) + + line = Workplane("XY").hLine(1) + + with self.assertRaises(ValueError): + line.section()