From bbc429bb997cc351002e2f898c2fc3a4e214d16b Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Thu, 7 May 2020 16:57:14 +1000 Subject: [PATCH] New feature to switch / load / create new contexts per object --- .../blenderbim/bim/__init__.py | 1 + src/ifcblenderexport/blenderbim/bim/ifc.py | 10 ++++ .../blenderbim/bim/operator.py | 57 +++++++++++++++++-- src/ifcblenderexport/blenderbim/bim/ui.py | 4 +- 4 files changed, 66 insertions(+), 6 deletions(-) diff --git a/src/ifcblenderexport/blenderbim/bim/__init__.py b/src/ifcblenderexport/blenderbim/bim/__init__.py index 68f9f4654c..f7a108876b 100644 --- a/src/ifcblenderexport/blenderbim/bim/__init__.py +++ b/src/ifcblenderexport/blenderbim/bim/__init__.py @@ -97,6 +97,7 @@ if bpy is not None: operator.ActivateView, operator.ExecuteIfcDiff, operator.AssignContext, + operator.SwitchContext, operator.SetViewPreset1, operator.SetViewPreset2, operator.OpenUpstream, diff --git a/src/ifcblenderexport/blenderbim/bim/ifc.py b/src/ifcblenderexport/blenderbim/bim/ifc.py index 3eb6db8400..a4eeadf5f6 100644 --- a/src/ifcblenderexport/blenderbim/bim/ifc.py +++ b/src/ifcblenderexport/blenderbim/bim/ifc.py @@ -1,5 +1,15 @@ +import bpy +import ifcopenshell + class IfcStore(): path = '' file = None pset_template_path = '' pset_template_file = None + + @staticmethod + def get_file(): + if IfcStore.file is None: + IfcStore.path = bpy.context.scene.BIMProperties.ifc_file + IfcStore.file = ifcopenshell.open(IfcStore.path) + return IfcStore.file diff --git a/src/ifcblenderexport/blenderbim/bim/operator.py b/src/ifcblenderexport/blenderbim/bim/operator.py index 1862a178cf..26435f5044 100644 --- a/src/ifcblenderexport/blenderbim/bim/operator.py +++ b/src/ifcblenderexport/blenderbim/bim/operator.py @@ -1203,11 +1203,7 @@ class ValidateIfcFile(bpy.types.Operator): import ifcopenshell.validate logger = logging.getLogger('validate') logger.setLevel(logging.DEBUG) - if bpy.context.scene.BIMProperties.ifc_file \ - and bpy.context.scene.BIMProperties.ifc_file != ifc.IfcStore.path: - ifc.IfcStore.file = ifcopenshell.open(bpy.context.scene.BIMProperties.ifc_file) - ifc.IfcStore.path = bpy.context.scene.BIMProperties.ifc_file - ifcopenshell.validate.validate(ifc.IfcStore.file, logger) + ifcopenshell.validate.validate(ifc.IfcStore.get_file(), logger) return {'FINISHED'} @@ -1759,6 +1755,57 @@ class AssignContext(bpy.types.Operator): ) +class SwitchContext(bpy.types.Operator): + bl_idname = 'bim.switch_context' + bl_label = 'Switch Context' + + # Warning: This is an incredibly experimental operator. It effectively does + # a mini-import. A better approach will make this obsolete in the future. + def execute(self, context): + self.obj = bpy.context.active_object + + if '/' not in self.obj.data.name: + self.obj.data.name = 'Model/Body/MODEL_VIEW/' + self.obj.data.name + + self.context = bpy.context.scene.BIMProperties.available_contexts + self.subcontext = bpy.context.scene.BIMProperties.available_subcontexts + self.target_view = bpy.context.scene.BIMProperties.available_target_views + + global_id = self.obj.BIMObjectProperties.attributes.get('GlobalId').string_value + + mesh = bpy.data.meshes.get('{}/{}/{}/{}'.format( + self.context, self.subcontext, self.target_view, self.obj.data.name.split('/')[3])) + if not mesh: + try: + mesh = self.pull_mesh_from_ifc(global_id) + except: + mesh = bpy.data.meshes.new('{}/{}/{}/{}'.format( + self.context, self.subcontext, self.target_view, self.obj.data.name.split('/')[3])) + + self.obj.data = mesh + return {'FINISHED'} + + def pull_mesh_from_ifc(self, global_id): + self.file = ifc.IfcStore.get_file() + logger = logging.getLogger('ImportIFC') + ifc_import_settings = import_ifc.IfcImportSettings.factory(bpy.context, ifc.IfcStore.path, logger) + element = self.file.by_id(global_id) + settings = ifcopenshell.geom.settings() + settings.set(settings.INCLUDE_CURVES, True) + rep = [r for r in element.Representation.Representations if + r.ContextOfItems.ContextType == self.context \ + and r.ContextOfItems.ContextIdentifier == self.subcontext \ + and r.ContextOfItems.TargetView == self.target_view][0] + shape = ifcopenshell.geom.create_shape(settings, rep) + ifc_importer = import_ifc.IfcImporter(ifc_import_settings) + mesh = ifc_importer.create_mesh(element, shape) + mesh.name = '{}/{}/{}/{}'.format( + self.context, self.subcontext, self.target_view, self.obj.data.name.split('/')[3]) + material_creator = import_ifc.MaterialCreator(ifc_import_settings) + material_creator.create(element, self.obj, mesh) + return mesh + + class SetViewPreset1(bpy.types.Operator): bl_idname = 'bim.set_view_preset_1' bl_label = 'Set View Preset 1' diff --git a/src/ifcblenderexport/blenderbim/bim/ui.py b/src/ifcblenderexport/blenderbim/bim/ui.py index 8288ff42f9..743f01c697 100644 --- a/src/ifcblenderexport/blenderbim/bim/ui.py +++ b/src/ifcblenderexport/blenderbim/bim/ui.py @@ -367,7 +367,9 @@ class BIM_PT_mesh(Panel): row.prop(bpy.context.scene.BIMProperties, 'available_contexts', text='') row.prop(bpy.context.scene.BIMProperties, 'available_subcontexts', text='') row.prop(bpy.context.scene.BIMProperties, 'available_target_views', text='') - row = layout.row() + + row = layout.row(align=True) + row.operator('bim.switch_context') row.operator('bim.assign_context') row = layout.row()