import gradio as gr import ifcopenshell import pandas as pd from tempfile import NamedTemporaryFile import os def extract_properties(ifc_file_path, element_class): try: model = ifcopenshell.open(ifc_file_path) results = [] elements = model.by_type("IfcElement") # Get unique type names element_types = sorted(list(set(elem.is_a() for elem in elements))) classes_to_check = [element_class] if element_class != "" else sorted(list(set(obj.is_a() for obj in element_types))) for class_name in classes_to_check: elements = model.by_type(class_name) for element in elements: # Get all properties properties = {} for definition in element.IsDefinedBy: if definition.is_a("IfcRelDefinesByProperties"): prop_set = definition.RelatingPropertyDefinition if prop_set.is_a("IfcPropertySet"): for prop in prop_set.HasProperties: properties[f"{prop_set.Name}.{prop.Name}"] = prop.NominalValue.wrappedValue if prop.NominalValue else None row = { "GlobalId": element.GlobalId, "Type": element.is_a(), "Name": element.Name, **properties } results.append(row) if not results: return pd.DataFrame({"Message": [f"No {element_class if element_class != '' else ''} elements found"]}), None, None df = pd.DataFrame(results) # Create temporary files for downloads with NamedTemporaryFile(delete=False, suffix='.csv') as tmp_csv: df.to_csv(tmp_csv.name, index=False) csv_path = tmp_csv.name with NamedTemporaryFile(delete=False, suffix='.xlsx') as tmp_excel: df.to_excel(tmp_excel.name, index=False) excel_path = tmp_excel.name return df, csv_path, excel_path except Exception as e: return pd.DataFrame({"Error": [f"Processing failed: {str(e)}"]}), None, None def extract_ifc_types(ifc_file): """Extract all IFC types from uploaded file""" if not ifc_file: return [] try: ifc = ifcopenshell.open(ifc_file.name) # Get all elements that are IfcElement or its subtypes elements = ifc.by_type("IfcElement") # Get unique type names element_types = sorted(list(set(elem.is_a() for elem in elements))) return element_types except: return [] def update_dropdown(ifc_file): """Update dropdown options when file is uploaded""" choices = extract_ifc_types(ifc_file) return gr.Dropdown(choices=choices, value="", interactive=True) # Gradio Interface with gr.Blocks(title="IFC Property Extractor") as demo: gr.Markdown("## 🛠️ IFC Property Extractor") with gr.Row(): ifc_input = gr.File( label="1. Upload IFC File", file_types=[".ifc"], type="filepath" ) with gr.Row(): with gr.Column(): class_filter = gr.Dropdown( [""], value="", label="2. Filter by Class", interactive=False ) extract_btn = gr.Button("Extract Properties", variant="primary") with gr.Column(): csv_download = gr.File(label="Download CSV", visible=False) excel_download = gr.File(label="Download Excel", visible=False) output_table = gr.Dataframe( label="Extracted Properties", interactive=True, wrap=False, ) # Update dropdown when file is uploaded ifc_input.change( fn=update_dropdown, inputs=ifc_input, outputs=[class_filter] ) extract_btn.click( fn=extract_properties, inputs=[ifc_input, class_filter], outputs=[output_table, csv_download, excel_download] ) # Show download buttons only when files are available extract_btn.click( lambda: [gr.File(visible=True), gr.File(visible=True)], outputs=[csv_download, excel_download] ) demo.launch()