Mesh

Triangle mesh geometry for RayD scenes

Overview#

Mesh is the basic geometry unit in RayD. It holds triangle vertex positions and face indices, optional UV coordinates, and a transform. Meshes are added to a Scene and cannot be shared across scenes.

import rayd as rd
import drjit as dr
 
rd.set_device(0)
 
mesh = rd.Mesh(
    dr.cuda.Array3f(
        [-1.0, 1.0, 1.0, -1.0],
        [-1.0, -1.0, 1.0, 1.0],
        [0.0, 0.0, 0.0, 0.0],
    ),
    dr.cuda.Array3i([0, 0], [1, 2], [2, 3]),
)

Constructor#

rd.Mesh(v, f, uv=None, f_uv=None, verbose=False)
ParameterTypeDescription
vArray3f or Array3fADVertex positions. Passing Array3fAD attaches gradients automatically
fArray3iFace indices. Each column is one triangle (v0, v1, v2)
uvArray2f | NoneOptional UV coordinates
f_uvArray3i | NoneOptional UV face indices
verboseboolEnable verbose build logging

Properties#

PropertyDescription
mesh.vertex_positionsGet or set vertex positions. Accepts Array3f or Array3fAD
mesh.vertex_positions_worldVertex positions after applying the to_world transform
mesh.vertex_normalsPer-vertex normals
mesh.vertex_uvGet or set UV coordinates
mesh.face_indicesGet or set face indices
mesh.face_uv_indicesGet or set UV face indices
mesh.to_worldGet or set the full world transform matrix
mesh.to_world_leftLeft factor of the transform
mesh.to_world_rightRight factor of the transform
mesh.use_face_normalsGet or set whether to use face normals instead of vertex normals
mesh.edges_enabledGet or set whether edge queries are enabled for this mesh
mesh.num_verticesNumber of vertices
mesh.num_facesNumber of faces

Methods#

mesh.build() — Build the mesh's internal acceleration structure. Call after construction before adding to a scene.

mesh.set_transform(mat, set_left=True) — Set the mesh transform matrix.

mesh.append_transform(mat, append_left=True) — Multiply the current transform by mat.

mesh.secondary_edges() — Return a SecondaryEdgeInfo object containing the mesh's secondary edges for edge sampling and nearest-edge queries.

mesh.edge_indices() — Return a tuple of five arrays containing edge index data.

Differentiable Vertices#

To differentiate through mesh geometry, pass an Array3fAD as vertex positions:

verts = dr.cuda.ad.Array3f(
    [0.0, 1.0, 0.0],
    [0.0, 0.0, 1.0],
    [0.0, 0.0, 0.0],
)
dr.enable_grad(verts)
 
mesh = rd.Mesh(
    dr.cuda.Array3f([0.0, 1.0, 0.0], [0.0, 0.0, 1.0], [0.0, 0.0, 0.0]),
    dr.cuda.Array3i([0], [1], [2]),
)
mesh.vertex_positions = verts

After scene.intersect(), call dr.backward(loss) to propagate gradients back to the vertex positions.

SecondaryEdgeInfo#

mesh.secondary_edges() returns a SecondaryEdgeInfo with:

FieldDescription
startEdge start positions
edgeEdge direction vectors
normal0, normal1Adjacent face normals
oppositeOpposite vertex positions
is_boundaryBoolean mask — True for boundary edges
edges = mesh.secondary_edges()
print("edge count =", edges.size())
boundary_count = sum(bool(v) for v in list(edges.is_boundary))
print("boundary edges =", boundary_count)

Next Steps#