mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-26 18:21:59 +00:00
Fix #6174. Accommodate invalid index maps, and also implement an early return for single colours.
A single colour index map is a waste but some IFCs have it apparently.
This commit is contained in:
@@ -592,33 +592,42 @@ class Loader(bonsai.core.tool.Loader):
|
|||||||
opacity = opacity if opacity is not None else 1.0
|
opacity = opacity if opacity is not None else 1.0
|
||||||
data_list = [d + (opacity,) for d in data_list]
|
data_list = [d + (opacity,) for d in data_list]
|
||||||
|
|
||||||
faces_tex_coord_data = {}
|
if index_map.is_a("IfcIndexedColourMap") and len(index_map.Colours.ColourList) == 1:
|
||||||
for tex_coord_index, face_remap in zip(texture_map, faces_remap, strict=True):
|
# Early return scenario in case there is only one colour
|
||||||
faces_tex_coord_data[tuple(face_remap)] = (tex_coord_index, face_remap)
|
data_colour = data_list[0]
|
||||||
|
for bface in bm.faces:
|
||||||
|
for loop in bface.loops:
|
||||||
|
loop[layer] = data_colour
|
||||||
|
elif len(texture_map) != len(faces_remap):
|
||||||
|
print(f"Warning: invalid index map found: {index_map}")
|
||||||
|
else:
|
||||||
|
faces_tex_coord_data = {}
|
||||||
|
for tex_coord_index, face_remap in zip(texture_map, faces_remap, strict=True):
|
||||||
|
faces_tex_coord_data[tuple(face_remap)] = (tex_coord_index, face_remap)
|
||||||
|
|
||||||
# Apply attribute to each face
|
# Apply attribute to each face
|
||||||
for bface in bm.faces:
|
for bface in bm.faces:
|
||||||
face = tuple(loop.vert.index for loop in bface.loops)
|
face = tuple(loop.vert.index for loop in bface.loops)
|
||||||
# Find the corresponding index in data list by matching ifc faceset with blender face.
|
# Find the corresponding index in data list by matching ifc faceset with blender face.
|
||||||
data_index = None
|
data_index = None
|
||||||
if tex_coord_data := faces_tex_coord_data.get(face):
|
if tex_coord_data := faces_tex_coord_data.get(face):
|
||||||
tex_coord_index, face_remap = tex_coord_data
|
tex_coord_index, face_remap = tex_coord_data
|
||||||
# Subtract 1 as tex_coord_index starts with 1.
|
# Subtract 1 as tex_coord_index starts with 1.
|
||||||
if map_type == "UV":
|
if map_type == "UV":
|
||||||
data_index = [tex_coord_index[face_remap.index(i)] - 1 for i in face]
|
data_index = [tex_coord_index[face_remap.index(i)] - 1 for i in face]
|
||||||
|
else:
|
||||||
|
data_index = [tex_coord_index - 1 for i in face]
|
||||||
else:
|
else:
|
||||||
data_index = [tex_coord_index - 1 for i in face]
|
# This face may be part of another representation item
|
||||||
else:
|
# Or we couldn't match it due to georeferencing.
|
||||||
# This face may be part of another representation item
|
continue
|
||||||
# Or we couldn't match it due to georeferencing.
|
|
||||||
continue
|
|
||||||
|
|
||||||
# apply uv to each loop
|
# apply uv to each loop
|
||||||
for loop, i in zip(bface.loops, data_index):
|
for loop, i in zip(bface.loops, data_index):
|
||||||
if map_type == "UV":
|
if map_type == "UV":
|
||||||
loop[layer].uv = data_list[i]
|
loop[layer].uv = data_list[i]
|
||||||
else:
|
else:
|
||||||
loop[layer] = data_list[i]
|
loop[layer] = data_list[i]
|
||||||
|
|
||||||
# Finish up, write the bmesh back to the mesh
|
# Finish up, write the bmesh back to the mesh
|
||||||
bm.to_mesh(mesh)
|
bm.to_mesh(mesh)
|
||||||
|
|||||||
Reference in New Issue
Block a user