From 808ddad2861b6c1324c67dd3409bd9ebf6433cd1 Mon Sep 17 00:00:00 2001 From: Kristian <57712777+NMC-TBone@users.noreply.github.com> Date: Fri, 29 Nov 2024 11:43:35 -0700 Subject: [PATCH] fix(vertex colors): support new color attributes and handle multiple domains (#215) Vertex colors are now handled using `color_attributes`, replacing the deprecated `vertex_colors`. This update adds support for both CORNER and POINT domains. https://docs.blender.org/api/current/bpy.types.Mesh.html#bpy.types.Mesh.vertex_colors fixes: #204 --- addon/i3dio/node_classes/shape.py | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/addon/i3dio/node_classes/shape.py b/addon/i3dio/node_classes/shape.py index f858c7b..325e5de 100644 --- a/addon/i3dio/node_classes/shape.py +++ b/addon/i3dio/node_classes/shape.py @@ -192,7 +192,7 @@ def process_subsets(self, mesh) -> None: subset.first_index = next_index next_vertex, next_index = self.process_subset(mesh, subset) - def process_subset(self, mesh, subset: SubSet, triangle_offset: int = 0) -> tuple[int, int]: + def process_subset(self, mesh: bpy.types.Mesh, subset: SubSet, triangle_offset: int = 0) -> tuple[int, int]: self.logger.debug(f"Processing subset: {subset}") for triangle in subset.triangles[triangle_offset:]: @@ -202,13 +202,23 @@ def process_subset(self, mesh, subset: SubSet, triangle_offset: int = 0) -> tupl for loop_index in triangle.loops: blender_vertex = mesh.vertices[mesh.loops[loop_index].vertex_index] - # Add vertex color vertex_color = None - if len(mesh.vertex_colors): - # Get the color from the active layer or first layer, since only one vertex color layer is supported in GE - color_layer = mesh.vertex_colors.active if mesh.vertex_colors.active is not None else mesh.vertex_colors[0] - vertex_color = color_layer.data[loop_index].color + if len(mesh.color_attributes): + # Use the active color layer or fallback to the first (GE supports only one layer) + color_layer = mesh.color_attributes.active_color or mesh.color_attributes[0] + + match color_layer.domain: + case 'CORNER': + # Color data is stored per corner/loop + vertex_color = color_layer.data[loop_index].color_srgb + case 'POINT': + # Color data is stored per vertex + color_vertex_index = mesh.loops[loop_index].vertex_index + vertex_color = color_layer.data[color_vertex_index].color_srgb + case _: + self.logger.warning(f"Incompatible color attribute {color_layer.name}: " + f"domain={color_layer.domain}, data_type={color_layer.data_type}") # Add uvs uvs = []