Skip to content

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))
API Reference
Complete API documentation for Mesh3D, including parameters, attributes, and methods.
View Reference →

Parameters

ParameterTypeDefaultDescription
vertex_positionsnp.ndarray | list[list[float]] | list[float]RequiredVertex coordinates with shape (N, 3). A (3,) value is accepted as one vertex, and empty input is allowed.
triangle_indicesnp.ndarray | list[list[int]] | NoneNoneOptional triangle vertex indices with shape (M, 3). Each index must be in the range [0, N).
vertex_normalsnp.ndarray | list[list[float]] | NoneNoneOptional per-vertex normals with shape (N, 3).
vertex_colorsnp.ndarray | list[list[int]] | list[list[float]] | NoneNoneOptional per-vertex colors. Accepts packed uint32 RGBA values with shape (N,), or RGB/RGBA channel values with shape (N, 3) or (N, 4).

Raises

ExceptionCondition
TypeErrorAn input can't be converted to its expected array type
ValueErrorvertex_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

AttributeTypeDescription
vertex_positionsnp.ndarrayDefensive copy, shape (N, 3) float32. Read-only; Mesh3D instances are immutable after construction.
triangle_indicesnp.ndarray | NoneDefensive copy, shape (M, 3) int32, or None. Read-only.
vertex_normalsnp.ndarray | NoneDefensive copy, shape (N, 3) float32, or None. Read-only.
vertex_colorsnp.ndarray | NoneDefensive copy of the packed RGBA colors, shape (N,) uint32 (0xRRGGBBAA), or None. Read-only.
has_vertex_colorsboolWhether vertex_colors is not None.
has_vertex_normalsboolWhether vertex_normals is not None.

Methods

MethodTypeDescription
Mesh3D.coerce(value)Mesh3DConverts 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)Mesh3DLoads 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)Mesh3DDownloads a mesh file (or reuses a cached copy) and loads it the same way as from_path.
copy()Mesh3DReturns a new, independent Mesh3D with the same vertex positions, triangle indices, normals, and colors.
save_to_path(path)NoneWrites the mesh to disk; the on-disk format is inferred from the file extension (PLY, GLB, GLTF, STL, OBJ).

Operators

OperationBehavior
len(mesh)Number of vertices N.
mesh == otherTrue 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()