bernd wrote: ↑Tue Mar 31, 2020 10:45 am
I made progress in updateing my rebar code. I will hopfully make it public in the next few days.
That's Great.
I also created a function to create BOM spreadsheet.
Code: Select all
import FreeCAD
COLUMN_HEADERS = [
"Member",
"Mark",
"No. Of Rebars",
"Diameter in mm",
"Length in m/piece",
"Total Length in m",
]
COLUMN_DIA_HEADERS = [8, 10, 12, 16, 20]
def addSheetHeaders(spreadsheet):
# Format cells
spreadsheet.mergeCells("A1:A2")
spreadsheet.mergeCells("B1:B2")
spreadsheet.mergeCells("C1:C2")
spreadsheet.mergeCells("D1:D2")
spreadsheet.mergeCells("E1:E2")
spreadsheet.mergeCells(
"F1:" + chr(ord("F") + len(COLUMN_DIA_HEADERS) - 1) + "1"
)
spreadsheet.setAlignment("F1:J2", "vcenter", "keep")
spreadsheet.setAlignment("F1:J2", "center", "keep")
# Add column headers
spreadsheet.set("A1", COLUMN_HEADERS[0])
spreadsheet.set("B1", COLUMN_HEADERS[1])
spreadsheet.set("C1", COLUMN_HEADERS[2])
spreadsheet.set("D1", COLUMN_HEADERS[3])
spreadsheet.set("E1", COLUMN_HEADERS[4])
spreadsheet.set("F1", COLUMN_HEADERS[5])
for i, dia in enumerate(COLUMN_DIA_HEADERS):
spreadsheet.set(chr(ord("F") + i) + "2", "#" + str(dia))
def makeBillOfMaterial():
# Create new spreadsheet object
bill_of_material = FreeCAD.ActiveDocument.addObject(
"Spreadsheet::Sheet", "RebarBillOfMaterial"
)
# Add column headers
addSheetHeaders(bill_of_material)
# Get Part::FeaturePython objects list
objects_list = FreeCAD.ActiveDocument.findObjects("Part::FeaturePython")
# Create rebars list and dictionary with membersas key with corresponding
# rebars list as value
rebars_list = []
members_rebars_dict = {}
for item in objects_list:
if hasattr(item, "IfcType"):
if item.IfcType == "Reinforcing Bar":
rebars_list.append(item)
base_obj = item.Base
if not base_obj:
member = "Unknown"
else:
member = base_obj.Support[0][0].Label
if member not in members_rebars_dict:
members_rebars_dict[member] = []
else:
members_rebars_dict[member].append(item)
# Add data to spreadsheet
row = 3
for member in members_rebars_dict:
bill_of_material.set("A" + str(row), member)
for rebars in members_rebars_dict[member]:
bill_of_material.set("C" + str(row), str(rebars.Amount))
bill_of_material.set("D" + str(row), str(rebars.Diameter))
bill_of_material.set("E" + str(row), str(rebars.Length))
bill_of_material.set(
chr(ord("F") + COLUMN_DIA_HEADERS.index(rebars.Diameter.Value))
+ str(row),
str(rebars.TotalLength),
)
row += 1
row += 1
bill_of_material.setDisplayUnit("E3:E" + str(row), "m")
bill_of_material.setDisplayUnit(
"F3:" + chr(ord("F") + len(COLUMN_DIA_HEADERS) - 1) + str(row), "m"
)
FreeCAD.ActiveDocument.recompute()
print("WIP")
How to use:
1. Open model for which we need to calculate BOM for reinforcement.
2. Copy and paste above code into freecad python console.
3. Type `makeBillOfMaterial()` in freecad python console.
Sample model can be found in attachment and here is screenshot of its BOM spreadsheet.
- SampleBOMOutput.png (259.96 KiB) Viewed 2153 times
BOM contains columns which are present in
BOM file shared by @bernd or in
image shared by @hardeep
Please review and give your suggestions.
The length present in BOM is automatically calculated by below function which is already present in ArchRebar.py file of base rebar implementation. Now, do we need to calculate length of rebar shape as @bernd suggested
here that it may be tricky task to calculate length of rebar shape?
Code: Select all
def getLengthOfRebar(rebar):
""" getLengthOfRebar(RebarObject): Calculates the length of the rebar."""
base = rebar.Base
# When rebar is derived from DWire
if hasattr(base, "Length"):
return base.Length
# When rebar is derived from Sketch
elif base.isDerivedFrom("Sketcher::SketchObject"):
length = 0
for geo in base.Geometry:
length += geo.length()
return length
else:
FreeCAD.Console.PrintError("Cannot calculate rebar length from its base object\n")
return None
Thanks,