|
2 | 2 | # SPDX-License-Identifier: Apache-2.0 |
3 | 3 | import pathlib |
4 | 4 |
|
| 5 | +import numpy as np |
5 | 6 | import stl |
6 | 7 | import tinyobjloader |
7 | 8 | import usdex.core |
@@ -154,51 +155,45 @@ def convert_obj(prim: Usd.Prim, input_path: pathlib.Path, data: ConversionData) |
154 | 155 | obj_mesh = shape.mesh |
155 | 156 | face_vertex_counts = obj_mesh.num_face_vertices |
156 | 157 |
|
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) |
160 | 160 |
|
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) |
163 | 163 |
|
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] |
169 | 168 |
|
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() |
172 | 171 |
|
173 | 172 | # Process normals |
174 | 173 | normals = None |
175 | 174 | 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) |
179 | 177 |
|
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] |
184 | 181 |
|
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() |
186 | 183 | normals = usdex.core.Vec3fPrimvarData(UsdGeom.Tokens.faceVarying, Vt.Vec3fArray(normals_data), Vt.IntArray(remapped_normal_indices)) |
187 | 184 | normals.index() # re-index the normals to remove duplicates |
188 | 185 |
|
189 | 186 | # Process UV coordinates |
190 | 187 | uvs = None |
191 | 188 | 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) |
195 | 191 |
|
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] |
200 | 195 |
|
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() |
202 | 197 | uvs = usdex.core.Vec2fPrimvarData(UsdGeom.Tokens.faceVarying, Vt.Vec2fArray(uv_data), Vt.IntArray(remapped_texcoord_indices)) |
203 | 198 | uvs.index() # re-index the uvs to remove duplicates |
204 | 199 |
|
|
0 commit comments