mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-09 21:53:40 +00:00
#2339 Read directly from raw data instead of using strings for IfcDiff output
This commit is contained in:
@@ -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")
|
|
||||||
|
|||||||
@@ -40,55 +40,63 @@ 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"
|
||||||
remove.collection = "diff_relationships"
|
remove.collection = "diff_relationships"
|
||||||
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)
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
Reference in New Issue
Block a user