|
|
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") |
|
|
|
|
|
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: |
|
|
|
|
|
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) |
|
|
|
|
|
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) |
|
|
|
|
|
elements = ifc.by_type("IfcElement") |
|
|
|
|
|
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) |
|
|
|
|
|
|
|
|
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, |
|
|
) |
|
|
|
|
|
|
|
|
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] |
|
|
) |
|
|
|
|
|
|
|
|
extract_btn.click( |
|
|
lambda: [gr.File(visible=True), gr.File(visible=True)], |
|
|
outputs=[csv_download, excel_download] |
|
|
) |
|
|
|
|
|
demo.launch() |
|
|
|