diff --git a/src/blenderbim/blenderbim/bim/helper.py b/src/blenderbim/blenderbim/bim/helper.py index 3d9ac797bd..37807c275c 100644 --- a/src/blenderbim/blenderbim/bim/helper.py +++ b/src/blenderbim/blenderbim/bim/helper.py @@ -19,6 +19,7 @@ import bpy import json import math +import zipfile import ifcopenshell import ifcopenshell.util.attribute from mathutils import geometry @@ -99,35 +100,44 @@ def export_attributes(props, callback=None): return attributes -class IFCHeaderSpecs: +class IfcHeaderExtractor: def __init__(self, filepath: str): - # According to https://www.steptools.com/stds/step/IS_final_p21e3.html#clause-8 - self.description = "" - self.implementation_level = "" - self.name = "" - self.time_stamp = "" - self.author = "" - self.organization = "" - self.preprocessor_version = "" - self.originating_system = "" - self.authorization = "" - self.schema_name = "" - with open(filepath) as ifc_file: - max_lines_to_parse = 50 - for _ in range(max_lines_to_parse): - line = next(ifc_file) - if line.startswith("FILE_DESCRIPTION"): - for i, part in enumerate(line.split("'")): - if i == 1: - self.description = part - elif i == 3: - self.implementation_level = part - elif line.startswith("FILE_NAME"): - for i, part in enumerate(line.split("'")): - if i == 1: - self.name = part - elif i == 3: - self.time_stamp = part - elif line.startswith("FILE_SCHEMA"): - self.schema_name = line.split("'")[1] - break + self.filepath = filepath + + def extract(self): + extension = self.filepath.split(".")[-1] + if extension.lower() == "ifc": + with open(self.filepath) as ifc_file: + return self.extract_ifc_spf(ifc_file) + elif extension.lower() == "ifczip": + return self.extract_ifc_zip() + + def extract_ifc_spf(self, ifc_file): + # https://www.steptools.com/stds/step/IS_final_p21e3.html#clause-8 + data = {} + max_lines_to_parse = 50 + for _ in range(max_lines_to_parse): + line = next(ifc_file) + if isinstance(line, bytes): + line = line.decode("utf-8") + print(line) + if line.startswith("FILE_DESCRIPTION"): + for i, part in enumerate(line.split("'")): + if i == 1: + data["description"] = part + elif i == 3: + data["implementation_level"] = part + elif line.startswith("FILE_NAME"): + for i, part in enumerate(line.split("'")): + if i == 1: + data["name"] = part + 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])) diff --git a/src/blenderbim/blenderbim/bim/ui.py b/src/blenderbim/blenderbim/bim/ui.py index 955bc2b117..cc7f900ba8 100644 --- a/src/blenderbim/blenderbim/bim/ui.py +++ b/src/blenderbim/blenderbim/bim/ui.py @@ -22,7 +22,7 @@ from pathlib import Path from . import ifc from bpy.types import Panel from bpy.props import StringProperty, IntProperty, BoolProperty -from blenderbim.bim.helper import IFCHeaderSpecs +from blenderbim.bim.helper import IfcHeaderExtractor import blenderbim.tool as tool @@ -41,15 +41,15 @@ class IFCFileSelector: if self.is_existing_ifc_file(filepath): box = self.layout.box() box.label(text="IFC Header Specifications", icon="INFO") - ifc_specs = IFCHeaderSpecs(filepath) - for attr_name, attr_value in ifc_specs.__dict__.items(): - if attr_value != "": + header_data = IfcHeaderExtractor(filepath).extract() + for key, value in header_data.items(): + if value != "": split = box.split() - split.label(text=attr_name.title().replace("_", " ")) - split.label(text=str(attr_value)) + split.label(text=key.title().replace("_", " ")) + split.label(text=str(value)) if ( - attr_name.lower() == "schema_name" - and str(attr_value).lower() == "ifc2x3" + key.lower() == "schema_name" + and str(value).lower() == "ifc2x3" and filepath[-4:].lower() == ".ifc" ): row = box.row()