diff --git a/cadquery/cq.py b/cadquery/cq.py index 9753bac6c..5617d82c1 100644 --- a/cadquery/cq.py +++ b/cadquery/cq.py @@ -1080,7 +1080,9 @@ def translate(self, vec: VectorLike) -> "Workplane": ] ) - def shell(self, thickness: float) -> "Workplane": + def shell( + self, thickness: float, kind: Literal["arc", "intersection"] = "arc" + ) -> "Workplane": """ Remove the selected faces to create a shell of the specified thickness. @@ -1088,6 +1090,7 @@ def shell(self, thickness: float) -> "Workplane": :param thickness: a positive float, representing the thickness of the desired shell. Negative values shell inwards, positive values shell outwards. + :param kind: kind of joints, intersetion or arc (default: arc). :raises: ValueError if the current stack contains objects that are not faces of a solid further up in the chain. :returns: a CQ object with the resulting shelled solid selected. @@ -1120,7 +1123,7 @@ def shell(self, thickness: float) -> "Workplane": faces = [f for f in self.objects if isinstance(f, Face)] - s = solidRef.shell(faces, thickness) + s = solidRef.shell(faces, thickness, kind=kind) return self.newObject([s]) def fillet(self, radius: float) -> "Workplane": diff --git a/cadquery/occ_impl/shapes.py b/cadquery/occ_impl/shapes.py index 61cab4501..679c416f7 100644 --- a/cadquery/occ_impl/shapes.py +++ b/cadquery/occ_impl/shapes.py @@ -1665,6 +1665,7 @@ def shell( faceList: Iterable[Face], thickness: float, tolerance: float = 0.0001, + kind: Literal["arc", "intersection"] = "arc", ) -> Any: """ make a shelled solid of given by removing the list of faces @@ -1675,6 +1676,11 @@ def shell( :return: a shelled solid """ + kind_dict = { + "arc": GeomAbs_JoinType.GeomAbs_Arc, + "intersection": GeomAbs_JoinType.GeomAbs_Intersection, + } + occ_faces_list = TopTools_ListOfShape() if faceList: @@ -1682,7 +1688,12 @@ def shell( occ_faces_list.Append(f.wrapped) shell_builder = BRepOffsetAPI_MakeThickSolid( - self.wrapped, occ_faces_list, thickness, tolerance, Intersection=True + self.wrapped, + occ_faces_list, + thickness, + tolerance, + Intersection=True, + Join=kind_dict[kind], ) shell_builder.Build() @@ -1690,7 +1701,12 @@ def shell( else: # if no faces provided a watertight solid will be constructed shell_builder = BRepOffsetAPI_MakeThickSolid( - self.wrapped, occ_faces_list, thickness, tolerance, Intersection=True + self.wrapped, + occ_faces_list, + thickness, + tolerance, + Intersection=True, + Join=kind_dict[kind], ) shell_builder.Build() diff --git a/tests/test_cadquery.py b/tests/test_cadquery.py index 028e2fd66..295a764f3 100644 --- a/tests/test_cadquery.py +++ b/tests/test_cadquery.py @@ -1828,9 +1828,21 @@ def testSimpleShell(self): """ Create s simple box """ - s = Workplane("XY").box(2, 2, 2).faces("+Z").shell(0.05) - self.saveModel(s) - self.assertEqual(23, s.faces().size()) + s1 = Workplane("XY").box(2, 2, 2).faces("+Z").shell(0.05) + self.saveModel(s1) + self.assertEqual(23, s1.faces().size()) + + s2 = ( + Workplane() + .ellipse(4, 2) + .extrude(4) + .faces(">Z") + .shell(+2, kind="intersection") + ) + self.assertEqual(5, s2.faces().size()) + + s3 = Workplane().ellipse(4, 2).extrude(4).faces(">Z").shell(+2, kind="arc") + self.assertEqual(6, s3.faces().size()) def testClosedShell(self): """