Mesh (Dr.Jit)

rayd.drjit.Mesh - triangle mesh construction, vertex and UV attributes, transforms, normals, edge extraction, and per-mesh edge data.

rayd.drjit.Mesh holds one triangle mesh: vertex positions, faces, optional UVs, and a world transform. Add it to a Scene to query it.

Mesh#

Mesh()
Mesh(
    v: drjit.cuda.Array3f | drjit.cuda.ad.Array3f,
    f: drjit.cuda.Array3i,
    uv: drjit.cuda.Array2f | drjit.cuda.ad.Array2f = [],
    f_uv: drjit.cuda.Array3i = [],
    verbose: bool = False,
)

Creates a mesh from vertex and face arrays.

vArray3frequired

Vertex positions in object space. Pass a drjit.cuda.ad.Array3f to keep the mesh differentiable with respect to the positions.

fdrjit.cuda.Array3irequired

Triangles as three vertex indices each.

uvArray2fdefault []

Optional per-vertex texture coordinates. An AD array keeps UVs differentiable.

f_uvdrjit.cuda.Array3idefault []

Optional per-face UV indices, when UVs are indexed separately from positions.

verbosebooldefault False

Print diagnostic information while the mesh is created.

import rayd.drjit as rd
from drjit.cuda import Array3f, Array3i
 
mesh = rd.Mesh(Array3f([0, 1, 1, 0], [0, 0, 1, 1], [0, 0, 0, 0]),
               Array3i([0, 0], [1, 2], [2, 3]))
print(mesh.num_vertices, mesh.num_faces)   # 4 2

A Scene stores a copy of the mesh when you call add_mesh. Later changes to the Mesh object do not reach the scene; use Scene.update_mesh_vertices or Scene.set_mesh_transform instead.

Methods#

build#

build() -> None

Computes the mesh's derived data: world-space vertices, normals, and the edge list. Scene.build() does this for every mesh, so you only call it to inspect a mesh before it joins a scene, for example before secondary_edges().

set_transform#

set_transform(mat: drjit.cuda.ad.Matrix4f, set_left: bool = True) -> None

Replaces the left transform factor (set_left=True) or the right factor (set_left=False).

matdrjit.cuda.ad.Matrix4frequired

4x4 transform with column vectors (p_world = M @ p). An AD matrix makes the transform differentiable.

set_leftbooldefault True

Which factor to replace.

append_transform#

append_transform(mat: drjit.cuda.ad.Matrix4f, append_left: bool = True) -> None

Multiplies mat onto the left factor (append_left=True) or the right factor.

edge_indices#

edge_indices() -> tuple

Returns the mesh's unique edges as a 5-tuple of Int arrays: (vertex0, vertex1, face0, face1, opposite_vertex). face1 is -1 for a boundary edge. Call build() first.

secondary_edges#

secondary_edges() -> SecondaryEdgeInfo

Returns the world-space edge data of a built mesh. SecondaryEdgeInfo has start, edge (the edge vector), normal0, normal1 (adjacent face normals), opposite (the opposite vertex), is_boundary, and size().

mesh.build()
edges = mesh.secondary_edges()
print(edges.size(), edges.is_boundary)   # 5 [True, False, True, True, True]
print(mesh.edge_indices()[3])            # face1: [-1, 1, -1, -1, -1]

Properties#

PropertyTypeAccessMeaning
num_verticesintreadvertex count
num_facesintreadtriangle count
vertex_positionsad.Array3fread/writeobject-space positions
vertex_positions_worldad.Array3freadworld-space positions after the transform
vertex_normalsad.Array3freadper-vertex normals
vertex_uvad.Array2fread/writetexture coordinates
face_indicesArray3iread/writetriangles
face_uv_indicesArray3iread/writeper-face UV indices
to_worldad.Matrix4fread/writemiddle transform factor
to_world_left, to_world_rightad.Matrix4fread/writeouter transform factors
use_face_normalsboolread/writeshade with face normals instead of interpolated vertex normals (default False)
edges_enabledboolread/writeinclude this mesh's edges in the scene edge set (default True)

The world transform is to_world_left @ to_world @ to_world_right. All three default to the identity.