From 2a8251fc94d1b9b837121455dd1d46f1cb3b8788 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Sat, 9 May 2020 18:14:10 +1000 Subject: [PATCH] New UI to manage representation contexts for each object --- .../blenderbim/bim/__init__.py | 1 + .../blenderbim/bim/import_ifc.py | 25 +++++++++++++ .../blenderbim/bim/operator.py | 16 ++++++++- src/ifcblenderexport/blenderbim/bim/prop.py | 2 ++ src/ifcblenderexport/blenderbim/bim/ui.py | 35 +++++++++++++++++-- 5 files changed, 76 insertions(+), 3 deletions(-) diff --git a/src/ifcblenderexport/blenderbim/bim/__init__.py b/src/ifcblenderexport/blenderbim/bim/__init__.py index 59e35330d2..2c6d30a883 100644 --- a/src/ifcblenderexport/blenderbim/bim/__init__.py +++ b/src/ifcblenderexport/blenderbim/bim/__init__.py @@ -178,6 +178,7 @@ if bpy is not None: ui.BIM_PT_material, ui.BIM_PT_mesh, ui.BIM_PT_object, + ui.BIM_PT_representations, ui.BIM_PT_classification_references, ui.BIM_PT_documents, ui.BIM_PT_camera, diff --git a/src/ifcblenderexport/blenderbim/bim/import_ifc.py b/src/ifcblenderexport/blenderbim/bim/import_ifc.py index f06cb3297e..4d23ee2d4a 100644 --- a/src/ifcblenderexport/blenderbim/bim/import_ifc.py +++ b/src/ifcblenderexport/blenderbim/bim/import_ifc.py @@ -435,6 +435,7 @@ class IfcImporter(): self.add_element_classifications(element, obj) self.add_element_document_relations(element, obj) self.add_type_product_psets(element, obj) + self.add_product_representation_contexts(element, obj) self.type_collection.objects.link(obj) self.type_products[element.GlobalId] = obj @@ -523,6 +524,7 @@ class IfcImporter(): self.add_element_document_relations(element, obj) self.add_defines_by_type_relation(element, obj) self.add_product_definitions(element, obj) + self.add_product_representation_contexts(element, obj) self.added_data[element.GlobalId] = obj return obj @@ -627,6 +629,29 @@ class IfcImporter(): bpy.ops.mesh.normals_make_consistent(context_override) bpy.ops.object.editmode_toggle(context_override) + def add_product_representation_contexts(self, element, obj): + subcontexts = [] + if element.is_a('IfcProduct'): + if not element.Representation: + return + for r in element.Representation.Representations: + subcontexts.append('{}/{}/{}'.format( + r.ContextOfItems.ContextType, + r.ContextOfItems.ContextIdentifier, + r.ContextOfItems.TargetView)) + elif element.is_a('IfcTypeProduct'): + if not element.RepresentationMaps: + return + for r in element.RepresentationMaps: + subcontexts.append('{}/{}/{}'.format( + r.MappedRepresentation.ContextOfItems.ContextType, + r.MappedRepresentation.ContextOfItems.ContextIdentifier, + r.MappedRepresentation.ContextOfItems.TargetView)) + subcontexts = set(subcontexts) + for subcontext in subcontexts: + representation_context = obj.BIMObjectProperties.representation_contexts.add() + representation_context.context, representation_context.name, representation_context.target_view = subcontext.split('/') + def add_product_definitions(self, element, obj): if not hasattr(element, 'IsDefinedBy') or not element.IsDefinedBy: return diff --git a/src/ifcblenderexport/blenderbim/bim/operator.py b/src/ifcblenderexport/blenderbim/bim/operator.py index 68c0e8bfa5..a0572ecdc0 100644 --- a/src/ifcblenderexport/blenderbim/bim/operator.py +++ b/src/ifcblenderexport/blenderbim/bim/operator.py @@ -1757,6 +1757,9 @@ class AssignContext(bpy.types.Operator): class SwitchContext(bpy.types.Operator): bl_idname = 'bim.switch_context' bl_label = 'Switch Context' + context_name: bpy.props.StringProperty() + subcontext_name: bpy.props.StringProperty() + target_view_name: bpy.props.StringProperty() # Warning: This is an incredibly experimental operator. It effectively does # a mini-import. A better approach will make this obsolete in the future. @@ -1770,16 +1773,26 @@ class SwitchContext(bpy.types.Operator): 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 + if self.context_name: + self.context = self.context_name + if self.subcontext_name: + self.subcontext = self.subcontext_name + if self.target_view_name: + self.target_view = self.target_view_name mesh = bpy.data.meshes.get('{}/{}/{}/{}'.format( self.context, self.subcontext, self.target_view, self.obj.data.name.split('/')[3])) if not mesh: try: + global_id = self.obj.BIMObjectProperties.attributes.get('GlobalId').string_value 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])) + representation_context = self.obj.BIMObjectProperties.representation_contexts.add() + representation_context.context = self.context + representation_context.name = self.subcontext + representation_context.target_view = self.target_view self.obj.data = mesh return {'FINISHED'} @@ -1806,6 +1819,7 @@ class SwitchContext(bpy.types.Operator): mesh = ifc_importer.create_mesh(element, shape) mesh.name = '{}/{}/{}/{}'.format( self.context, self.subcontext, self.target_view, self.obj.data.name.split('/')[3]) + self.obj.data = mesh material_creator = import_ifc.MaterialCreator(ifc_import_settings) material_creator.create(element, self.obj, mesh) return mesh diff --git a/src/ifcblenderexport/blenderbim/bim/prop.py b/src/ifcblenderexport/blenderbim/bim/prop.py index 3ff6c4b72f..3eee13e17b 100644 --- a/src/ifcblenderexport/blenderbim/bim/prop.py +++ b/src/ifcblenderexport/blenderbim/bim/prop.py @@ -382,6 +382,7 @@ class Variable(PropertyGroup): class Subcontext(PropertyGroup): name: StringProperty(name='Name') + context: StringProperty(name='Context') target_view: StringProperty(name='Target View') @@ -1017,6 +1018,7 @@ class BIMObjectProperties(PropertyGroup): has_boundary_condition: BoolProperty(name='Has Boundary Condition') boundary_condition: PointerProperty(name='Boundary Condition', type=BoundaryCondition) structural_member_connection: PointerProperty(name='Structural Member Connection', type=bpy.types.Object) + representation_contexts: CollectionProperty(name="Representation Contexts", type=Subcontext) class BIMMaterialProperties(PropertyGroup): diff --git a/src/ifcblenderexport/blenderbim/bim/ui.py b/src/ifcblenderexport/blenderbim/bim/ui.py index 193ec14a30..7227a75fe3 100644 --- a/src/ifcblenderexport/blenderbim/bim/ui.py +++ b/src/ifcblenderexport/blenderbim/bim/ui.py @@ -221,6 +221,38 @@ class BIM_PT_documents(Panel): layout.label(text="Reference is invalid") +class BIM_PT_representations(Panel): + bl_label = 'Representations' + bl_idname = 'BIM_PT_representations' + bl_options = {'DEFAULT_CLOSED'} + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = 'object' + + def draw(self, context): + layout = self.layout + props = context.active_object.BIMObjectProperties + + if not props.representation_contexts: + layout.label(text="No representations found") + + row = layout.row(align=True) + 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.operator('bim.switch_context', icon='ADD', text='') + + for index, subcontext in enumerate(props.representation_contexts): + row = layout.row(align=True) + row.prop(subcontext, 'context', text='') + row.prop(subcontext, 'name', text='') + row.prop(subcontext, 'target_view', text='') + op = row.operator('bim.switch_context', icon='OUTLINER_DATA_MESH', text='') + op.context_name = subcontext.context + op.subcontext_name = subcontext.name + op.target_view_name = subcontext.target_view + + class BIM_PT_classification_references(Panel): bl_label = 'Classification References' bl_idname = 'BIM_PT_classification_references' @@ -368,8 +400,7 @@ class BIM_PT_mesh(Panel): row.prop(bpy.context.scene.BIMProperties, 'available_subcontexts', text='') row.prop(bpy.context.scene.BIMProperties, 'available_target_views', text='') - row = layout.row(align=True) - row.operator('bim.switch_context') + row = layout.row() row.operator('bim.assign_context') row = layout.row(align=True)