From 7c2c946b2feb36103f848b9b8668765ecbb2c18c Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Fri, 5 Aug 2022 10:59:07 +1000 Subject: [PATCH] Fix bug in diff visualisation for non-rooted entities. Refactor diff UI to data class. --- .../blenderbim/bim/module/diff/data.py | 59 +++++++++++++++++++ .../blenderbim/bim/module/diff/operator.py | 12 ++-- .../blenderbim/bim/module/diff/prop.py | 11 +++- .../blenderbim/bim/module/diff/ui.py | 27 ++++----- 4 files changed, 85 insertions(+), 24 deletions(-) create mode 100644 src/blenderbim/blenderbim/bim/module/diff/data.py diff --git a/src/blenderbim/blenderbim/bim/module/diff/data.py b/src/blenderbim/blenderbim/bim/module/diff/data.py new file mode 100644 index 0000000000..0d12d0bafc --- /dev/null +++ b/src/blenderbim/blenderbim/bim/module/diff/data.py @@ -0,0 +1,59 @@ +# BlenderBIM Add-on - OpenBIM Blender Add-on +# Copyright (C) 2022 Dion Moult +# +# This file is part of BlenderBIM Add-on. +# +# BlenderBIM Add-on is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# BlenderBIM Add-on is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with BlenderBIM Add-on. If not, see . + +import bpy +import json +import blenderbim.tool as tool + + +def refresh(): + DiffData.is_loaded = False + + +class DiffData: + data = {} + is_loaded = False + diff_json_file = None + diff = None + + @classmethod + def load(cls): + cls.data = {"diff_json": cls.diff_json(), "changes": cls.changes()} + cls.is_loaded = True + + @classmethod + def diff_json(cls): + props = bpy.context.scene.DiffProperties + if not props.diff_json_file: + cls.diff = None + return + if props.diff_json_file != cls.diff_json_file: + cls.diff_json_file = props.diff_json_file + with open(props.diff_json_file, "r") as file: + cls.diff = json.load(file) + return cls.diff + + @classmethod + def changes(cls): + diff = cls.diff_json() + if not diff: + return {} + 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()} diff --git a/src/blenderbim/blenderbim/bim/module/diff/operator.py b/src/blenderbim/blenderbim/bim/module/diff/operator.py index e0c7553905..56307ef5e0 100644 --- a/src/blenderbim/blenderbim/bim/module/diff/operator.py +++ b/src/blenderbim/blenderbim/bim/module/diff/operator.py @@ -49,17 +49,19 @@ class VisualiseDiff(bpy.types.Operator): with open(context.scene.DiffProperties.diff_json_file, "r") as file: diff = json.load(file) for obj in context.visible_objects: - obj.color = (1.0, 1.0, 1.0, 0.2) + obj.color = (1.0, 1.0, 1.0, 1.0) element = tool.Ifc.get_entity(obj) if not element: continue - global_id = element.GlobalId + global_id = getattr(element, "GlobalId", None) + if not global_id: + continue if global_id in diff["deleted"]: - obj.color = (1.0, 0.0, 0.0, 0.2) + obj.color = (1.0, 0.0, 0.0, 1.0) elif global_id in diff["added"]: - obj.color = (0.0, 1.0, 0.0, 0.2) + obj.color = (0.0, 1.0, 0.0, 1.0) elif global_id in diff["changed"]: - obj.color = (0.0, 0.0, 1.0, 0.2) + obj.color = (0.0, 0.0, 1.0, 1.0) area = next(area for area in context.screen.areas if area.type == "VIEW_3D") area.spaces[0].shading.color_type = "OBJECT" return {"FINISHED"} diff --git a/src/blenderbim/blenderbim/bim/module/diff/prop.py b/src/blenderbim/blenderbim/bim/module/diff/prop.py index 4dde19cce3..9b04aa024f 100644 --- a/src/blenderbim/blenderbim/bim/module/diff/prop.py +++ b/src/blenderbim/blenderbim/bim/module/diff/prop.py @@ -18,6 +18,7 @@ import bpy from blenderbim.bim.prop import StrProperty +from blenderbim.bim.module.diff.data import DiffData from bpy.types import PropertyGroup from bpy.props import ( PointerProperty, @@ -30,14 +31,20 @@ from bpy.props import ( CollectionProperty, ) + +def update_diff_json_file(self, context): + DiffData.data["diff_json"] = DiffData.diff_json() + + class Relationships(PropertyGroup): relationship: EnumProperty( name="Relationship", - items=[(r,r,r) for r in ["type", "property", "container", "aggregate", "classification"]], + items=[(r, r.capitalize(), r) for r in ["type", "property", "container", "aggregate", "classification"]], ) + class DiffProperties(PropertyGroup): - diff_json_file: StringProperty(default="", name="Diff JSON File") + 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 --git a/src/blenderbim/blenderbim/bim/module/diff/ui.py b/src/blenderbim/blenderbim/bim/module/diff/ui.py index dc92d76a6a..9ff84125d9 100644 --- a/src/blenderbim/blenderbim/bim/module/diff/ui.py +++ b/src/blenderbim/blenderbim/bim/module/diff/ui.py @@ -18,6 +18,7 @@ from bpy.types import Panel from blenderbim.bim.ifc import IfcStore +from blenderbim.bim.module.diff.data import DiffData import blenderbim.tool as tool import json @@ -32,6 +33,9 @@ class BIM_PT_diff(Panel): bl_parent_id = "BIM_PT_quality_control" def draw(self, context): + if not DiffData.is_loaded: + DiffData.load() + layout = self.layout layout.use_property_split = True @@ -81,21 +85,10 @@ class BIM_PT_diff(Panel): row.operator("bim.select_diff_json_file", icon="FILE_FOLDER", text="") row.operator("bim.visualise_diff", icon="HIDE_OFF", text="") - - # Show diff results # - if bim_properties.diff_json_file: - with open(context.scene.DiffProperties.diff_json_file, "r") as file: - results = json.load(file) - if results: + if DiffData.data["changes"]: + row = layout.row() + row.label(text="Diff Results:") + for key, value in DiffData.data["changes"].items(): row = layout.row() - row = layout.row() - row.label(text="Diff Results:") - for g in results["changed"]: - obj = tool.Ifc.get_entity(context.active_object) - if obj.GlobalId == g: - for k,v in results["changed"][g].items(): - row = layout.row() - row.alignment = "LEFT" - row.label(text=f"{str(k).upper()}: {str(v)}") - - \ No newline at end of file + row.label(text=key) + row.label(text=value)