Mesh3D
SUMMARY
A triangle mesh in 3D space.
python
from telekinesis import datatypes
import numpy as np
mesh = datatypes.Mesh3D(np.array([[0, 0, 0], [1, 0, 0], [0, 1, 0]], dtype=np.float32))Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
vertex_positions | np.ndarray | list[list[float]] | list[float] | Required | Vertex coordinates with shape (N, 3). A (3,) value is accepted as one vertex, and empty input is allowed. |
triangle_indices | np.ndarray | list[list[int]] | None | None | Optional triangle vertex indices with shape (M, 3). Each index must be in the range [0, N). |
vertex_normals | np.ndarray | list[list[float]] | None | None | Optional per-vertex normals with shape (N, 3). |
vertex_colors | np.ndarray | list[list[int]] | list[list[float]] | None | None | Optional per-vertex colors. Accepts packed uint32 RGBA values with shape (N,), or RGB/RGBA channel values with shape (N, 3) or (N, 4). |
Raises
| Exception | Condition |
|---|---|
TypeError | An input can't be converted to its expected array type |
ValueError | vertex_positions/triangle_indices/vertex_normals isn't shape (N, 3)/(M, 3); triangle_indices references a vertex outside [0, N); vertex_normals/vertex_colors's length doesn't match N; or vertex_colors has an unsupported shape (not packed (N,) uint32, nor (N, 3)/(N, 4)) |
Attributes
| Attribute | Type | Description |
|---|---|---|
vertex_positions | np.ndarray | Defensive copy, shape (N, 3) float32. Read-only; Mesh3D instances are immutable after construction. |
triangle_indices | np.ndarray | None | Defensive copy, shape (M, 3) int32, or None. Read-only. |
vertex_normals | np.ndarray | None | Defensive copy, shape (N, 3) float32, or None. Read-only. |
vertex_colors | np.ndarray | None | Defensive copy of the packed RGBA colors, shape (N,) uint32 (0xRRGGBBAA), or None. Read-only. |
has_vertex_colors | bool | Whether vertex_colors is not None. |
has_vertex_normals | bool | Whether vertex_normals is not None. |
Methods
| Method | Type | Description |
|---|---|---|
Mesh3D.coerce(value) | Mesh3D | Converts array-like vertex positions into a Mesh3D. Accepts an array-like of shape (N, 3). If value is already a Mesh3D, it is returned unchanged. |
Mesh3D.from_path(path, compute_vertex_normals=False) | Mesh3D | Loads a mesh from disk (PLY, OBJ, STL, GLB, GLTF, and other formats trimesh supports). Multi-geometry scenes are concatenated into one mesh. Set compute_vertex_normals=True to compute normals when the file doesn't provide any. |
Mesh3D.from_url(url, *, cache_dir=None, use_cache=True, connect_timeout=5.0, read_timeout=30.0, compute_vertex_normals=False) | Mesh3D | Downloads a mesh file (or reuses a cached copy) and loads it the same way as from_path. |
copy() | Mesh3D | Returns a new, independent Mesh3D with the same vertex positions, triangle indices, normals, and colors. |
save_to_path(path) | None | Writes the mesh to disk; the on-disk format is inferred from the file extension (PLY, GLB, GLTF, STL, OBJ). |
Operators
| Operation | Behavior |
|---|---|
len(mesh) | Number of vertices N. |
mesh == other | True only if other is a Mesh3D with equal vertex_positions, triangle_indices (including presence), vertex_normals (including presence), and vertex_colors (including presence), each compared by value. NotImplemented if other isn't a Mesh3D. |
Visualization
python
import rerun as rr
# Your code block
# ....
rr.init("mesh3d_example", spawn=True)
datatypes.visualize(mesh, entity_path="/mesh", label="Mesh3D")Example
python
"""Demonstrates the Telekinesis Mesh3D datatype."""
import time
import numpy as np
import rerun as rr
from loguru import logger
from telekinesis import datatypes
def mesh3d_example():
"""Demonstrate creation, inspection, operations, visualization, and serialization."""
# ======================= Create ============================================
vertex_positions = np.array([[0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1]], dtype=np.float32)
triangle_indices = np.array([[0, 1, 2], [0, 1, 3], [0, 2, 3], [1, 2, 3]], dtype=np.int32)
vertex_normals = np.array([[0, 0, -1], [0, -1, 0], [-1, 0, 0], [1, 1, 1]], dtype=np.float32)
vertex_colors = np.array(
[[255, 0, 0, 255], [0, 255, 0, 255], [0, 0, 255, 255], [255, 255, 0, 255]],
dtype=np.uint8,
)
mesh = datatypes.Mesh3D(
vertex_positions=vertex_positions,
triangle_indices=triangle_indices,
vertex_normals=vertex_normals,
vertex_colors=vertex_colors,
)
logger.info(f"Created Mesh3D: {mesh}")
mesh_url = "https://assets.telekinesis.ai/examples/v1/meshes/gear_box.glb"
mesh_from_url = datatypes.Mesh3D.from_url(url=mesh_url, use_cache=True)
logger.info(f"Mesh3D created from URL: {mesh_from_url}")
# ======================= Inspect ===========================================
logger.info(f"vertex_positions={mesh.vertex_positions}")
logger.info(f"triangle_indices={mesh.triangle_indices}")
logger.info(f"vertex_normals={mesh.vertex_normals}")
logger.info(f"vertex_colors (packed RGBA uint32)={mesh.vertex_colors}")
logger.info(f"has_vertex_normals={mesh.has_vertex_normals}")
logger.info(f"has_vertex_colors={mesh.has_vertex_colors}")
logger.info(f"length={len(mesh)}")
# ======================= Operations =========================================
mesh_copy = mesh.copy()
logger.info(f"Copied Mesh3D: {mesh_copy}")
mesh.save_to_path("results/my_mesh_saved.ply")
logger.info("Saved Mesh3D to disk as a .ply file.")
mesh_from_path = datatypes.Mesh3D.from_path("results/my_mesh_saved.ply")
logger.info(f"Mesh3D loaded from .ply file: {mesh_from_path}")
# ======================= Visualize =========================================
rr.init("mesh3d_example", spawn=True)
datatypes.visualize(mesh, entity_path="/mesh3d", label="My Mesh3D")
# ======================= Serialize / Deserialize ===========================
start = time.perf_counter()
serialized = datatypes.serialize(mesh)
serialization_ms = (time.perf_counter() - start) * 1000
start = time.perf_counter()
deserialized = datatypes.deserialize(serialized)["param_0"]
deserialization_ms = (time.perf_counter() - start) * 1000
logger.info(f"Deserialized Mesh3D: {deserialized}")
logger.info(f"Round-trip successful: {mesh == deserialized}")
logger.info(f"Serialization time: {serialization_ms:.3f} ms")
logger.info(f"Deserialization time: {deserialization_ms:.3f} ms")
if __name__ == "__main__":
mesh3d_example()