Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions cadquery/assembly.py
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,33 @@ 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:
"""
Expand Down
15 changes: 12 additions & 3 deletions cadquery/occ_impl/shapes.py
Original file line number Diff line number Diff line change
Expand Up @@ -6553,14 +6553,23 @@ 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,
)
Expand Down
18 changes: 18 additions & 0 deletions tests/test_assembly.py
Original file line number Diff line number Diff line change
Expand Up @@ -2603,3 +2603,21 @@ def test_name_geometries(tmpdir):
assert len([l for l in lines if "top_face" in l]) == 2
assert len([l for l in lines if "plane_" in l]) == 2
assert len([l for l in lines if "seg_" in l]) == 3


def test_toBOM():

assy = cq.Assembly(name="root")
assy.add(box(1, 1, 1), name="part1")

subassy = cq.Assembly(name="sub")
subassy.add(box(2, 2, 2), name="part2")
assy.add(subassy, name="sub")

bom = assy.toBOM()

assert len(bom) == 4
assert bom[0] == {"name": "root", "level": 0, "has_shape": False}
assert bom[1] == {"name": "part1", "level": 1, "has_shape": True}
assert bom[2] == {"name": "sub", "level": 1, "has_shape": False}
assert bom[3] == {"name": "part2", "level": 2, "has_shape": True}