Experimental reimplementation of reloading an updated IFC

This commit is contained in:
Dion Moult
2022-10-24 13:36:50 +11:00
parent a908fa62ba
commit 248dab936d
2 changed files with 76 additions and 6 deletions
+8 -2
View File
@@ -252,13 +252,19 @@ class IfcStore:
if not obj: if not obj:
return return
if obj.BIMObjectProperties.ifc_definition_id: if obj.BIMObjectProperties.ifc_definition_id:
element = IfcStore.get_file().by_id(obj.BIMObjectProperties.ifc_definition_id) try:
element = IfcStore.get_file().by_id(obj.BIMObjectProperties.ifc_definition_id)
except:
return
data = {"id": element.id(), "obj": obj.name} data = {"id": element.id(), "obj": obj.name}
if hasattr(element, "GlobalId"): if hasattr(element, "GlobalId"):
data["guid"] = element.GlobalId data["guid"] = element.GlobalId
IfcStore.commit_link_element(data) IfcStore.commit_link_element(data)
if hasattr(obj, "BIMMaterialProperties") and obj.BIMMaterialProperties.ifc_style_id: if hasattr(obj, "BIMMaterialProperties") and obj.BIMMaterialProperties.ifc_style_id:
element = IfcStore.get_file().by_id(obj.BIMMaterialProperties.ifc_style_id) try:
element = IfcStore.get_file().by_id(obj.BIMMaterialProperties.ifc_style_id)
except:
return
data = {"id": element.id(), "obj": obj.name} data = {"id": element.id(), "obj": obj.name}
IfcStore.commit_link_element(data) IfcStore.commit_link_element(data)
+68 -4
View File
@@ -19,11 +19,14 @@
import os import os
import bpy import bpy
import json import json
import time
import logging
import webbrowser import webbrowser
import ifcopenshell import ifcopenshell
import blenderbim.bim.handler import blenderbim.bim.handler
import blenderbim.tool as tool import blenderbim.tool as tool
from . import schema from . import schema
from blenderbim.bim import import_ifc
from blenderbim.bim.ifc import IfcStore from blenderbim.bim.ifc import IfcStore
from blenderbim.bim.prop import StrProperty from blenderbim.bim.prop import StrProperty
from blenderbim.bim.ui import IFCFileSelector from blenderbim.bim.ui import IFCFileSelector
@@ -397,16 +400,77 @@ class BIM_OT_remove_section_plane(bpy.types.Operator):
bpy.ops.object.delete({"selected_objects": [context.active_object]}) bpy.ops.object.delete({"selected_objects": [context.active_object]})
class ReloadIfcFile(bpy.types.Operator): class ReloadIfcFile(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.reload_ifc_file" bl_idname = "bim.reload_ifc_file"
bl_label = "Reload IFC File" bl_label = "Reload IFC File"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
bl_description = "Reload the same IFC file" bl_description = "Reload an updated IFC file"
filepath: bpy.props.StringProperty(subtype="FILE_PATH")
filter_glob: bpy.props.StringProperty(default="*.ifc", options={"HIDDEN"})
def execute(self, context): def _execute(self, context):
# TODO: reimplement. See #1222. import ifcdiff
old = tool.Ifc.get()
new = ifcopenshell.open(self.filepath)
ifc_diff = ifcdiff.IfcDiff(old, new, relationships=[])
ifc_diff.diff()
changed_elements = set([k for k, v in ifc_diff.change_register.items() if "geometry_changed" in v])
for global_id in ifc_diff.deleted_elements | changed_elements:
element = tool.Ifc.get().by_guid(global_id)
obj = tool.Ifc.get_object(element)
if obj:
bpy.data.objects.remove(obj)
# STEP IDs may change, but we assume the GlobalID to be constant
obj_map = {}
for obj in bpy.data.objects:
element = tool.Ifc.get_entity(obj)
if element and hasattr(element, "GlobalId"):
obj_map[obj.name] = element.GlobalId
delta_elements = [new.by_guid(global_id) for global_id in ifc_diff.added_elements | changed_elements]
tool.Ifc.set(new)
for obj in bpy.data.objects:
global_id = obj_map.get(obj.name)
if global_id:
try:
tool.Ifc.link(new.by_guid(global_id), obj)
except:
# Still prototyping, so things like types definitely won't work
print("Could not relink", obj)
start = time.time()
logger = logging.getLogger("ImportIFC")
path_log = os.path.join(context.scene.BIMProperties.data_dir, "process.log")
if not os.access(context.scene.BIMProperties.data_dir, os.W_OK):
path_log = os.path.join(tempfile.mkdtemp(), "process.log")
logging.basicConfig(
filename=path_log,
filemode="a",
level=logging.DEBUG,
)
settings = import_ifc.IfcImportSettings.factory(context, self.filepath, logger)
settings.has_filter = True
settings.should_filter_spatial_elements = False
settings.elements = delta_elements
settings.logger.info("Starting import")
ifc_importer = import_ifc.IfcImporter(settings)
ifc_importer.execute()
settings.logger.info("Import finished in {:.2f} seconds".format(time.time() - start))
print("Import finished in {:.2f} seconds".format(time.time() - start))
context.scene.BIMProperties.ifc_file = self.filepath
return {"FINISHED"} return {"FINISHED"}
def invoke(self, context, event):
context.window_manager.fileselect_add(self)
return {"RUNNING_MODAL"}
class AddIfcFile(bpy.types.Operator): class AddIfcFile(bpy.types.Operator):
bl_idname = "bim.add_ifc_file" bl_idname = "bim.add_ifc_file"