mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-19 06:39:13 +00:00
Don't assume the first representation when checking materials
This commit is contained in:
@@ -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):
|
||||||
|
|||||||
Reference in New Issue
Block a user