From 9fb163cb643e2ec7ffa08fef6ffd5ae599757f9b Mon Sep 17 00:00:00 2001 From: gumyr Date: Tue, 5 Nov 2024 11:53:51 -0500 Subject: [PATCH] Adding Compound.first_level_shapes to extract objects --- src/build123d/topology.py | 28 ++++++++++++++++++++++++++++ tests/test_direct_api.py | 7 +++++++ 2 files changed, 35 insertions(+) diff --git a/src/build123d/topology.py b/src/build123d/topology.py index afe4f9d..ab0f600 100644 --- a/src/build123d/topology.py +++ b/src/build123d/topology.py @@ -4509,6 +4509,34 @@ class Compound(Mixin3D, Shape): return results + def first_level_shapes( + self, _shapes: list[TopoDS_Shape] = None + ) -> ShapeList[Shape]: + """first_level_shapes + + This method iterates through the immediate children of the compound and + collects all non-compound shapes (e.g., vertices, edges, faces, solids). + If a child shape is itself a compound, the method recursively explores it, + retrieving all first-level shapes within any nested compounds. + + Note: the _shapes parameter is not to be assigned by the user. + + Returns: + ShapeList[Shape]: Shapes contained within the Compound + """ + if _shapes is None: + _shapes = [] + iterator = TopoDS_Iterator() + iterator.Initialize(self.wrapped) + while iterator.More(): + child = Shape.cast(iterator.Value()) + if isinstance(child, Compound): + child.first_level_shapes(_shapes) + else: + _shapes.append(child) + iterator.Next() + return ShapeList(_shapes) + def unwrap(self, fully: bool = True) -> Union[Self, Shape]: """Strip unnecessary Compound wrappers diff --git a/tests/test_direct_api.py b/tests/test_direct_api.py index 6702b0f..1790861 100644 --- a/tests/test_direct_api.py +++ b/tests/test_direct_api.py @@ -875,6 +875,13 @@ class TestCompound(DirectApiTestCase): comp4 = comp3.unwrap(fully=True) self.assertTrue(isinstance(comp4, Face)) + def test_first_level_shapes(self): + base_shapes = Compound(children=PolarLocations(15, 20) * Box(4, 4, 4)) + fls = base_shapes.first_level_shapes() + self.assertTrue(isinstance(fls, ShapeList)) + self.assertEqual(len(fls), 20) + self.assertTrue(all(isinstance(s, Solid) for s in fls)) + class TestEdge(DirectApiTestCase): def test_close(self):