From 3a0edab8c150749293defd4b889f7019c2e85551 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Sat, 20 Feb 2021 15:15:44 +1100 Subject: [PATCH] Blender now helps prevent saving Blender without having an exported IFC. See #1323. --- src/ifcblenderexport/blenderbim/bim/__init__.py | 2 ++ src/ifcblenderexport/blenderbim/bim/handler.py | 16 ++++++++++++++-- src/ifcblenderexport/blenderbim/bim/operator.py | 3 +++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/ifcblenderexport/blenderbim/bim/__init__.py b/src/ifcblenderexport/blenderbim/bim/__init__.py index 6d94237727..065e88ed59 100644 --- a/src/ifcblenderexport/blenderbim/bim/__init__.py +++ b/src/ifcblenderexport/blenderbim/bim/__init__.py @@ -165,6 +165,7 @@ if bpy is not None: bpy.app.handlers.depsgraph_update_post.append(on_register) bpy.app.handlers.load_post.append(handler.setDefaultProperties) bpy.app.handlers.load_post.append(handler.loadIfcStore) + bpy.app.handlers.save_pre.append(handler.ensureIfcExported) bpy.app.handlers.save_pre.append(handler.storeIdMap) bpy.types.TOPBAR_MT_file_export.append(menu_func_export) bpy.types.TOPBAR_MT_file_import.append(menu_func_import) @@ -191,6 +192,7 @@ if bpy is not None: bpy.app.handlers.load_post.remove(handler.setDefaultProperties) bpy.app.handlers.load_post.remove(handler.loadIfcStore) bpy.app.handlers.save_pre.remove(handler.storeIdMap) + bpy.app.handlers.save_pre.remove(handler.ensureIfcExported) bpy.types.TOPBAR_MT_file_export.remove(menu_func_export) bpy.types.TOPBAR_MT_file_import.remove(menu_func_import) del bpy.types.Scene.BIMProperties diff --git a/src/ifcblenderexport/blenderbim/bim/handler.py b/src/ifcblenderexport/blenderbim/bim/handler.py index a8960d04cc..25527d3dd7 100644 --- a/src/ifcblenderexport/blenderbim/bim/handler.py +++ b/src/ifcblenderexport/blenderbim/bim/handler.py @@ -10,22 +10,34 @@ def loadIfcStore(scene): IfcStore.file = None IfcStore.schema = None props = bpy.context.scene.BIMProperties - IfcStore.id_map = {int(k): bpy.data.objects.get(v) for k, v in json.loads(props.id_map).items()} if props.id_map else {} + IfcStore.id_map = ( + {int(k): bpy.data.objects.get(v) for k, v in json.loads(props.id_map).items()} if props.id_map else {} + ) IfcStore.guid_map = ( {k: bpy.data.objects.get(v) for k, v in json.loads(props.guid_map).items()} if props.id_map else {} ) # Purge data cache from blenderbim.bim import modules + for module in modules.values(): if not module: continue try: - getattr(getattr(module, 'data'), 'Data').purge() + getattr(getattr(module, "data"), "Data").purge() except AttributeError: pass +@persistent +def ensureIfcExported(scene): + print('ensuring') + if IfcStore.get_file() and not bpy.context.scene.BIMProperties.ifc_file: + # The invocation pops up a file select window. + # This is non-blocking, therefore the Blend file is saved before we export. + bpy.ops.export_ifc.bim("INVOKE_DEFAULT", should_force_resave=True) + + @persistent def storeIdMap(scene): bpy.context.scene.BIMProperties.id_map = json.dumps({k: v.name for k, v in IfcStore.id_map.items()}) diff --git a/src/ifcblenderexport/blenderbim/bim/operator.py b/src/ifcblenderexport/blenderbim/bim/operator.py index e4cce773c2..da701ce54a 100644 --- a/src/ifcblenderexport/blenderbim/bim/operator.py +++ b/src/ifcblenderexport/blenderbim/bim/operator.py @@ -67,6 +67,7 @@ class ExportIFC(bpy.types.Operator): filepath: bpy.props.StringProperty(subtype="FILE_PATH") json_version: bpy.props.EnumProperty(items=[("4", "4", ""), ("5a", "5a", "")], name="IFC JSON Version") json_compact: bpy.props.BoolProperty(name="Export Compact IFCJSON", default=False) + should_force_resave: bpy.props.BoolProperty(name="Resave .blend", default=False) def invoke(self, context, event): if not self.filepath: @@ -103,6 +104,8 @@ class ExportIFC(bpy.types.Operator): new.name = output_file if not bpy.context.scene.BIMProperties.ifc_file: bpy.context.scene.BIMProperties.ifc_file = output_file + if self.should_force_resave: + bpy.ops.wm.save_as_mainfile(filepath=bpy.data.filepath) return {"FINISHED"}