Don't assume the first representation when checking materials

This commit is contained in:
Dion Moult
2020-03-20 09:38:41 +11:00
parent 83bba733c7
commit 3b8b0cbbbf
+54 -37
View File
@@ -16,46 +16,63 @@ class MaterialCreator():
self.parsed_meshes = [] self.parsed_meshes = []
self.ifc_import_settings = ifc_import_settings self.ifc_import_settings = ifc_import_settings
def create(self, element, object, mesh): def create(self, element, obj, mesh):
self.object = object self.obj = obj
self.mesh = mesh self.mesh = mesh
if not element.Representation: if not element.Representation:
return return
if self.ifc_import_settings.should_treat_styled_item_as_material \ if self.ifc_import_settings.should_treat_styled_item_as_material \
and self.mesh.name in self.parsed_meshes: and self.mesh.name in self.parsed_meshes:
return return
for item in element.Representation.Representations[0].Items: if self.parse_representations(element):
if item.is_a('IfcMappedItem'): return # styled items override material styles
item = item.MappingSource.MappedRepresentation.Items[0] self.parse_material(element)
if item.StyledByItem:
styled_item = item.StyledByItem[0] def parse_representations(self, element):
if styled_item.Name: for representation in element.Representation.Representations:
material_name = styled_item.Name if self.parse_representation(representation):
# This is for a bug in Revit where Revit exports this in IFC4 return True
elif styled_item.Styles[0] \
and styled_item.Styles[0].is_a('IfcPresentationStyleAssignment') \ def parse_representation(self, representation):
and styled_item.Styles[0].Styles[0].Name: for item in representation.Items:
material_name = styled_item.Styles[0].Styles[0].Name if self.parse_representation_item(item):
elif styled_item.Styles[0] \ return True
and styled_item.Styles[0].is_a('IfcPresentationStyle') \
and styled_item.Styles[0].Name: def parse_representation_item(self, item):
material_name = styled_item.Styles[0].Name if item.is_a('IfcMappedItem'):
else: item = item.MappingSource.MappedRepresentation.Items[0]
material_name = str(styled_item.id()) if not item.StyledByItem:
if material_name not in self.materials: return
self.materials[material_name] = bpy.data.materials.new(material_name) styled_item = item.StyledByItem[0]
self.parse_styled_item(item.StyledByItem[0], self.materials[material_name]) if styled_item.Name:
if self.ifc_import_settings.should_treat_styled_item_as_material: material_name = styled_item.Name
# Revit workaround: since Revit exports all material # This is for a bug in Revit where Revit exports this in IFC4
# assignments as individual object styled items. Treating elif styled_item.Styles[0] \
# them as reusable materials makes things much more and styled_item.Styles[0].is_a('IfcPresentationStyleAssignment') \
# efficient in Blender. and styled_item.Styles[0].Styles[0].Name:
if self.mesh.name not in self.parsed_meshes: material_name = styled_item.Styles[0].Styles[0].Name
self.assign_material_to_mesh(self.materials[material_name]) elif styled_item.Styles[0] \
else: and styled_item.Styles[0].is_a('IfcPresentationStyle') \
# Proper behaviour and styled_item.Styles[0].Name:
self.assign_material_to_mesh(self.materials[material_name], is_styled_item=True) material_name = styled_item.Styles[0].Name
return # styled items override material styles else:
material_name = str(styled_item.id())
if material_name not in self.materials:
self.materials[material_name] = bpy.data.materials.new(material_name)
self.parse_styled_item(item.StyledByItem[0], self.materials[material_name])
if self.ifc_import_settings.should_treat_styled_item_as_material:
# Revit workaround: since Revit exports all material
# assignments as individual object styled items. Treating
# them as reusable materials makes things much more
# efficient in Blender.
if self.mesh.name not in self.parsed_meshes:
self.assign_material_to_mesh(self.materials[material_name])
else:
# Proper behaviour
self.assign_material_to_mesh(self.materials[material_name], is_styled_item=True)
return True
def parse_material(self, element):
for association in element.HasAssociations: for association in element.HasAssociations:
if association.is_a('IfcRelAssociatesMaterial'): if association.is_a('IfcRelAssociatesMaterial'):
material_select = association.RelatingMaterial material_select = association.RelatingMaterial
@@ -117,8 +134,8 @@ class MaterialCreator():
self.parsed_meshes.append(self.mesh.name) self.parsed_meshes.append(self.mesh.name)
self.mesh.materials.append(material) self.mesh.materials.append(material)
if is_styled_item: if is_styled_item:
self.object.material_slots[0].link = 'OBJECT' self.obj.material_slots[0].link = 'OBJECT'
self.object.material_slots[0].material = material self.obj.material_slots[0].material = material
class IfcImporter(): class IfcImporter():
def __init__(self, ifc_import_settings): def __init__(self, ifc_import_settings):