From f06f4fa805d0a2ef1250abf6eb2d3f8bd7609152 Mon Sep 17 00:00:00 2001 From: gumyr Date: Tue, 6 Feb 2024 10:33:20 -0500 Subject: [PATCH] Allowing Shell to take a single Face Issue #531 --- src/build123d/topology.py | 37 ++++++++++++++++++++++++++++++++++--- tests/test_direct_api.py | 11 +++++++++-- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/build123d/topology.py b/src/build123d/topology.py index 1ba58cb..b3523dc 100644 --- a/src/build123d/topology.py +++ b/src/build123d/topology.py @@ -95,6 +95,7 @@ from OCP.BRepBuilderAPI import ( BRepBuilderAPI_MakeEdge, BRepBuilderAPI_MakeFace, BRepBuilderAPI_MakePolygon, + BRepBuilderAPI_MakeShell, BRepBuilderAPI_MakeSolid, BRepBuilderAPI_MakeVertex, BRepBuilderAPI_MakeWire, @@ -6076,6 +6077,23 @@ class Shell(Shape): parent (Compound, optional): assembly parent. Defaults to None. """ + @overload + def __init__( + self, + face: Face, + label: str = "", + color: Color = None, + parent: Compound = None, + ): + """Build a shell from a single Face + + Args: + face (Face): Face to convert to Shell + label (str, optional): Defaults to ''. + color (Color, optional): Defaults to None. + parent (Compound, optional): assembly parent. Defaults to None. + """ + @overload def __init__( self, @@ -6094,29 +6112,42 @@ class Shell(Shape): """ def __init__(self, *args, **kwargs): - faces, obj, label, color, parent = (None,) * 5 + face, faces, obj, label, color, parent = (None,) * 6 if args: l_a = len(args) if isinstance(args[0], TopoDS_Shape): obj, label, color, parent = args[:4] + (None,) * (4 - l_a) + elif isinstance(args[0], Face): + face, label, color, parent = args[:4] + (None,) * (4 - l_a) elif isinstance(args[0], Iterable): faces, label, color, parent = args[:4] + (None,) * (4 - l_a) unknown_args = ", ".join( - set(kwargs.keys()).difference(["faces", "obj", "label", "color", "parent"]) + set(kwargs.keys()).difference( + ["face", "faces", "obj", "label", "color", "parent"] + ) ) if unknown_args: raise ValueError(f"Unexpected argument(s) {unknown_args}") obj = kwargs.get("obj", obj) + face = kwargs.get("face", face) faces = kwargs.get("faces", faces) label = kwargs.get("label", label) color = kwargs.get("color", color) parent = kwargs.get("parent", parent) if faces: - obj = Shell._make_shell(faces) + if len(faces) == 1: + face = faces[0] + else: + obj = Shell._make_shell(faces) + if face: + builder = BRepBuilderAPI_MakeShell( + BRepAdaptor_Surface(face.wrapped).Surface().Surface() + ) + obj = builder.Shape() super().__init__( obj=obj, diff --git a/tests/test_direct_api.py b/tests/test_direct_api.py index 824d387..7799933 100644 --- a/tests/test_direct_api.py +++ b/tests/test_direct_api.py @@ -46,7 +46,7 @@ from build123d.build_enums import ( from build123d.build_part import BuildPart from build123d.operations_part import extrude from build123d.operations_sketch import make_face -from build123d.operations_generic import fillet, add +from build123d.operations_generic import fillet, add, sweep from build123d.objects_part import Box, Cylinder from build123d.objects_curve import Polyline from build123d.build_sketch import BuildSketch @@ -3087,6 +3087,13 @@ class TestShells(DirectApiTestCase): with self.assertRaises(ValueError): Shell(bob="fred") + x_section = Rot(90) * Spline((0, -5), (-3, -2), (-2, 0), (-3, 2), (0, 5)) + surface = sweep(x_section, Circle(5).wire()) + single_face = Shell(surface.face()) + self.assertTrue(single_face.is_valid()) + single_face = Shell(surface.faces()) + self.assertTrue(single_face.is_valid()) + class TestSolid(DirectApiTestCase): def test_make_solid(self): @@ -3675,7 +3682,7 @@ class TestWire(DirectApiTestCase): self.assertTupleAlmostEquals(w6.color.to_tuple(), (1.0, 0.0, 0.0, 1.0), 5) w7 = Wire(w6) self.assertTrue(w7.is_valid()) - c0 = Polyline((0,0),(1,0),(1,1)) + c0 = Polyline((0, 0), (1, 0), (1, 1)) w8 = Wire(c0) self.assertTrue(w8.is_valid()) with self.assertRaises(ValueError):