Skip to content

Commit 90f2b42

Browse files
authored
Optimize mesh splitting performance by face colors (#595)
Improved the split_mesh_by_face_color function to use vectorized operations instead of iterating over unique colors. This change significantly reduces processing time for meshes with many faces by batching submesh creation and using numpy's sorting capabilities.
1 parent 05443ae commit 90f2b42

File tree

1 file changed

+23
-7
lines changed

1 file changed

+23
-7
lines changed

skrobot/utils/mesh.py

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,31 @@ def split_mesh_by_face_color(mesh):
2222
generate a list of submeshes, where each submesh contains
2323
faces of the same color.
2424
"""
25-
if mesh.visual.kind == 'texture':
25+
# If mesh has no color info or uses texture, don't split
26+
if not hasattr(mesh.visual, 'face_colors') or mesh.visual.kind == 'texture':
2627
return [mesh]
28+
2729
face_colors = mesh.visual.face_colors
28-
unique_colors = np.unique(face_colors, axis=0)
29-
submeshes = []
30-
for color in unique_colors:
31-
mask = np.all(face_colors == color, axis=1)
32-
submesh = mesh.submesh([mask])[0]
33-
submeshes.append(submesh)
30+
31+
# Use np.unique to get unique colors and inverse indices
32+
# return_inverse=True returns indices to reconstruct the original array
33+
unique_colors, inverse_indices = np.unique(
34+
face_colors, axis=0, return_inverse=True)
35+
36+
# Sort face indices by their color group
37+
# This creates a contiguous array of face indices grouped by color
38+
sorted_face_indices = np.arange(len(face_colors))[inverse_indices.argsort()]
39+
40+
# Count how many faces belong to each color group
41+
counts = np.bincount(inverse_indices)
42+
43+
# Split the sorted indices into groups based on counts
44+
# This creates a list of arrays, each containing face indices for one color
45+
grouped_face_indices = np.split(sorted_face_indices, counts.cumsum()[:-1])
46+
47+
# Create all submeshes at once using the grouped indices
48+
# append=False prevents adding to the original mesh
49+
submeshes = mesh.submesh(grouped_face_indices, append=False)
3450

3551
return submeshes
3652

0 commit comments

Comments
 (0)