From de561b78e0bd9fd48d11e576c12c8d0f209eeb52 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Sun, 7 Nov 2021 13:20:24 +1100 Subject: [PATCH] Resolve #1750. You can now save IFCs under a relative path to your Blend file. --- src/blenderbim/blenderbim/bim/ifc.py | 3 +++ src/blenderbim/blenderbim/bim/module/project/__init__.py | 3 ++- src/blenderbim/blenderbim/bim/module/project/operator.py | 7 ++++++- src/blenderbim/test/bim/feature/project.feature | 9 ++++++++- 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/ifc.py b/src/blenderbim/blenderbim/bim/ifc.py index df11e946d5..5739cc3805 100644 --- a/src/blenderbim/blenderbim/bim/ifc.py +++ b/src/blenderbim/blenderbim/bim/ifc.py @@ -16,6 +16,7 @@ # You should have received a copy of the GNU General Public License # along with BlenderBIM Add-on. If not, see . +import os import bpy import uuid import zipfile @@ -62,6 +63,8 @@ class IfcStore: def get_file(): if IfcStore.file is None: IfcStore.path = bpy.context.scene.BIMProperties.ifc_file + if not os.path.isabs(IfcStore.path): + IfcStore.path = os.path.abspath(os.path.join(bpy.path.abspath("//"), IfcStore.path)) if IfcStore.path: try: IfcStore.load_file(IfcStore.path) diff --git a/src/blenderbim/blenderbim/bim/module/project/__init__.py b/src/blenderbim/blenderbim/bim/module/project/__init__.py index b21d486c2f..9ef8ba8b39 100644 --- a/src/blenderbim/blenderbim/bim/module/project/__init__.py +++ b/src/blenderbim/blenderbim/bim/module/project/__init__.py @@ -55,7 +55,8 @@ classes = ( def menu_func_export(self, context): - self.layout.operator(operator.ExportIFC.bl_idname, text="Industry Foundation Classes (.ifc/.ifczip/.ifcjson)") + op = self.layout.operator(operator.ExportIFC.bl_idname, text="Industry Foundation Classes (.ifc/.ifczip/.ifcjson)") + op.should_save_as = False def menu_func_import(self, context): diff --git a/src/blenderbim/blenderbim/bim/module/project/operator.py b/src/blenderbim/blenderbim/bim/module/project/operator.py index 516b70f15c..31fa5c3388 100644 --- a/src/blenderbim/blenderbim/bim/module/project/operator.py +++ b/src/blenderbim/blenderbim/bim/module/project/operator.py @@ -741,6 +741,7 @@ class ExportIFC(bpy.types.Operator): 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_save_as: bpy.props.BoolProperty(name="Should Save As", default=False) + use_relative_path: bpy.props.BoolProperty(name="Use Relative Path", default=False) def invoke(self, context, event): if not IfcStore.get_file(): @@ -748,6 +749,8 @@ class ExportIFC(bpy.types.Operator): return {"FINISHED"} if context.scene.BIMProperties.ifc_file and not self.should_save_as: self.filepath = context.scene.BIMProperties.ifc_file + if not os.path.isabs(self.filepath): + self.filepath = os.path.abspath(os.path.join(bpy.path.abspath("//"), self.filepath)) return self.execute(context) if not self.filepath: self.filepath = bpy.path.ensure_ext(bpy.data.filepath, ".ifc") @@ -790,7 +793,9 @@ class ExportIFC(bpy.types.Operator): if not scene.DocProperties.ifc_files: new = scene.DocProperties.ifc_files.add() new.name = output_file - if not scene.BIMProperties.ifc_file or self.should_save_as: + if self.use_relative_path and bpy.data.is_saved: + output_file = os.path.relpath(output_file, bpy.path.abspath("//")) + if scene.BIMProperties.ifc_file != output_file: scene.BIMProperties.ifc_file = output_file if bpy.data.is_saved and bpy.data.is_dirty and bpy.data.filepath: bpy.ops.wm.save_mainfile(filepath=bpy.data.filepath) diff --git a/src/blenderbim/test/bim/feature/project.feature b/src/blenderbim/test/bim/feature/project.feature index 5cfa76f322..e95aef66e4 100644 --- a/src/blenderbim/test/bim/feature/project.feature +++ b/src/blenderbim/test/bim/feature/project.feature @@ -324,7 +324,7 @@ Scenario: Export IFC - with basic contents Given an empty Blender session And I press "bim.load_project(filepath='{cwd}/test/files/basic.ifc')" When I press "export_ifc.bim(filepath='{cwd}/test/files/export.ifc')" - Then "scene.BIMProperties.ifc_file" is "{cwd}/test/files/basic.ifc" + Then "scene.BIMProperties.ifc_file" is "{cwd}/test/files/export.ifc" Scenario: Export IFC - with basic contents and saving as another file Given an empty Blender session @@ -332,6 +332,13 @@ Scenario: Export IFC - with basic contents and saving as another file When I press "export_ifc.bim(filepath='{cwd}/test/files/export.ifc', should_save_as=True)" Then "scene.BIMProperties.ifc_file" is "{cwd}/test/files/export.ifc" +Scenario: Export IFC - with basic contents and saving as a relative path + Given an empty Blender session + And I press "bim.load_project(filepath='{cwd}/test/files/basic.ifc')" + When I press "wm.save_mainfile(filepath='{cwd}/test/files/export.blend')" + And I press "export_ifc.bim(filepath='{cwd}/test/files/export.ifc', use_relative_path=True)" + Then "scene.BIMProperties.ifc_file" is "export.ifc" + Scenario: Export IFC - with deleted objects synchronised Given an empty IFC project When the object "IfcBuildingStorey/My Storey" is selected