Fix bug in diff visualisation for non-rooted entities. Refactor diff UI to data class.

This commit is contained in:
Dion Moult
2022-08-05 10:59:07 +10:00
parent 5b34e08c37
commit 7c2c946b2f
4 changed files with 85 additions and 24 deletions
@@ -0,0 +1,59 @@
# BlenderBIM Add-on - OpenBIM Blender Add-on
# Copyright (C) 2022 Dion Moult <dion@thinkmoult.com>
#
# 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 <http://www.gnu.org/licenses/>.
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()}
@@ -49,17 +49,19 @@ class VisualiseDiff(bpy.types.Operator):
with open(context.scene.DiffProperties.diff_json_file, "r") as file: with open(context.scene.DiffProperties.diff_json_file, "r") as file:
diff = json.load(file) diff = json.load(file)
for obj in context.visible_objects: 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) element = tool.Ifc.get_entity(obj)
if not element: if not element:
continue continue
global_id = element.GlobalId global_id = getattr(element, "GlobalId", None)
if not global_id:
continue
if global_id in diff["deleted"]: 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"]: 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"]: 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 = next(area for area in context.screen.areas if area.type == "VIEW_3D")
area.spaces[0].shading.color_type = "OBJECT" area.spaces[0].shading.color_type = "OBJECT"
return {"FINISHED"} return {"FINISHED"}
@@ -18,6 +18,7 @@
import bpy import bpy
from blenderbim.bim.prop import StrProperty from blenderbim.bim.prop import StrProperty
from blenderbim.bim.module.diff.data import DiffData
from bpy.types import PropertyGroup from bpy.types import PropertyGroup
from bpy.props import ( from bpy.props import (
PointerProperty, PointerProperty,
@@ -30,14 +31,20 @@ from bpy.props import (
CollectionProperty, CollectionProperty,
) )
def update_diff_json_file(self, context):
DiffData.data["diff_json"] = DiffData.diff_json()
class Relationships(PropertyGroup): class Relationships(PropertyGroup):
relationship: EnumProperty( relationship: EnumProperty(
name="Relationship", 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): 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_old_file: StringProperty(default="", name="Diff Old IFC File")
diff_new_file: StringProperty(default="", name="Diff New IFC File") diff_new_file: StringProperty(default="", name="Diff New IFC File")
diff_relationships: CollectionProperty(type=Relationships, name="Diff Relationships") diff_relationships: CollectionProperty(type=Relationships, name="Diff Relationships")
+10 -17
View File
@@ -18,6 +18,7 @@
from bpy.types import Panel from bpy.types import Panel
from blenderbim.bim.ifc import IfcStore from blenderbim.bim.ifc import IfcStore
from blenderbim.bim.module.diff.data import DiffData
import blenderbim.tool as tool import blenderbim.tool as tool
import json import json
@@ -32,6 +33,9 @@ class BIM_PT_diff(Panel):
bl_parent_id = "BIM_PT_quality_control" bl_parent_id = "BIM_PT_quality_control"
def draw(self, context): def draw(self, context):
if not DiffData.is_loaded:
DiffData.load()
layout = self.layout layout = self.layout
layout.use_property_split = True 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.select_diff_json_file", icon="FILE_FOLDER", text="")
row.operator("bim.visualise_diff", icon="HIDE_OFF", text="") row.operator("bim.visualise_diff", icon="HIDE_OFF", text="")
if DiffData.data["changes"]:
# Show diff results # row = layout.row()
if bim_properties.diff_json_file: row.label(text="Diff Results:")
with open(context.scene.DiffProperties.diff_json_file, "r") as file: for key, value in DiffData.data["changes"].items():
results = json.load(file)
if results:
row = layout.row() row = layout.row()
row = layout.row() row.label(text=key)
row.label(text="Diff Results:") row.label(text=value)
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)}")