## 
## CreateBOM: A Macro for FreeCAD
##
## The goal of this macro is to generate a Bill of Materials (BOM) 
## from the active FreeCAD document.
##
# Build BOM from document objects
doc = FreeCAD.ActiveDocument
objects = doc.Objects
# variant: FreeCADGui.Selection.getSelection()

# Get spreadsheet with name BOM
boms = App.activeDocument().getObjectsByLabel("BOM")
filtered = list(filter(lambda obj: obj.TypeId == "Spreadsheet::Sheet", boms))
if len(filtered) > 0:
  bom = filtered[0]
else:
  bom = App.activeDocument().addObject('Spreadsheet::Sheet','BOM')

# clean and set titles
bom.clearAll()
bom.set("A1", "Name")
bom.set("B1", "Length (cm)")
bom.set("C1", "Width (cm)")
bom.set("D1", "Height (cm)")

# fill with objects
cell = 1
for obj in objects:
    # Extract dimensions of the object, if available
    length = getattr(obj, "Length", 0)
    width= getattr(obj, "Width", 0)
    height = getattr(obj, "Height", 0)

    # Sort dimensions in descending order
    values = sorted([length, width, height], reverse=True)
    length = values[0]
    width = values[1]
    height = values[2]

    # Skip objects without dimensions
    if (length == 0) and (width == 0) and (height == 0):
        continue

    # Write object details to the BOM spreadsheet
    cell = cell + 1
    bom.set("A" + str(cell), obj.Label)
    bom.set("B" + str(cell), str(length))
    bom.set("C" + str(cell), str(width))
    bom.set("D" + str(cell), str(height))

App.ActiveDocument.recompute()