diff --git a/cadquery/assembly.py b/cadquery/assembly.py index fdf98dd73..0e79f3f55 100644 --- a/cadquery/assembly.py +++ b/cadquery/assembly.py @@ -627,6 +627,37 @@ def export( return self + def toBOM( + self, + indent: int = 0, + _result: Optional[List[Dict[str, Any]]] = None, + ) -> List[Dict[str, Any]]: + """ + Generate a Bill of Materials (BOM) for this assembly. + + Returns a flat list of dictionaries, one per component, with fields: + - name: component name + - level: nesting depth (0 = root) + - has_shape: whether the component has geometry + + :param indent: current nesting level (used internally for recursion) + :return: list of BOM line items + """ + + if _result is None: + _result = [] + + _result.append({ + "name": self.name, + "level": indent, + "has_shape": self.obj is not None, + }) + + for child in self.children: + child.toBOM(indent=indent + 1, _result=_result) + + return _result + @classmethod def importStep(cls, path: str, unit: UnitLiterals = "MM") -> Self: """ diff --git a/cadquery/occ_impl/shapes.py b/cadquery/occ_impl/shapes.py index 7d3c665a9..72c5cf5db 100644 --- a/cadquery/occ_impl/shapes.py +++ b/cadquery/occ_impl/shapes.py @@ -6553,14 +6553,21 @@ def plane() -> Face: return _shape(BRepBuilderAPI_MakeFace(pln_geom, -INF, INF, -INF, INF).Face(), Face) -def box(w: float, l: float, h: float) -> Solid: +def box(length: float, width: float, height: float) -> Solid: """ - Construct a solid box. + Construct a solid box centered on the XY plane. + + :param length: box size along the X axis + :param width: box size along the Y axis + :param height: box size along the Z axis """ return _shape( BRepPrimAPI_MakeBox( - gp_Ax2(Vector(-w / 2, -l / 2, 0).toPnt(), Vector(0, 0, 1).toDir()), w, l, h + gp_Ax2(Vector(-length / 2, -width / 2, 0).toPnt(), Vector(0, 0, 1).toDir()), + length, + width, + height, ).Shape(), Solid, )