Skip loading mappings if representation has openings #5405

To avoid errors
This commit is contained in:
Andrej730
2024-09-17 17:50:20 +05:00
parent 2a2efefac3
commit 53a6192858
3 changed files with 37 additions and 13 deletions
+17 -11
View File
@@ -50,7 +50,11 @@ class MaterialCreator:
self.ifc_importer = ifc_importer
def create(
self, element: ifcopenshell.entity_instance, obj: bpy.types.Object, mesh: Union[OBJECT_DATA_TYPE, None]
self,
element: ifcopenshell.entity_instance,
obj: bpy.types.Object,
mesh: Union[OBJECT_DATA_TYPE, None],
shape_has_openings: bool,
) -> None:
if ((rep := getattr(element, "Representation", ...) is not ...) and not rep) or (
(rep := getattr(element, "RepresentationMaps", ...) is not ...) and not rep
@@ -78,7 +82,7 @@ class MaterialCreator:
# Though 0 value will not occur as we don't use default materials in IfcImporter.
self.parsed_meshes.add(self.mesh.name)
self.load_texture_maps()
self.load_texture_maps(shape_has_openings)
self.assign_material_slots_to_faces()
tool.Geometry.record_object_materials(obj)
del self.mesh["ios_materials"]
@@ -104,13 +108,15 @@ class MaterialCreator:
print(f"WARNING. IfcTextureMap texture coordinates is not supported.")
return
def load_texture_maps(self) -> None:
def load_texture_maps(self, shape_has_openings: bool) -> None:
for style_or_material_id in self.mesh["ios_materials"]:
if not (material := self.styles.get(style_or_material_id)):
continue
material = self.styles[style_or_material_id]
if coords := self.get_ifc_coordinate(material):
if shape_has_openings and coords.is_a("IfcIndexedTextureMap"):
continue
tool.Loader.load_indexed_map(coords, self.mesh)
def assign_material_slots_to_faces(self) -> None:
@@ -586,7 +592,7 @@ class IfcImporter:
break
obj = bpy.data.objects.new(tool.Loader.get_name(element), mesh)
self.link_element(element, obj)
self.material_creator.create(element, obj, mesh)
self.material_creator.create(element, obj, mesh, False)
self.type_products[element.GlobalId] = obj
def create_native_elements(self):
@@ -850,7 +856,7 @@ class IfcImporter:
def create_product(
self,
element: ifcopenshell.entity_instance,
shape: Optional[Any] = None,
shape: Optional[Union[ifcopenshell.geom.ShapeElementType, ifcopenshell.geom.ShapeType]] = None,
mesh: Optional[OBJECT_DATA_TYPE] = None,
) -> Union[bpy.types.Object, None]:
if element is None:
@@ -886,12 +892,12 @@ class IfcImporter:
mat = np.array(shape.transformation.matrix).reshape((4, 4), order="F")
self.set_matrix_world(obj, tool.Loader.apply_blender_offset_to_matrix_world(obj, mat))
assert mesh # Type checker.
self.material_creator.create(element, obj, mesh)
elif mesh:
self.material_creator.create(element, obj, mesh, tool.Geometry.does_shape_has_openings(shape))
elif mesh: # When does this occur?
self.set_matrix_world(
obj, tool.Loader.apply_blender_offset_to_matrix_world(obj, self.get_element_matrix(element))
)
self.material_creator.create(element, obj, mesh)
self.material_creator.create(element, obj, mesh, False)
elif hasattr(element, "ObjectPlacement"):
self.set_matrix_world(
obj, tool.Loader.apply_blender_offset_to_matrix_world(obj, self.get_element_matrix(element))
@@ -1383,9 +1389,9 @@ class IfcImporter:
mesh.polygons.foreach_set("use_smooth", [0] * total_faces)
mesh.update()
# TODO: geometry id is not always an int.
rep_id = geometry.id
if rep_id.isdigit():
rep_str: str = geometry.id
if "openings" not in rep_str:
rep_id = rep_str.split("-", 1)[0]
rep = self.file.by_id(int(rep_id))
tool.Loader.load_indexed_colour_map(rep, mesh)
else:
+10 -2
View File
@@ -646,12 +646,20 @@ class Geometry(bonsai.core.tool.Geometry):
elif shape:
mesh = ifc_importer.create_mesh(element, shape)
ifc_importer.material_creator.load_existing_materials()
ifc_importer.material_creator.create(element, obj, mesh)
shape_has_openings = cls.does_shape_has_openings(shape)
ifc_importer.material_creator.create(element, obj, mesh, shape_has_openings)
mesh.BIMMeshProperties.has_openings_applied = apply_openings
tool.Loader.load_indexed_colour_map(representation, mesh)
if not shape_has_openings:
tool.Loader.load_indexed_colour_map(representation, mesh)
return mesh
@classmethod
def does_shape_has_openings(
cls, shape: Union[ifcopenshell.geom.ShapeElementType, ifcopenshell.geom.ShapeType]
) -> bool:
return "openings" in getattr(shape, "geometry", shape).id
@classmethod
def import_representation_parameters(cls, data: bpy.types.Mesh) -> None:
props = data.BIMMeshProperties
+10
View File
@@ -472,6 +472,16 @@ class Loader(bonsai.core.tool.Loader):
@classmethod
def load_indexed_colour_map(cls, representation: ifcopenshell.entity_instance, mesh: bpy.types.Mesh) -> None:
"""Ensure indexed colour map is loaded for representation if it's available.
Method doesn't support elements with openings, see #5405.
:param representation: IfcShapeRepresentation of any type. Representation may not have an indexed colour map,
method will automatically check if it does and will skip it otherwise.
:raises AssertionError: If mesh doesn't match the representation exactly, which usually occurs
if element geometry is altered by openings.
"""
if representation.RepresentationType != "Tessellation":
return