Header data previews for IFCZIP are now supported as well.

This commit is contained in:
Dion Moult
2022-01-17 18:21:20 +11:00
parent 52ea69bcec
commit 8b06aa9e0b
2 changed files with 49 additions and 39 deletions
+41 -31
View File
@@ -19,6 +19,7 @@
import bpy import bpy
import json import json
import math import math
import zipfile
import ifcopenshell import ifcopenshell
import ifcopenshell.util.attribute import ifcopenshell.util.attribute
from mathutils import geometry from mathutils import geometry
@@ -99,35 +100,44 @@ def export_attributes(props, callback=None):
return attributes return attributes
class IFCHeaderSpecs: class IfcHeaderExtractor:
def __init__(self, filepath: str): def __init__(self, filepath: str):
# According to https://www.steptools.com/stds/step/IS_final_p21e3.html#clause-8 self.filepath = filepath
self.description = ""
self.implementation_level = "" def extract(self):
self.name = "" extension = self.filepath.split(".")[-1]
self.time_stamp = "" if extension.lower() == "ifc":
self.author = "" with open(self.filepath) as ifc_file:
self.organization = "" return self.extract_ifc_spf(ifc_file)
self.preprocessor_version = "" elif extension.lower() == "ifczip":
self.originating_system = "" return self.extract_ifc_zip()
self.authorization = ""
self.schema_name = "" def extract_ifc_spf(self, ifc_file):
with open(filepath) as ifc_file: # https://www.steptools.com/stds/step/IS_final_p21e3.html#clause-8
max_lines_to_parse = 50 data = {}
for _ in range(max_lines_to_parse): max_lines_to_parse = 50
line = next(ifc_file) for _ in range(max_lines_to_parse):
if line.startswith("FILE_DESCRIPTION"): line = next(ifc_file)
for i, part in enumerate(line.split("'")): if isinstance(line, bytes):
if i == 1: line = line.decode("utf-8")
self.description = part print(line)
elif i == 3: if line.startswith("FILE_DESCRIPTION"):
self.implementation_level = part for i, part in enumerate(line.split("'")):
elif line.startswith("FILE_NAME"): if i == 1:
for i, part in enumerate(line.split("'")): data["description"] = part
if i == 1: elif i == 3:
self.name = part data["implementation_level"] = part
elif i == 3: elif line.startswith("FILE_NAME"):
self.time_stamp = part for i, part in enumerate(line.split("'")):
elif line.startswith("FILE_SCHEMA"): if i == 1:
self.schema_name = line.split("'")[1] data["name"] = part
break elif i == 3:
data["time_stamp"] = part
elif line.startswith("FILE_SCHEMA"):
data["schema_name"] = line.split("'")[1]
break
return data
def extract_ifc_zip(self):
archive = zipfile.ZipFile(self.filepath, "r")
return self.extract_ifc_spf(archive.open(archive.filelist[0]))
+8 -8
View File
@@ -22,7 +22,7 @@ from pathlib import Path
from . import ifc from . import ifc
from bpy.types import Panel from bpy.types import Panel
from bpy.props import StringProperty, IntProperty, BoolProperty from bpy.props import StringProperty, IntProperty, BoolProperty
from blenderbim.bim.helper import IFCHeaderSpecs from blenderbim.bim.helper import IfcHeaderExtractor
import blenderbim.tool as tool import blenderbim.tool as tool
@@ -41,15 +41,15 @@ class IFCFileSelector:
if self.is_existing_ifc_file(filepath): if self.is_existing_ifc_file(filepath):
box = self.layout.box() box = self.layout.box()
box.label(text="IFC Header Specifications", icon="INFO") box.label(text="IFC Header Specifications", icon="INFO")
ifc_specs = IFCHeaderSpecs(filepath) header_data = IfcHeaderExtractor(filepath).extract()
for attr_name, attr_value in ifc_specs.__dict__.items(): for key, value in header_data.items():
if attr_value != "": if value != "":
split = box.split() split = box.split()
split.label(text=attr_name.title().replace("_", " ")) split.label(text=key.title().replace("_", " "))
split.label(text=str(attr_value)) split.label(text=str(value))
if ( if (
attr_name.lower() == "schema_name" key.lower() == "schema_name"
and str(attr_value).lower() == "ifc2x3" and str(value).lower() == "ifc2x3"
and filepath[-4:].lower() == ".ifc" and filepath[-4:].lower() == ".ifc"
): ):
row = box.row() row = box.row()