IFC3 / app.py
TIRTH143's picture
Upload app.py with huggingface_hub
9f59d45 verified
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()