# # --- from CHATGPT (WORKING) 20240707 ----- # import ifcopenshell import blenderbim.tool as tool import pandas as pd from ifcopenshell.util import selector from ifcopenshell.util import cost from ifcopenshell.api import run # Load the IFC model model = tool.Ifc.get() # BoQ = model.by_type('IfcCostSchedule')[0] # Example of fetching the first IfcCostSchedule, adjust as needed BoQlst = list(selector.filter_elements(model, "IfcCostSchedule, Name = Staircase, PredefinedType = BUDGET")) BoQ = BoQlst[0] # Fetch the root items in the BoQ rootitems = cost.get_root_cost_items(BoQ) # Function to recursively assign index values and collect data def assign_index_and_collect_data(items, parent_index=''): result = [] for i, item in enumerate(items): # Calculate the index for the current item if parent_index == '': current_index = f"{i+1}" # For root items, start from '1', '2', etc. else: current_index = f"{parent_index}.{i+1}" # For child items, append to the parent index # Calculate the total quantity using ifcopenshell.util.cost.get_total_quantity if ifcopenshell.util.cost.get_total_quantity(item): try: quantity = ifcopenshell.util.cost.get_total_quantity(item) except Exception as e: quantity = f"Error: {e}" else: quantity = 0 # Calculate the cost value if available if item.CostValues: try: cost_value = ifcopenshell.util.cost.calculate_applied_value(item, item.CostValues[0]) except Exception as e: cost_value = f"Error: {e}" else: cost_value = 0 run("cost.edit_cost_item", model, cost_item = item, attributes={"Identification": current_index}) # Collect the item's data item_data = { 'Identification': item.Identification if item.Identification is not None else 0, 'Name': item.Name if item.Name else "Unnamed", 'Quantity': round(quantity,2), 'CostValue': round(cost_value,2) } result.append(item_data) # Recursively process nested cost items nested_items = cost.get_nested_cost_items(item) if nested_items: result.extend(assign_index_and_collect_data(nested_items, current_index)) return result # Start the process with the root items and an empty parent index indexed_cost_items = assign_index_and_collect_data(rootitems) # Create the DataFrame from the list of dictionaries df = pd.DataFrame(indexed_cost_items).fillna(0) # Display the DataFrame (optional) print('\n',df,'\n')