#2339 Read directly from raw data instead of using strings for IfcDiff output

This commit is contained in:
Dion Moult
2022-08-18 17:57:11 +10:00
parent 836a162d57
commit 97cf1da4ff
5 changed files with 75 additions and 39 deletions
@@ -33,7 +33,11 @@ class DiffData:
@classmethod @classmethod
def load(cls): 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 cls.is_loaded = True
@classmethod @classmethod
@@ -48,6 +52,24 @@ class DiffData:
cls.diff = json.load(file) cls.diff = json.load(file)
return cls.diff 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 @classmethod
def changes(cls): def changes(cls):
diff = cls.diff_json() diff = cls.diff_json()
@@ -56,4 +78,9 @@ class DiffData:
element = tool.Ifc.get_entity(bpy.context.active_object) element = tool.Ifc.get_entity(bpy.context.active_object)
if not element or not hasattr(element, "GlobalId"): if not element or not hasattr(element, "GlobalId"):
return {} 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
@@ -17,11 +17,11 @@
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>. # along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
import bpy import bpy
import json
import ifccsv import ifccsv
import ifcopenshell import ifcopenshell
import json import blenderbim.bim.handler
import blenderbim.tool as tool import blenderbim.tool as tool
from blenderbim.bim.ifc import IfcStore
class SelectDiffJsonFile(bpy.types.Operator): class SelectDiffJsonFile(bpy.types.Operator):
@@ -29,6 +29,7 @@ class SelectDiffJsonFile(bpy.types.Operator):
bl_label = "Select Diff JSON File" bl_label = "Select Diff JSON File"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
filepath: bpy.props.StringProperty(subtype="FILE_PATH") filepath: bpy.props.StringProperty(subtype="FILE_PATH")
filter_glob: bpy.props.StringProperty(default="*.json", options={"HIDDEN"})
def execute(self, context): def execute(self, context):
context.scene.DiffProperties.diff_json_file = self.filepath context.scene.DiffProperties.diff_json_file = self.filepath
@@ -72,9 +73,10 @@ class SelectDiffOldFile(bpy.types.Operator):
bl_label = "Select Diff Old File" bl_label = "Select Diff Old File"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
filepath: bpy.props.StringProperty(subtype="FILE_PATH") filepath: bpy.props.StringProperty(subtype="FILE_PATH")
filter_glob: bpy.props.StringProperty(default="*.ifc", options={"HIDDEN"})
def execute(self, context): def execute(self, context):
context.scene.DiffProperties.diff_old_file = self.filepath context.scene.DiffProperties.old_file = self.filepath
return {"FINISHED"} return {"FINISHED"}
def invoke(self, context, event): def invoke(self, context, event):
@@ -87,9 +89,10 @@ class SelectDiffNewFile(bpy.types.Operator):
bl_label = "Select Diff New File" bl_label = "Select Diff New File"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
filepath: bpy.props.StringProperty(subtype="FILE_PATH") filepath: bpy.props.StringProperty(subtype="FILE_PATH")
filter_glob: bpy.props.StringProperty(default="*.ifc", options={"HIDDEN"})
def execute(self, context): def execute(self, context):
context.scene.DiffProperties.diff_new_file = self.filepath context.scene.DiffProperties.new_file = self.filepath
return {"FINISHED"} return {"FINISHED"}
def invoke(self, context, event): def invoke(self, context, event):
@@ -113,14 +116,14 @@ class ExecuteIfcDiff(bpy.types.Operator):
import ifcdiff import ifcdiff
ifc_diff = ifcdiff.IfcDiff( ifc_diff = ifcdiff.IfcDiff(
context.scene.DiffProperties.diff_old_file, context.scene.DiffProperties.old_file,
context.scene.DiffProperties.diff_new_file, context.scene.DiffProperties.new_file,
self.filepath, self.filepath,
[r.relationship for r in context.scene.DiffProperties.diff_relationships], [r.relationship for r in context.scene.DiffProperties.diff_relationships],
context.scene.DiffProperties.diff_filter_elements, context.scene.DiffProperties.diff_filter_elements,
) )
diff = ifc_diff.diff() ifc_diff.diff()
ifc_diff.export() ifc_diff.export()
context.scene.DiffProperties.diff_json_file = self.filepath context.scene.DiffProperties.diff_json_file = self.filepath
context.scene.DiffProperties.diff_result = diff blenderbim.bim.handler.refresh_ui_data()
return {"FINISHED"} return {"FINISHED"}
@@ -44,9 +44,8 @@ class Relationships(PropertyGroup):
class DiffProperties(PropertyGroup): class DiffProperties(PropertyGroup):
diff_json_file: StringProperty(default="", name="Diff JSON File", update=update_diff_json_file) diff_json_file: StringProperty(default="", name="JSON Output", update=update_diff_json_file)
diff_old_file: StringProperty(default="", name="Diff Old IFC File") old_file: StringProperty(default="", name="Old IFC File")
diff_new_file: StringProperty(default="", name="Diff New IFC File") new_file: StringProperty(default="", name="New IFC File")
diff_relationships: CollectionProperty(type=Relationships, name="Diff Relationships") diff_relationships: CollectionProperty(type=Relationships, name="Relationships")
diff_filter_elements: StringProperty(default="", name="Diff Filter") diff_filter_elements: StringProperty(default="", name="Filter")
diff_result: StringProperty(default="", name="Diff Result")
+27 -19
View File
@@ -40,28 +40,28 @@ class BIM_PT_diff(Panel):
layout.use_property_split = True layout.use_property_split = True
scene = context.scene scene = context.scene
bim_properties = scene.DiffProperties props = scene.DiffProperties
layout.label(text="IFC Diff Setup:") layout.label(text="IFC Diff Setup:")
row = layout.row(align=True) 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.operator("bim.select_diff_old_file", icon="FILE_FOLDER", text="")
row = layout.row(align=True) 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.operator("bim.select_diff_new_file", icon="FILE_FOLDER", text="")
row = layout.row(align=True) row = layout.row(align=True)
row.prop(bim_properties, "diff_relationships") row.prop(props, "diff_relationships")
row.context_pointer_set("bim_prop_group", bim_properties) row.context_pointer_set("bim_prop_group", props)
add = row.operator("bim.edit_blender_collection", icon="ADD", text="") add = row.operator("bim.edit_blender_collection", icon="ADD", text="")
add.option = "add" add.option = "add"
add.collection = "diff_relationships" 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 = 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=" ") row.prop(r, "relationship", text=" ")
remove = row.operator("bim.edit_blender_collection", icon="REMOVE", text="") remove = row.operator("bim.edit_blender_collection", icon="REMOVE", text="")
remove.option = "remove" remove.option = "remove"
@@ -69,26 +69,34 @@ class BIM_PT_diff(Panel):
remove.index = index remove.index = index
row = layout.row(align=True) 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.operator("bim.ifc_selector", icon="FILTER", text="")
row = layout.row() row = layout.row()
row.operator("bim.execute_ifc_diff") 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 = 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.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"]: if DiffData.data["diff_json"]:
row = layout.row() 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(): for key, value in DiffData.data["changes"].items():
row = layout.row() row = box.row()
row.label(text=key) if key == "Added":
row.label(text=value) icon = "ADD"
elif key == "Deleted":
icon = "X"
else:
icon = "GREASEPENCIL"
row.label(text=key, icon=icon)
-1
View File
@@ -121,7 +121,6 @@ class IfcDiff:
print(" - {} item(s) were changed either geometrically or with data".format(len(self.change_register.keys()))) 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)) print("# Diff finished in {:.2f} seconds".format(time.time() - start))
logging.disable(logging.NOTSET) logging.disable(logging.NOTSET)
return f"# Diff finished in {time.time() - start:.2f} seconds"
def export(self): def export(self):
with open(self.output_file, "w", encoding="utf-8") as diff_file: with open(self.output_file, "w", encoding="utf-8") as diff_file: