diff --git a/src/ifcblenderexport/blenderbim/bim/__init__.py b/src/ifcblenderexport/blenderbim/bim/__init__.py index 6437767d8f..eb28ff5d73 100644 --- a/src/ifcblenderexport/blenderbim/bim/__init__.py +++ b/src/ifcblenderexport/blenderbim/bim/__init__.py @@ -17,6 +17,7 @@ if bpy is not None: "context": None, "covetool": None, "csv": None, + "diff": None, "bimtester": None, "debug": None, "geometry": None, @@ -40,9 +41,6 @@ if bpy is not None: operator.SelectClass, operator.SelectType, operator.OpenUri, - operator.SelectDiffJsonFile, - operator.SelectDiffNewFile, - operator.SelectDiffOldFile, operator.SelectDataDir, operator.SelectSchemaDir, operator.SelectIfcFile, @@ -106,8 +104,6 @@ if bpy is not None: operator.OpenView, operator.OpenViewCamera, operator.ActivateView, - operator.ExecuteIfcDiff, - operator.VisualiseDiff, operator.ExportClashSets, operator.ImportClashSets, operator.AddClashSet, @@ -228,7 +224,6 @@ if bpy is not None: ui.BIM_PT_ifcclash, ui.BIM_PT_library, ui.BIM_PT_presentation_layers, - ui.BIM_PT_diff, ui.BIM_PT_patch, ui.BIM_PT_mvd, ui.BIM_PT_presentation_layer_data, diff --git a/src/ifcblenderexport/blenderbim/bim/module/bimtester/ui.py b/src/ifcblenderexport/blenderbim/bim/module/bimtester/ui.py index 9ee1bb0689..1e6ffddf79 100644 --- a/src/ifcblenderexport/blenderbim/bim/module/bimtester/ui.py +++ b/src/ifcblenderexport/blenderbim/bim/module/bimtester/ui.py @@ -32,7 +32,7 @@ class BIM_PT_qa(Panel): else: return - if context.scene.BimTesterProperties.features_file != '': # To handle the error when no .feature file exists in the folder + if str(context.scene.BimTesterProperties.features_file) != '': # To handle the error when no .feature file exists in the folder row = layout.row() row.operator("bim.execute_bim_tester") diff --git a/src/ifcblenderexport/blenderbim/bim/module/diff/__init__.py b/src/ifcblenderexport/blenderbim/bim/module/diff/__init__.py new file mode 100644 index 0000000000..6c551c11ce --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/diff/__init__.py @@ -0,0 +1,22 @@ +import bpy +from . import ui, prop, operator + +classes = ( + operator.SelectDiffJsonFile, + operator.VisualiseDiff, + operator.SelectDiffOldFile, + operator.SelectDiffNewFile, + operator.ExecuteIfcDiff, + prop.DiffProperties, + ui.BIM_PT_diff, +) + + + +def register(): + bpy.types.Scene.DiffProperties = bpy.props.PointerProperty(type=prop.DiffProperties) + + +def unregister(): + del bpy.types.Scene.DiffProperties + diff --git a/src/ifcblenderexport/blenderbim/bim/module/diff/operator.py b/src/ifcblenderexport/blenderbim/bim/module/diff/operator.py new file mode 100644 index 0000000000..7b34cc4bbf --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/diff/operator.py @@ -0,0 +1,101 @@ +import bpy +import ifccsv +import ifcopenshell +import json +from blenderbim.bim.ifc import IfcStore + + + +class SelectDiffJsonFile(bpy.types.Operator): + bl_idname = "bim.select_diff_json_file" + bl_label = "Select Diff JSON File" + filepath: bpy.props.StringProperty(subtype="FILE_PATH") + + def execute(self, context): + bpy.context.scene.DiffProperties.diff_json_file = self.filepath + return {"FINISHED"} + + def invoke(self, context, event): + context.window_manager.fileselect_add(self) + return {"RUNNING_MODAL"} + + +class VisualiseDiff(bpy.types.Operator): + bl_idname = "bim.visualise_diff" + bl_label = "Visualise Diff" + + def execute(self, context): + #ifc_file = IfcStore.get_file() # In case we get from Store + ifc_file = ifcopenshell.open(context.scene.DiffProperties.diff_new_file) # for Now refer to the new file + with open(bpy.context.scene.DiffProperties.diff_json_file, "r") as file: + diff = json.load(file) + for obj in bpy.context.visible_objects: + obj.color = (1.0, 1.0, 1.0, 0.2) + global_id = ifc_file.by_id(obj.BIMObjectProperties.ifc_definition_id).GlobalId + #global_id = obj.BIMObjectProperties.attributes.get("GlobalId") + if not global_id: + continue + if global_id.string_value in diff["deleted"]: + obj.color = (1.0, 0.0, 0.0, 0.2) + elif global_id.string_value in diff["added"]: + obj.color = (0.0, 1.0, 0.0, 0.2) + elif global_id.string_value in diff["changed"]: + obj.color = (0.0, 0.0, 1.0, 0.2) + area = next(area for area in bpy.context.screen.areas if area.type == "VIEW_3D") + area.spaces[0].shading.color_type = "OBJECT" + return {"FINISHED"} + + +class SelectDiffOldFile(bpy.types.Operator): + bl_idname = "bim.select_diff_old_file" + bl_label = "Select Diff Old File" + filepath: bpy.props.StringProperty(subtype="FILE_PATH") + + def execute(self, context): + bpy.context.scene.DiffProperties.diff_old_file = self.filepath + return {"FINISHED"} + + def invoke(self, context, event): + context.window_manager.fileselect_add(self) + return {"RUNNING_MODAL"} + + +class SelectDiffNewFile(bpy.types.Operator): + bl_idname = "bim.select_diff_new_file" + bl_label = "Select Diff New File" + filepath: bpy.props.StringProperty(subtype="FILE_PATH") + + def execute(self, context): + bpy.context.scene.DiffProperties.diff_new_file = self.filepath + return {"FINISHED"} + + def invoke(self, context, event): + context.window_manager.fileselect_add(self) + return {"RUNNING_MODAL"} + + +class ExecuteIfcDiff(bpy.types.Operator): + bl_idname = "bim.execute_ifc_diff" + bl_label = "Execute IFC Diff" + filename_ext = ".json" + filepath: bpy.props.StringProperty(subtype="FILE_PATH") + + def invoke(self, context, event): + self.filepath = bpy.path.ensure_ext(bpy.data.filepath, ".json") + WindowManager = context.window_manager + WindowManager.fileselect_add(self) + return {"RUNNING_MODAL"} + + def execute(self, context): + import ifcdiff + + ifc_diff = ifcdiff.IfcDiff( + bpy.context.scene.DiffProperties.diff_old_file, + bpy.context.scene.DiffProperties.diff_new_file, + self.filepath, + bpy.context.scene.DiffProperties.diff_relationships.split(), + ) + ifc_diff.diff() + ifc_diff.export() + bpy.context.scene.DiffProperties.diff_json_file = self.filepath + return {"FINISHED"} diff --git a/src/ifcblenderexport/blenderbim/bim/module/diff/prop.py b/src/ifcblenderexport/blenderbim/bim/module/diff/prop.py new file mode 100644 index 0000000000..a0d05ab85d --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/diff/prop.py @@ -0,0 +1,21 @@ +import bpy +from blenderbim.bim.prop import StrProperty +from bpy.types import PropertyGroup +from bpy.props import ( + PointerProperty, + StringProperty, + EnumProperty, + BoolProperty, + IntProperty, + FloatProperty, + FloatVectorProperty, + CollectionProperty, +) + + +class DiffProperties(PropertyGroup): + diff_json_file: StringProperty(default="", name="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: StringProperty(default="", name="Diff Relationships") + diff --git a/src/ifcblenderexport/blenderbim/bim/module/diff/ui.py b/src/ifcblenderexport/blenderbim/bim/module/diff/ui.py new file mode 100644 index 0000000000..692b79d37e --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/diff/ui.py @@ -0,0 +1,40 @@ +from bpy.types import Panel +from blenderbim.bim.ifc import IfcStore + + +class BIM_PT_diff(Panel): + bl_label = "IFC Diff" + bl_idname = "BIM_PT_diff" + bl_options = {"DEFAULT_CLOSED"} + bl_space_type = "PROPERTIES" + bl_region_type = "WINDOW" + bl_context = "scene" + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + scene = context.scene + bim_properties = scene.DiffProperties + + layout.label(text="IFC Diff Setup:") + + row = layout.row(align=True) + row.prop(bim_properties, "diff_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.operator("bim.select_diff_new_file", icon="FILE_FOLDER", text="") + + row = layout.row(align=True) + row.prop(bim_properties, "diff_relationships") + + row = layout.row() + row.operator("bim.execute_ifc_diff") + + # TODO: show if there ifc diff operation is sucessful + row = layout.row(align=True) + row.prop(bim_properties, "diff_json_file") + row.operator("bim.select_diff_json_file", icon="FILE_FOLDER", text="") + row.operator("bim.visualise_diff", icon="HIDE_OFF", text="") diff --git a/src/ifcblenderexport/blenderbim/bim/operator.py b/src/ifcblenderexport/blenderbim/bim/operator.py index d320e282d2..dd95539cdf 100644 --- a/src/ifcblenderexport/blenderbim/bim/operator.py +++ b/src/ifcblenderexport/blenderbim/bim/operator.py @@ -748,98 +748,6 @@ class ExecuteIfcPatch(bpy.types.Operator): return {"FINISHED"} -class SelectDiffJsonFile(bpy.types.Operator): - bl_idname = "bim.select_diff_json_file" - bl_label = "Select Diff JSON File" - filepath: bpy.props.StringProperty(subtype="FILE_PATH") - - def execute(self, context): - bpy.context.scene.BIMProperties.diff_json_file = self.filepath - return {"FINISHED"} - - def invoke(self, context, event): - context.window_manager.fileselect_add(self) - return {"RUNNING_MODAL"} - - -class VisualiseDiff(bpy.types.Operator): - bl_idname = "bim.visualise_diff" - bl_label = "Visualise Diff" - - def execute(self, context): - with open(bpy.context.scene.BIMProperties.diff_json_file, "r") as file: - diff = json.load(file) - for obj in bpy.context.visible_objects: - obj.color = (1.0, 1.0, 1.0, 0.2) - global_id = obj.BIMObjectProperties.attributes.get("GlobalId") - if not global_id: - continue - if global_id.string_value in diff["deleted"]: - obj.color = (1.0, 0.0, 0.0, 0.2) - elif global_id.string_value in diff["added"]: - obj.color = (0.0, 1.0, 0.0, 0.2) - elif global_id.string_value in diff["changed"]: - obj.color = (0.0, 0.0, 1.0, 0.2) - area = next(area for area in bpy.context.screen.areas if area.type == "VIEW_3D") - area.spaces[0].shading.color_type = "OBJECT" - return {"FINISHED"} - - -class SelectDiffOldFile(bpy.types.Operator): - bl_idname = "bim.select_diff_old_file" - bl_label = "Select Diff Old File" - filepath: bpy.props.StringProperty(subtype="FILE_PATH") - - def execute(self, context): - bpy.context.scene.BIMProperties.diff_old_file = self.filepath - return {"FINISHED"} - - def invoke(self, context, event): - context.window_manager.fileselect_add(self) - return {"RUNNING_MODAL"} - - -class SelectDiffNewFile(bpy.types.Operator): - bl_idname = "bim.select_diff_new_file" - bl_label = "Select Diff New File" - filepath: bpy.props.StringProperty(subtype="FILE_PATH") - - def execute(self, context): - bpy.context.scene.BIMProperties.diff_new_file = self.filepath - return {"FINISHED"} - - def invoke(self, context, event): - context.window_manager.fileselect_add(self) - return {"RUNNING_MODAL"} - - -class ExecuteIfcDiff(bpy.types.Operator): - bl_idname = "bim.execute_ifc_diff" - bl_label = "Execute IFC Diff" - filename_ext = ".json" - filepath: bpy.props.StringProperty(subtype="FILE_PATH") - - def invoke(self, context, event): - self.filepath = bpy.path.ensure_ext(bpy.data.filepath, ".json") - WindowManager = context.window_manager - WindowManager.fileselect_add(self) - return {"RUNNING_MODAL"} - - def execute(self, context): - import ifcdiff - - ifc_diff = ifcdiff.IfcDiff( - bpy.context.scene.BIMProperties.diff_old_file, - bpy.context.scene.BIMProperties.diff_new_file, - self.filepath, - bpy.context.scene.BIMProperties.diff_relationships.split(), - ) - ifc_diff.diff() - ifc_diff.export() - bpy.context.scene.BIMProperties.diff_json_file = self.filepath - return {"FINISHED"} - - class ExportClashSets(bpy.types.Operator): bl_idname = "bim.export_clash_sets" bl_label = "Export Clash Sets" diff --git a/src/ifcblenderexport/blenderbim/bim/prop.py b/src/ifcblenderexport/blenderbim/bim/prop.py index 21fcdec6e6..bf67b2e656 100644 --- a/src/ifcblenderexport/blenderbim/bim/prop.py +++ b/src/ifcblenderexport/blenderbim/bim/prop.py @@ -1042,10 +1042,6 @@ class BIMProperties(PropertyGroup): search_pset_name: StringProperty(name="Search Pset Name") search_prop_name: StringProperty(name="Search Prop Name") search_pset_value: StringProperty(name="Search Pset Value") - diff_json_file: StringProperty(default="", name="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: StringProperty(default="", name="Diff Relationships") classification: EnumProperty(items=getClassifications, name="Classification", update=refreshReferences) active_classification_name: StringProperty(name="Active Classification Name") classifications: CollectionProperty(name="Classifications", type=Classification) diff --git a/src/ifcblenderexport/blenderbim/bim/ui.py b/src/ifcblenderexport/blenderbim/bim/ui.py index 1d45f5cc42..4ea0116d6b 100644 --- a/src/ifcblenderexport/blenderbim/bim/ui.py +++ b/src/ifcblenderexport/blenderbim/bim/ui.py @@ -802,43 +802,6 @@ class BIM_PT_library(Panel): layout.row().prop(scene.BIMLibrary, "description") -class BIM_PT_diff(Panel): - bl_label = "IFC Diff" - bl_idname = "BIM_PT_diff" - bl_options = {"DEFAULT_CLOSED"} - bl_space_type = "PROPERTIES" - bl_region_type = "WINDOW" - bl_context = "scene" - - def draw(self, context): - layout = self.layout - layout.use_property_split = True - - scene = context.scene - bim_properties = scene.BIMProperties - - layout.label(text="IFC Diff Setup:") - - row = layout.row(align=True) - row.prop(bim_properties, "diff_json_file") - row.operator("bim.select_diff_json_file", icon="FILE_FOLDER", text="") - row.operator("bim.visualise_diff", icon="HIDE_OFF", text="") - - row = layout.row(align=True) - row.prop(bim_properties, "diff_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.operator("bim.select_diff_new_file", icon="FILE_FOLDER", text="") - - row = layout.row(align=True) - row.prop(bim_properties, "diff_relationships") - - row = layout.row() - row.operator("bim.execute_ifc_diff") - - class BIM_PT_patch(Panel): bl_label = "IFC Patch" bl_idname = "BIM_PT_patch"