Skip to content

Commit 7cc6cbb

Browse files
committed
obj to usd: Mesh load optimization
1 parent c78947e commit 7cc6cbb

File tree

1 file changed

+23
-28
lines changed

1 file changed

+23
-28
lines changed

urdf_usd_converter/_impl/mesh.py

Lines changed: 23 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# SPDX-License-Identifier: Apache-2.0
33
import pathlib
44

5+
import numpy as np
56
import stl
67
import tinyobjloader
78
import usdex.core
@@ -154,51 +155,45 @@ def convert_obj(prim: Usd.Prim, input_path: pathlib.Path, data: ConversionData)
154155
obj_mesh = shape.mesh
155156
face_vertex_counts = obj_mesh.num_face_vertices
156157

157-
# Collect vertex indices used in this shape
158-
vertex_indices_in_shape = [idx.vertex_index for idx in obj_mesh.indices]
159-
unique_vertex_indices = sorted(set(vertex_indices_in_shape))
158+
# Get indices directly as arrays
159+
vertex_indices_in_shape = np.array(obj_mesh.vertex_indices(), dtype=np.int32)
160160

161-
# Create mapping from old indices to new indices
162-
vertex_index_map = {old_idx: new_idx for new_idx, old_idx in enumerate(unique_vertex_indices)}
161+
# Process vertices using NumPy for speed
162+
unique_vertex_indices = np.unique(vertex_indices_in_shape)
163163

164-
# Extract only vertices used in this shape
165-
points = []
166-
for old_idx in unique_vertex_indices:
167-
i = old_idx * 3
168-
points.append(Gf.Vec3f(attrib.vertices[i], attrib.vertices[i + 1], attrib.vertices[i + 2]))
164+
# Extract vertices: reshape attrib.vertices and use NumPy indexing
165+
vertices_array = np.array(attrib.vertices, dtype=np.float32).reshape(-1, 3)
166+
points_array = vertices_array[unique_vertex_indices]
167+
points = [Gf.Vec3f(float(p[0]), float(p[1]), float(p[2])) for p in points_array]
169168

170-
# Remap to new indices
171-
face_vertex_indices = [vertex_index_map[old_idx] for old_idx in vertex_indices_in_shape]
169+
# Remap indices using NumPy searchsorted
170+
face_vertex_indices = np.searchsorted(unique_vertex_indices, vertex_indices_in_shape).tolist()
172171

173172
# Process normals
174173
normals = None
175174
if len(attrib.normals) > 0:
176-
normal_indices_in_shape = [idx.normal_index for idx in obj_mesh.indices]
177-
unique_normal_indices = sorted(set(normal_indices_in_shape))
178-
normal_index_map = {old_idx: new_idx for new_idx, old_idx in enumerate(unique_normal_indices)}
175+
normal_indices_in_shape = np.array(obj_mesh.normal_indices(), dtype=np.int32)
176+
unique_normal_indices = np.unique(normal_indices_in_shape)
179177

180-
normals_data = []
181-
for old_idx in unique_normal_indices:
182-
i = old_idx * 3
183-
normals_data.append(Gf.Vec3f(attrib.normals[i], attrib.normals[i + 1], attrib.normals[i + 2]))
178+
normals_array = np.array(attrib.normals, dtype=np.float32).reshape(-1, 3)
179+
normals_data_array = normals_array[unique_normal_indices]
180+
normals_data = [Gf.Vec3f(float(n[0]), float(n[1]), float(n[2])) for n in normals_data_array]
184181

185-
remapped_normal_indices = [normal_index_map[old_idx] for old_idx in normal_indices_in_shape]
182+
remapped_normal_indices = np.searchsorted(unique_normal_indices, normal_indices_in_shape).tolist()
186183
normals = usdex.core.Vec3fPrimvarData(UsdGeom.Tokens.faceVarying, Vt.Vec3fArray(normals_data), Vt.IntArray(remapped_normal_indices))
187184
normals.index() # re-index the normals to remove duplicates
188185

189186
# Process UV coordinates
190187
uvs = None
191188
if len(attrib.texcoords) > 0:
192-
texcoord_indices_in_shape = [idx.texcoord_index for idx in obj_mesh.indices]
193-
unique_texcoord_indices = sorted(set(texcoord_indices_in_shape))
194-
texcoord_index_map = {old_idx: new_idx for new_idx, old_idx in enumerate(unique_texcoord_indices)}
189+
texcoord_indices_in_shape = np.array(obj_mesh.texcoord_indices(), dtype=np.int32)
190+
unique_texcoord_indices = np.unique(texcoord_indices_in_shape)
195191

196-
uv_data = []
197-
for old_idx in unique_texcoord_indices:
198-
i = old_idx * 2
199-
uv_data.append(Gf.Vec2f(attrib.texcoords[i], attrib.texcoords[i + 1]))
192+
texcoords_array = np.array(attrib.texcoords, dtype=np.float32).reshape(-1, 2)
193+
uv_data_array = texcoords_array[unique_texcoord_indices]
194+
uv_data = [Gf.Vec2f(float(uv[0]), float(uv[1])) for uv in uv_data_array]
200195

201-
remapped_texcoord_indices = [texcoord_index_map[old_idx] for old_idx in texcoord_indices_in_shape]
196+
remapped_texcoord_indices = np.searchsorted(unique_texcoord_indices, texcoord_indices_in_shape).tolist()
202197
uvs = usdex.core.Vec2fPrimvarData(UsdGeom.Tokens.faceVarying, Vt.Vec2fArray(uv_data), Vt.IntArray(remapped_texcoord_indices))
203198
uvs.index() # re-index the uvs to remove duplicates
204199

0 commit comments

Comments
 (0)