From 97cf1da4ff43bf05c413d4fdd33bb4122859285b Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Thu, 18 Aug 2022 17:57:11 +1000 Subject: [PATCH] #2339 Read directly from raw data instead of using strings for IfcDiff output --- .../blenderbim/bim/module/diff/data.py | 31 ++++++++++- .../blenderbim/bim/module/diff/operator.py | 19 ++++--- .../blenderbim/bim/module/diff/prop.py | 11 ++-- .../blenderbim/bim/module/diff/ui.py | 52 +++++++++++-------- src/ifcdiff/ifcdiff.py | 1 - 5 files changed, 75 insertions(+), 39 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/diff/data.py b/src/blenderbim/blenderbim/bim/module/diff/data.py index 0d12d0bafc..8dfc47e615 100644 --- a/src/blenderbim/blenderbim/bim/module/diff/data.py +++ b/src/blenderbim/blenderbim/bim/module/diff/data.py @@ -33,7 +33,11 @@ class DiffData: @classmethod def load(cls): - cls.data = {"diff_json": cls.diff_json(), "changes": cls.changes()} + cls.data["diff_json"] = cls.diff_json() + cls.data["total_added"] = cls.total_added() + cls.data["total_deleted"] = cls.total_deleted() + cls.data["total_changed"] = cls.total_changed() + cls.data["changes"] = cls.changes() cls.is_loaded = True @classmethod @@ -48,6 +52,24 @@ class DiffData: cls.diff = json.load(file) return cls.diff + @classmethod + def total_added(cls): + diff = cls.diff_json() + if diff: + return len(diff["added"]) + + @classmethod + def total_deleted(cls): + diff = cls.diff_json() + if diff: + return len(diff["deleted"]) + + @classmethod + def total_changed(cls): + diff = cls.diff_json() + if diff: + return len(diff["changed"].keys()) + @classmethod def changes(cls): diff = cls.diff_json() @@ -56,4 +78,9 @@ class DiffData: element = tool.Ifc.get_entity(bpy.context.active_object) if not element or not hasattr(element, "GlobalId"): return {} - return {k.upper().replace("_", " "): str(v) for k, v in diff["changed"].get(element.GlobalId, {}).items()} + changes = {k.upper().replace("_", " "): str(v) for k, v in diff["changed"].get(element.GlobalId, {}).items()} + if element.GlobalId in diff["added"]: + changes["Added"] = True + elif element.GlobalId in diff["deleted"]: + changes["Deleted"] = True + return changes diff --git a/src/blenderbim/blenderbim/bim/module/diff/operator.py b/src/blenderbim/blenderbim/bim/module/diff/operator.py index 56307ef5e0..c6c2af3dcf 100644 --- a/src/blenderbim/blenderbim/bim/module/diff/operator.py +++ b/src/blenderbim/blenderbim/bim/module/diff/operator.py @@ -17,11 +17,11 @@ # along with BlenderBIM Add-on. If not, see . import bpy +import json import ifccsv import ifcopenshell -import json +import blenderbim.bim.handler import blenderbim.tool as tool -from blenderbim.bim.ifc import IfcStore class SelectDiffJsonFile(bpy.types.Operator): @@ -29,6 +29,7 @@ class SelectDiffJsonFile(bpy.types.Operator): bl_label = "Select Diff JSON File" bl_options = {"REGISTER", "UNDO"} filepath: bpy.props.StringProperty(subtype="FILE_PATH") + filter_glob: bpy.props.StringProperty(default="*.json", options={"HIDDEN"}) def execute(self, context): context.scene.DiffProperties.diff_json_file = self.filepath @@ -72,9 +73,10 @@ class SelectDiffOldFile(bpy.types.Operator): bl_label = "Select Diff Old File" bl_options = {"REGISTER", "UNDO"} filepath: bpy.props.StringProperty(subtype="FILE_PATH") + filter_glob: bpy.props.StringProperty(default="*.ifc", options={"HIDDEN"}) def execute(self, context): - context.scene.DiffProperties.diff_old_file = self.filepath + context.scene.DiffProperties.old_file = self.filepath return {"FINISHED"} def invoke(self, context, event): @@ -87,9 +89,10 @@ class SelectDiffNewFile(bpy.types.Operator): bl_label = "Select Diff New File" bl_options = {"REGISTER", "UNDO"} filepath: bpy.props.StringProperty(subtype="FILE_PATH") + filter_glob: bpy.props.StringProperty(default="*.ifc", options={"HIDDEN"}) def execute(self, context): - context.scene.DiffProperties.diff_new_file = self.filepath + context.scene.DiffProperties.new_file = self.filepath return {"FINISHED"} def invoke(self, context, event): @@ -113,14 +116,14 @@ class ExecuteIfcDiff(bpy.types.Operator): import ifcdiff ifc_diff = ifcdiff.IfcDiff( - context.scene.DiffProperties.diff_old_file, - context.scene.DiffProperties.diff_new_file, + context.scene.DiffProperties.old_file, + context.scene.DiffProperties.new_file, self.filepath, [r.relationship for r in context.scene.DiffProperties.diff_relationships], context.scene.DiffProperties.diff_filter_elements, ) - diff = ifc_diff.diff() + ifc_diff.diff() ifc_diff.export() context.scene.DiffProperties.diff_json_file = self.filepath - context.scene.DiffProperties.diff_result = diff + blenderbim.bim.handler.refresh_ui_data() return {"FINISHED"} diff --git a/src/blenderbim/blenderbim/bim/module/diff/prop.py b/src/blenderbim/blenderbim/bim/module/diff/prop.py index 9b04aa024f..fb1426416a 100644 --- a/src/blenderbim/blenderbim/bim/module/diff/prop.py +++ b/src/blenderbim/blenderbim/bim/module/diff/prop.py @@ -44,9 +44,8 @@ class Relationships(PropertyGroup): class DiffProperties(PropertyGroup): - diff_json_file: StringProperty(default="", name="Diff JSON File", update=update_diff_json_file) - diff_old_file: StringProperty(default="", name="Diff Old IFC File") - diff_new_file: StringProperty(default="", name="Diff New IFC File") - diff_relationships: CollectionProperty(type=Relationships, name="Diff Relationships") - diff_filter_elements: StringProperty(default="", name="Diff Filter") - diff_result: StringProperty(default="", name="Diff Result") + diff_json_file: StringProperty(default="", name="JSON Output", update=update_diff_json_file) + old_file: StringProperty(default="", name="Old IFC File") + new_file: StringProperty(default="", name="New IFC File") + diff_relationships: CollectionProperty(type=Relationships, name="Relationships") + diff_filter_elements: StringProperty(default="", name="Filter") diff --git a/src/blenderbim/blenderbim/bim/module/diff/ui.py b/src/blenderbim/blenderbim/bim/module/diff/ui.py index 9ff84125d9..520a26ae39 100644 --- a/src/blenderbim/blenderbim/bim/module/diff/ui.py +++ b/src/blenderbim/blenderbim/bim/module/diff/ui.py @@ -40,55 +40,63 @@ class BIM_PT_diff(Panel): layout.use_property_split = True scene = context.scene - bim_properties = scene.DiffProperties + props = scene.DiffProperties layout.label(text="IFC Diff Setup:") row = layout.row(align=True) - row.prop(bim_properties, "diff_old_file") + row.prop(props, "old_file") row.operator("bim.select_diff_old_file", icon="FILE_FOLDER", text="") row = layout.row(align=True) - row.prop(bim_properties, "diff_new_file") + row.prop(props, "new_file") row.operator("bim.select_diff_new_file", icon="FILE_FOLDER", text="") row = layout.row(align=True) - row.prop(bim_properties, "diff_relationships") - row.context_pointer_set("bim_prop_group", bim_properties) + row.prop(props, "diff_relationships") + row.context_pointer_set("bim_prop_group", props) add = row.operator("bim.edit_blender_collection", icon="ADD", text="") add.option = "add" add.collection = "diff_relationships" - - for index, r in enumerate(bim_properties.diff_relationships): + + for index, r in enumerate(props.diff_relationships): row = layout.row(align=True) - row.context_pointer_set("bim_prop_group", bim_properties) + row.context_pointer_set("bim_prop_group", props) row.prop(r, "relationship", text=" ") remove = row.operator("bim.edit_blender_collection", icon="REMOVE", text="") remove.option = "remove" remove.collection = "diff_relationships" remove.index = index - + row = layout.row(align=True) - row.prop(bim_properties, "diff_filter_elements") + row.prop(props, "diff_filter_elements") row.operator("bim.ifc_selector", icon="FILTER", text="") row = layout.row() row.operator("bim.execute_ifc_diff") - if bim_properties.diff_result: - row = layout.row() - row.alignment = "CENTER" - row.label(text=bim_properties.diff_result) - # TODO: show if there ifc diff operation is sucessful row = layout.row(align=True) - row.prop(bim_properties, "diff_json_file") + row.prop(props, "diff_json_file") row.operator("bim.select_diff_json_file", icon="FILE_FOLDER", text="") row.operator("bim.visualise_diff", icon="HIDE_OFF", text="") - - if DiffData.data["changes"]: + + if DiffData.data["diff_json"]: row = layout.row() - row.label(text="Diff Results:") + row.alignment = "CENTER" + row.label(text=f"{DiffData.data['total_added']} added") + row.label(text=f"{DiffData.data['total_deleted']} deleted") + row.label(text=f"{DiffData.data['total_changed']} changed") + + if DiffData.data["changes"]: + box = layout.box() + row = box.row() + row.label(text="Active Object Changes:") for key, value in DiffData.data["changes"].items(): - row = layout.row() - row.label(text=key) - row.label(text=value) + row = box.row() + if key == "Added": + icon = "ADD" + elif key == "Deleted": + icon = "X" + else: + icon = "GREASEPENCIL" + row.label(text=key, icon=icon) diff --git a/src/ifcdiff/ifcdiff.py b/src/ifcdiff/ifcdiff.py index 224cdaa161..6bd7260155 100755 --- a/src/ifcdiff/ifcdiff.py +++ b/src/ifcdiff/ifcdiff.py @@ -121,7 +121,6 @@ class IfcDiff: print(" - {} item(s) were changed either geometrically or with data".format(len(self.change_register.keys()))) print("# Diff finished in {:.2f} seconds".format(time.time() - start)) logging.disable(logging.NOTSET) - return f"# Diff finished in {time.time() - start:.2f} seconds" def export(self): with open(self.output_file, "w", encoding="utf-8") as diff_file: