See #4054. Diffing now allows partial loading of changed elements to make it easier to visualise without loading and linking two models.

This commit is contained in:
Dion Moult
2023-11-29 15:57:59 +11:00
parent e8bd272189
commit b80ca3c167
4 changed files with 127 additions and 13 deletions
@@ -18,7 +18,7 @@
import bpy
import json
import ifccsv
import logging
import ifcopenshell
import blenderbim.bim.handler
import blenderbim.tool as tool
@@ -53,6 +53,16 @@ class VisualiseDiff(bpy.types.Operator):
for obj in context.visible_objects:
obj.color = (1.0, 1.0, 1.0, 1.0)
if "IfcDiff Deleted Elements" in obj.users_collection[0].name:
obj.color = (1.0, 0.0, 0.0, 1.0)
continue
elif "IfcDiff Added Elements" in obj.users_collection[0].name:
obj.color = (0.0, 1.0, 0.0, 1.0)
continue
elif "IfcDiff Changed Elements" in obj.users_collection[0].name:
obj.color = (0.0, 0.0, 0.7, 1.0)
continue
if not obj.BIMObjectProperties.ifc_definition_id:
continue
@@ -135,14 +145,84 @@ class ExecuteIfcDiff(bpy.types.Operator):
def execute(self, context):
import ifcdiff
old = ifcopenshell.open(context.scene.DiffProperties.old_file)
new = ifcopenshell.open(context.scene.DiffProperties.new_file)
relationships = [r.relationship for r in context.scene.DiffProperties.diff_relationships]
query = context.scene.DiffProperties.diff_filter_elements
self.props = context.scene.DiffProperties
if tool.Ifc.get():
if self.props.active_file == "NONE":
old = ifcopenshell.open(self.props.old_file)
new = ifcopenshell.open(self.props.new_file)
elif self.props.active_file == "NEW":
old = ifcopenshell.open(self.props.old_file)
new = tool.Ifc.get()
elif self.props.active_file == "OLD":
old = tool.Ifc.get()
new = ifcopenshell.open(self.props.new_file)
else:
old = ifcopenshell.open(self.props.old_file)
new = ifcopenshell.open(self.props.new_file)
relationships = [r.relationship for r in self.props.diff_relationships]
query = self.props.diff_filter_elements
ifc_diff = ifcdiff.IfcDiff(old, new, relationships=relationships, filter_elements=query)
ifc_diff.diff()
ifc_diff.export(self.filepath)
context.scene.DiffProperties.diff_json_file = self.filepath
self.props.diff_json_file = self.filepath
self.load_changed_elements(ifc_diff)
blenderbim.bim.handler.refresh_ui_data()
return {"FINISHED"}
def load_changed_elements(self, ifc_diff):
if not tool.Ifc.get() or self.props.active_file == "NONE" or not self.props.should_load_changed_elements:
return
active_ifc = tool.Ifc.get()
logger = logging.getLogger("ImportIFC")
ifc_import_settings = blenderbim.bim.import_ifc.IfcImportSettings.factory(bpy.context, None, logger)
ifc_importer = blenderbim.bim.import_ifc.IfcImporter(ifc_import_settings)
if self.props.active_file == "NEW":
tool.Ifc.set(ifc_diff.old)
ifc_importer.file = ifc_diff.old
ifc_importer.process_context_filter()
ifc_importer.create_materials()
ifc_importer.create_styles()
elements = {ifc_diff.old.by_guid(guid) for guid in ifc_diff.deleted_elements}
ifc_importer.create_generic_elements(elements)
self.place_objs_in_collection(ifc_importer.added_data.values(), "IfcDiff Deleted Elements")
ifc_importer.added_data = {}
elements = {ifc_diff.old.by_guid(guid) for guid in ifc_diff.change_register.keys()}
ifc_importer.create_generic_elements(elements)
self.place_objs_in_collection(ifc_importer.added_data.values(), "IfcDiff Changed Elements")
elif self.props.active_file == "OLD":
tool.Ifc.set(ifc_diff.new)
ifc_importer.file = ifc_diff.new
ifc_importer.process_context_filter()
ifc_importer.create_materials()
ifc_importer.create_styles()
elements = {ifc_diff.new.by_guid(guid) for guid in ifc_diff.added_elements}
ifc_importer.create_generic_elements(elements)
self.place_objs_in_collection(ifc_importer.added_data.values(), "IfcDiff Added Elements")
ifc_importer.added_data = {}
elements = {ifc_diff.new.by_guid(guid) for guid in ifc_diff.change_register.keys()}
ifc_importer.create_generic_elements(elements)
self.place_objs_in_collection(ifc_importer.added_data.values(), "IfcDiff Changed Elements")
tool.Ifc.set(active_ifc)
def place_objs_in_collection(self, objs, name):
collection = bpy.data.collections.get(name)
if not collection:
collection = bpy.data.collections.new(name)
bpy.context.scene.collection.children.link(collection)
for obj in objs:
if isinstance(obj, bpy.types.Object):
collection.objects.link(obj)
@@ -49,3 +49,13 @@ class DiffProperties(PropertyGroup):
new_file: StringProperty(default="", name="New IFC File")
diff_relationships: CollectionProperty(type=Relationships, name="Relationships")
diff_filter_elements: StringProperty(default="", name="Filter")
should_load_changed_elements: BoolProperty(name="Load Changed Elements", default=True)
active_file: EnumProperty(
items=[
("NONE", "N/A", ""),
("OLD", "Old", ""),
("NEW", "New", ""),
],
name="Active File",
default="NEW",
)
@@ -44,13 +44,38 @@ class BIM_PT_diff(Panel):
layout.label(text="IFC Diff Setup:")
row = layout.row(align=True)
row.prop(props, "old_file")
row.operator("bim.select_diff_old_file", icon="FILE_FOLDER", text="")
if tool.Ifc.get():
row = layout.row()
row.prop(props, "active_file")
row = layout.row(align=True)
row.prop(props, "new_file")
row.operator("bim.select_diff_new_file", icon="FILE_FOLDER", text="")
if props.active_file == "NONE":
row = layout.row(align=True)
row.prop(props, "old_file")
row.operator("bim.select_diff_old_file", icon="FILE_FOLDER", text="")
row = layout.row(align=True)
row.prop(props, "new_file")
row.operator("bim.select_diff_new_file", icon="FILE_FOLDER", text="")
elif props.active_file == "NEW":
row = layout.row(align=True)
row.prop(props, "old_file")
row.operator("bim.select_diff_old_file", icon="FILE_FOLDER", text="")
elif props.active_file == "OLD":
row = layout.row(align=True)
row.prop(props, "new_file")
row.operator("bim.select_diff_new_file", icon="FILE_FOLDER", text="")
if props.active_file != "NONE":
row = layout.row()
row.prop(props, "should_load_changed_elements")
else:
row = layout.row(align=True)
row.prop(props, "old_file")
row.operator("bim.select_diff_old_file", icon="FILE_FOLDER", text="")
row = layout.row(align=True)
row.prop(props, "new_file")
row.operator("bim.select_diff_new_file", icon="FILE_FOLDER", text="")
row = layout.row(align=True)
row.prop(props, "diff_relationships")
@@ -35,7 +35,6 @@ import blenderbim.tool as tool
import blenderbim.bim.handler
from mathutils import Vector, Matrix
from time import time
from blenderbim.bim import import_ifc
from blenderbim.bim.ifc import IfcStore