File size: 4,232 Bytes
9f59d45 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
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()
|