From 72a1c00e4683517b9ef667a7edbc7843b8c501fc Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Mon, 1 Jun 2020 22:37:11 +1000 Subject: [PATCH] Switching contexts are now more tolerant of broken IFCs. See #865. --- .../blenderbim/bim/import_ifc.py | 18 +++++------ .../blenderbim/bim/operator.py | 31 ++++++++++++------- src/ifcblenderexport/blenderbim/bim/ui.py | 1 + 3 files changed, 30 insertions(+), 20 deletions(-) diff --git a/src/ifcblenderexport/blenderbim/bim/import_ifc.py b/src/ifcblenderexport/blenderbim/bim/import_ifc.py index b0b1398bb8..68f47eb2a2 100644 --- a/src/ifcblenderexport/blenderbim/bim/import_ifc.py +++ b/src/ifcblenderexport/blenderbim/bim/import_ifc.py @@ -664,22 +664,22 @@ class IfcImporter(): for r in element.Representation.Representations: if r.ContextOfItems.is_a('IfcGeometricRepresentationSubContext'): subcontexts.append('{}/{}/{}'.format( - r.ContextOfItems.ContextType, - r.ContextOfItems.ContextIdentifier, - r.ContextOfItems.TargetView)) + r.ContextOfItems.ContextType or '', + r.ContextOfItems.ContextIdentifier or '', + r.ContextOfItems.TargetView or '')) else: subcontexts.append('{}/{}/{}'.format( - r.ContextOfItems.ContextType, - r.ContextOfItems.ContextIdentifier, - None)) + r.ContextOfItems.ContextType or '', + r.ContextOfItems.ContextIdentifier or '', + '')) 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)) + r.MappedRepresentation.ContextOfItems.ContextType or '', + r.MappedRepresentation.ContextOfItems.ContextIdentifier or '', + r.MappedRepresentation.ContextOfItems.TargetView or '')) subcontexts = set(subcontexts) for subcontext in subcontexts: representation_context = obj.BIMObjectProperties.representation_contexts.add() diff --git a/src/ifcblenderexport/blenderbim/bim/operator.py b/src/ifcblenderexport/blenderbim/bim/operator.py index 1fbee0de20..615e905ebd 100644 --- a/src/ifcblenderexport/blenderbim/bim/operator.py +++ b/src/ifcblenderexport/blenderbim/bim/operator.py @@ -1983,6 +1983,7 @@ class AssignContext(bpy.types.Operator): class SwitchContext(bpy.types.Operator): bl_idname = 'bim.switch_context' bl_label = 'Switch Context' + has_target_context: bpy.props.BoolProperty() context_name: bpy.props.StringProperty() subcontext_name: bpy.props.StringProperty() target_view_name: bpy.props.StringProperty() @@ -1999,11 +2000,9 @@ class SwitchContext(bpy.types.Operator): self.subcontext = bpy.context.scene.BIMProperties.available_subcontexts self.target_view = bpy.context.scene.BIMProperties.available_target_views - if self.context_name: + if self.has_target_context: 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( @@ -2031,17 +2030,27 @@ class SwitchContext(bpy.types.Operator): settings = ifcopenshell.geom.settings() settings.set(settings.INCLUDE_CURVES, True) if element.is_a('IfcProduct'): - 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] + representations = element.Representation.Representations else: - rep = [rm.MappedRepresentation for rm in element.RepresentationMaps if - rm.MappedRepresentation.ContextOfItems.ContextType == self.context \ - and rm.MappedRepresentation.ContextOfItems.ContextIdentifier == self.subcontext \ - and rm.MappedRepresentation.ContextOfItems.TargetView == self.target_view][0] + representations = element.RepresentationMaps + + for rep in element.Representation.Representations: + if rep.ContextOfItems.is_a('IfcGeometricRepresentationSubContext') \ + and rep.ContextOfItems.ContextType == self.context \ + and rep.ContextOfItems.ContextIdentifier == self.subcontext \ + and rep.ContextOfItems.TargetView == self.target_view: + break + elif rep.ContextOfItems.is_a('IfcGeometricRepresentationContext') \ + and rep.ContextOfItems.ContextType == self.context \ + and rep.ContextOfItems.ContextIdentifier == self.subcontext: + break + + if not element.is_a('IfcProduct'): + rep = rep.MappedRepresentation + shape = ifcopenshell.geom.create_shape(settings, rep) ifc_importer = import_ifc.IfcImporter(ifc_import_settings) + ifc_importer.file = self.file mesh = ifc_importer.create_mesh(element, shape) mesh.name = '{}/{}/{}/{}'.format( self.context, self.subcontext, self.target_view, self.obj.data.name.split('/')[3]) diff --git a/src/ifcblenderexport/blenderbim/bim/ui.py b/src/ifcblenderexport/blenderbim/bim/ui.py index 86e3f49b25..233301d2e8 100644 --- a/src/ifcblenderexport/blenderbim/bim/ui.py +++ b/src/ifcblenderexport/blenderbim/bim/ui.py @@ -248,6 +248,7 @@ class BIM_PT_representations(Panel): row.prop(subcontext, 'name', text='') row.prop(subcontext, 'target_view', text='') op = row.operator('bim.switch_context', icon='OUTLINER_DATA_MESH', text='') + op.has_target_context = True op.context_name = subcontext.context op.subcontext_name = subcontext.name op.target_view_name = subcontext.target_view