Importing a procedurally generated mesh into Isaac Sim

Hi,

I am trying to procedurally generate meshes and add them to IsaacSim. Is there a way to programmatically do this? Note that I don’t need the asset to be in an instanceable format. I tried to use the following piece of code

          mesh_data = ProcMesh(cfg)
          stage = get_current_stage()
          mesh = stage.DefinePrim("/World/proc_mesh", "Mesh")
          mesh.GetAttribute("points").Set(mesh_data.vertices)
          mesh.GetAttribute("faceVertexIndices").Set(mesh_data.triangles.flatten())
          mesh.GetAttribute("faceVertexCounts").Set(np.asarray([3] * mesh_data.triangles.shape[1]))
          
          mesh_prim = XFormPrim(prim_path="/World/proc_mesh",
                                name="proc_mesh",
                                position=None,
                                orientation=None)

          UsdPhysics.CollisionAPI.Apply(mesh_prim.prim)
          physx_collision_api = PhysxSchema.PhysxCollisionAPI.Apply(mesh_prim.prim)
          physx_collision_api.GetContactOffsetAttr().Set(0.02)
          physx_collision_api.GetRestOffsetAttr().Set(0.00)

This runs without errors. However, I don’t see the corresponding mesh in the viewer when it launches. Note that I do see that a mesh exists in the scene hierarchy panel, but it does not appear in the viewer and other objects do not collide with it.

Is there some additional step required to make this work?

Hi @ananyea1 - In order to create a mesh programmatically in Isaac Sim, you need to define the mesh attributes such as points, faceVertexIndices, and faceVertexCounts. However, you also need to define the normals and texture coordinates for the mesh to be visible in the viewer.

Here is an example of how you can create a mesh programmatically:

from pxr import Usd, UsdGeom, Vt, Gf

stage = Usd.Stage.CreateNew('test.usda')

mesh = UsdGeom.Mesh.Define(stage, '/World/proc_mesh')

# Define points for a simple triangle
points = Vt.Vec3fArray(3)
points[0] = Gf.Vec3f(0, 0, 0)
points[1] = Gf.Vec3f(0, 1, 0)
points[2] = Gf.Vec3f(1, 0, 0)

# Define face indices
faceIndices = Vt.IntArray(3)
faceIndices[0] = 0
faceIndices[1] = 1
faceIndices[2] = 2

# Define face counts
faceCounts = Vt.IntArray(1)
faceCounts[0] = 3

mesh.CreatePointsAttr(points)
mesh.CreateFaceVertexCountsAttr(faceCounts)
mesh.CreateFaceVertexIndicesAttr(faceIndices)

# Define normals
normals = Vt.Vec3fArray(3)
normals[0] = Gf.Vec3f(0, 0, 1)
normals[1] = Gf.Vec3f(0, 0, 1)
normals[2] = Gf.Vec3f(0, 0, 1)

mesh.CreateNormalsAttr(normals)

# Define texture coordinates
texCoords = Vt.Vec2fArray(3)
texCoords[0] = Gf.Vec2f(0, 0)
texCoords[1] = Gf.Vec2f(0, 1)
texCoords[2] = Gf.Vec2f(1, 0)

texCoordsAttr = UsdGeom.TexCoordSource.Create(mesh, 'st', texCoords)

stage.GetRootLayer().Save()

This script creates a new USD stage, defines a mesh with a single triangle, and sets the points, face indices, face counts, normals, and texture coordinates for the mesh. The mesh is then saved to a USD file named ‘test.usda’.

Please note that this script does not apply any physics or collision properties to the mesh. You would need to use the UsdPhysics and PhysxSchema APIs to apply these properties as needed for your application.

Also, please ensure that the normals and texture coordinates are correctly defined for your mesh. Incorrect normals or texture coordinates could cause the mesh to be invisible or not render correctly in the viewer.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.