|
14 | 14 | import os |
15 | 15 | import vtk |
16 | 16 | import json |
17 | | -from pxr import Usd, UsdGeom, Gf, Sdf |
| 17 | +from pxr import Usd, UsdGeom, Gf, Sdf, UsdShade |
18 | 18 | import trimesh |
19 | 19 | import numpy as np |
20 | 20 | import matplotlib.pyplot as plt |
| 21 | +import random |
| 22 | +import colorsys |
21 | 23 |
|
22 | 24 |
|
23 | 25 | def convert_to_mesh( |
@@ -186,30 +188,71 @@ def convert_mesh_to_usd(input_file, output_file): |
186 | 188 |
|
187 | 189 | # Create a new USD stage |
188 | 190 | stage = Usd.Stage.CreateNew(output_file) |
| 191 | + root = UsdGeom.Xform.Define(stage, "/World") |
| 192 | + stage.SetDefaultPrim(root.GetPrim()) |
| 193 | + materials_path = "/World/Materials" |
| 194 | + UsdGeom.Scope.Define(stage, materials_path) |
189 | 195 |
|
190 | 196 | # If the mesh is a Scene, process each geometry |
191 | 197 | if isinstance(mesh, trimesh.Scene): |
192 | | - for name, geometry in mesh.geometry.items(): |
193 | | - # Create a unique path for each mesh |
194 | | - mesh_path = f"/{name}" |
195 | | - usd_mesh = UsdGeom.Mesh.Define(stage, mesh_path) |
| 198 | + for node_name in mesh.graph.nodes: |
| 199 | + if node_name == "world": |
| 200 | + continue |
| 201 | + geom_name = mesh.graph.get(node_name)[1] |
| 202 | + if geom_name is not None and geom_name.startswith("mesh"): |
| 203 | + print(f"Processing mesh: {node_name} {geom_name}") |
| 204 | + # Create a unique path for each mesh |
| 205 | + node_path = f"/World/{node_name}" |
| 206 | + xform = UsdGeom.Xform.Define(stage, node_path) |
| 207 | + # Define the Mesh under the Xform |
| 208 | + mesh_path = f"{node_path}/Mesh" |
| 209 | + usd_mesh = UsdGeom.Mesh.Define(stage, mesh_path) |
| 210 | + # get the geometry of the node |
| 211 | + geometry = mesh.geometry[geom_name] |
| 212 | + |
| 213 | + # Create a random color for this mesh |
| 214 | + # Using HSV for better color distribution |
| 215 | + h = random.random() # Random hue |
| 216 | + s = 0.7 + 0.3 * random.random() # Saturation between 0.7-1.0 |
| 217 | + v = 0.7 + 0.3 * random.random() # Value between 0.7-1.0 |
| 218 | + r, g, b = colorsys.hsv_to_rgb(h, s, v) |
| 219 | + |
| 220 | + # Create a material with the random color |
| 221 | + mat_name = f"{node_name}_material" |
| 222 | + mat_path = f"{materials_path}/{mat_name}" |
| 223 | + material = UsdShade.Material.Define(stage, mat_path) |
| 224 | + |
| 225 | + # Create shader |
| 226 | + shader = UsdShade.Shader.Define(stage, f"{mat_path}/PreviewSurface") |
| 227 | + shader.CreateIdAttr("UsdPreviewSurface") |
| 228 | + |
| 229 | + # Set the random color |
| 230 | + shader.CreateInput("diffuseColor", Sdf.ValueTypeNames.Color3f).Set(Gf.Vec3f(r, g, b)) |
| 231 | + shader.CreateInput("roughness", Sdf.ValueTypeNames.Float).Set(0.4) |
| 232 | + |
| 233 | + # Connect shader to material |
| 234 | + material_output = material.CreateOutput("surface", Sdf.ValueTypeNames.Token) |
| 235 | + shader_output = shader.CreateOutput("surface", Sdf.ValueTypeNames.Token) |
| 236 | + material_output.ConnectToSource(shader_output) |
| 237 | + |
| 238 | + # Bind material to mesh |
| 239 | + UsdShade.MaterialBindingAPI(usd_mesh).Bind(material) |
| 240 | + |
| 241 | + # Set vertex positions |
| 242 | + usd_mesh.GetPointsAttr().Set([Gf.Vec3f(*vertex) for vertex in geometry.vertices]) |
| 243 | + |
| 244 | + # Set face indices and counts |
| 245 | + face_vertex_indices = geometry.faces.flatten().tolist() |
| 246 | + face_vertex_counts = [len(face) for face in geometry.faces] |
| 247 | + |
| 248 | + usd_mesh.GetFaceVertexIndicesAttr().Set(face_vertex_indices) |
| 249 | + usd_mesh.GetFaceVertexCountsAttr().Set(face_vertex_counts) |
| 250 | + |
| 251 | + # Optionally, set normals |
| 252 | + if geometry.vertex_normals is not None: |
| 253 | + usd_mesh.GetNormalsAttr().Set([Gf.Vec3f(*normal) for normal in geometry.vertex_normals]) |
| 254 | + usd_mesh.SetNormalsInterpolation("vertex") |
196 | 255 |
|
197 | | - # Set vertex positions |
198 | | - usd_mesh.GetPointsAttr().Set([Gf.Vec3f(*vertex) for vertex in geometry.vertices]) |
199 | | - |
200 | | - # Set face indices and counts |
201 | | - face_vertex_indices = geometry.faces.flatten().tolist() |
202 | | - face_vertex_counts = [len(face) for face in geometry.faces] |
203 | | - |
204 | | - usd_mesh.GetFaceVertexIndicesAttr().Set(face_vertex_indices) |
205 | | - usd_mesh.GetFaceVertexCountsAttr().Set(face_vertex_counts) |
206 | | - |
207 | | - # Optionally, set normals |
208 | | - if geometry.vertex_normals is not None: |
209 | | - usd_mesh.GetNormalsAttr().Set([Gf.Vec3f(*normal) for normal in geometry.vertex_normals]) |
210 | | - usd_mesh.SetNormalsInterpolation("vertex") |
211 | | - |
212 | | - # Handle materials and other attributes if needed |
213 | 256 | else: |
214 | 257 | # It's a single mesh, proceed as before |
215 | 258 | usd_mesh = UsdGeom.Mesh.Define(stage, "/Mesh") |
|
0 commit comments