mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-21 09:05:18 +00:00
Support multiple materials per object on import
This commit is contained in:
@@ -26,6 +26,7 @@ class MaterialCreator():
|
|||||||
and self.mesh.name in self.parsed_meshes:
|
and self.mesh.name in self.parsed_meshes:
|
||||||
return
|
return
|
||||||
if self.parse_representations(element):
|
if self.parse_representations(element):
|
||||||
|
self.assign_material_slots_to_faces(obj, mesh)
|
||||||
return # styled items override material styles
|
return # styled items override material styles
|
||||||
self.parse_material(element)
|
self.parse_material(element)
|
||||||
|
|
||||||
@@ -35,9 +36,11 @@ class MaterialCreator():
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def parse_representation(self, representation):
|
def parse_representation(self, representation):
|
||||||
|
has_parsed = False
|
||||||
for item in representation.Items:
|
for item in representation.Items:
|
||||||
if self.parse_representation_item(item):
|
if self.parse_representation_item(item):
|
||||||
return True
|
has_parsed = True
|
||||||
|
return has_parsed
|
||||||
|
|
||||||
def parse_representation_item(self, item):
|
def parse_representation_item(self, item):
|
||||||
if item.is_a('IfcMappedItem'):
|
if item.is_a('IfcMappedItem'):
|
||||||
@@ -56,6 +59,12 @@ class MaterialCreator():
|
|||||||
and styled_item.Styles[0].is_a('IfcPresentationStyle') \
|
and styled_item.Styles[0].is_a('IfcPresentationStyle') \
|
||||||
and styled_item.Styles[0].Name:
|
and styled_item.Styles[0].Name:
|
||||||
material_name = styled_item.Styles[0].Name
|
material_name = styled_item.Styles[0].Name
|
||||||
|
elif styled_item.Styles[0] \
|
||||||
|
and styled_item.Styles[0].is_a('IfcPresentationStyleAssignment'):
|
||||||
|
material_name = str(styled_item.Styles[0].Styles[0].id())
|
||||||
|
elif styled_item.Styles[0] \
|
||||||
|
and styled_item.Styles[0].is_a('IfcPresentationStyle'):
|
||||||
|
material_name = str(styled_item.Styles[0].id())
|
||||||
else:
|
else:
|
||||||
material_name = str(styled_item.id())
|
material_name = str(styled_item.id())
|
||||||
if material_name not in self.materials:
|
if material_name not in self.materials:
|
||||||
@@ -73,6 +82,20 @@ class MaterialCreator():
|
|||||||
self.assign_material_to_mesh(self.materials[material_name], is_styled_item=True)
|
self.assign_material_to_mesh(self.materials[material_name], is_styled_item=True)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def assign_material_slots_to_faces(self, obj, mesh):
|
||||||
|
if not mesh['ios_materials']:
|
||||||
|
return
|
||||||
|
slots = [s.name for s in obj.material_slots]
|
||||||
|
for index, polygon in enumerate(mesh.polygons):
|
||||||
|
material = mesh['ios_materials'][mesh['ios_material_ids'][index]]
|
||||||
|
if 'surface-style-' in material:
|
||||||
|
material = material[len('surface-style-'):]
|
||||||
|
try:
|
||||||
|
polygon.material_index = slots.index(material)
|
||||||
|
except:
|
||||||
|
self.ifc_import_settings.logger.error(
|
||||||
|
'Failed to assign material {} to object {}'.format(material, obj.name))
|
||||||
|
|
||||||
def parse_material(self, element):
|
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'):
|
||||||
@@ -135,8 +158,9 @@ 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.obj.material_slots[0].link = 'OBJECT'
|
index = len(self.obj.material_slots) - 1
|
||||||
self.obj.material_slots[0].material = material
|
self.obj.material_slots[index].link = 'OBJECT'
|
||||||
|
self.obj.material_slots[index].material = material
|
||||||
|
|
||||||
class IfcImporter():
|
class IfcImporter():
|
||||||
def __init__(self, ifc_import_settings):
|
def __init__(self, ifc_import_settings):
|
||||||
@@ -738,6 +762,8 @@ class IfcImporter():
|
|||||||
edges = [[e[i], e[i + 1]]
|
edges = [[e[i], e[i + 1]]
|
||||||
for i in range(0, len(e), 2)]
|
for i in range(0, len(e), 2)]
|
||||||
mesh.from_pydata(vertices, edges, faces)
|
mesh.from_pydata(vertices, edges, faces)
|
||||||
|
mesh['ios_materials'] = [m.name for m in geometry.materials]
|
||||||
|
mesh['ios_material_ids'] = geometry.material_ids
|
||||||
return mesh
|
return mesh
|
||||||
except:
|
except:
|
||||||
self.ifc_import_settings.logger.error('Could not create mesh for {}: {}/{}'.format(element.GlobalId, self.get_name(element)))
|
self.ifc_import_settings.logger.error('Could not create mesh for {}: {}/{}'.format(element.GlobalId, self.get_name(element)))
|
||||||
|
|||||||
Reference in New Issue
Block a user