Skip to content

Get Visual Meshes Data

SUMMARY

Get Visual Meshes Data returns all of the robot's visual mesh data as a single composed dictionary keyed by link name. Each entry packs the raw NumPy arrays - vertices, triangle indices, per-vertex normals, per-vertex RGBA colors - along with the URDF <visual><origin> offset and declared material color, so any downstream renderer can be fed straight from this one call.

SUPPORTED ROBOTS

Available on all supported manipulators.

The Skill

python
meshes = robot.get_visual_meshes_data()

The Code

python
"""
Read per-link visual mesh data (vertices/triangles/normals) for the Synapse SDK.

``get_visual_meshes_data`` parses the robot's URDF and returns raw
vertex/triangle/normal arrays ready for visualizers.

Universal Robots (UR10e) is used here purely for illustration. It supports all robots.

Usage:
    python get_visual_meshes_data.py
"""

from loguru import logger

from telekinesis.synapse.robots.manipulators import universal_robots


def main():
    """Read per-link visual mesh data and log a summary per link."""

    # Create the robot (no connect required — runs on the kinematic model)
    robot = universal_robots.UniversalRobotsUR10E()

    # Read per-link visual mesh data
    meshes = robot.get_visual_meshes_data()
    logger.info(f"Number of links: {len(meshes)}")

    # Log a shape summary per link (vertices / triangles / colors)
    for link_name, mesh in meshes.items():
        if mesh["vertices"] is None:
            logger.warning(f"{link_name}: no visual mesh")
            continue
        n_vertices = mesh["vertices"].shape[0]
        n_triangles = mesh["triangles"].shape[0]
        has_colors = mesh["vertex_colors"] is not None
        logger.success(
            f"{link_name}: vertices={n_vertices}, triangles={n_triangles}, "
            f"vertex_colors={has_colors}, mesh_origin={mesh['mesh_origin']}"
        )


if __name__ == "__main__":
    main()

The Explanation of the Code

python
from telekinesis.synapse.robots.manipulators import universal_robots

robot = universal_robots.UniversalRobotsUR10E()

Create the robot. UR10e is used here for illustration; the same pattern works for every supported brand. No connect() is required - runs against the kinematic model.

python
meshes = robot.get_visual_meshes_data()

Parse the URDF and return {link_name: dict} with raw vertices / triangles / vertex_normals / vertex_colors NumPy arrays, plus the URDF <visual><origin> mesh offset and declared material color. Each entry can be fed straight into a renderer.

python
for link_name, mesh in meshes.items():
    if mesh["vertices"] is None:
        logger.warning(f"{link_name}: no visual mesh")
        continue
    n_vertices = mesh["vertices"].shape[0]
    n_triangles = mesh["triangles"].shape[0]

Links without a usable mesh return vertices=None - guard for that case before reading shapes. The arrays are in the link's mesh frame; compose them with Get Visual Mesh Transforms for world-space rendering.

Return Value

dict[str, dict] keyed by link name. Each entry has:

KeyTypeDescription
verticesnp.ndarray(N, 3) | NoneVertex positions in the mesh frame. None when the link has no usable mesh.
trianglesnp.ndarray(M, 3) | NoneTriangle indices into vertices.
vertex_normalsnp.ndarray(N, 3) | NoneSmooth per-vertex normals.
vertex_colorsnp.ndarray(N, 4) uint8 | NonePer-vertex RGBA, baked from .dae materials when available.
mesh_origin(xyz, rpy)URDF <visual><origin> offset (zero vectors when absent).
color[r, g, b] 0-255 | NoneRGB color from the URDF <material> tag.

Result is cached on the first call. Supported mesh formats: .dae, .stl, .obj, .ply.

Where to Use the Skill

  • Visualization - Feed the arrays directly to any renderer expecting per-vertex arrays. Pair with Get Visual Mesh Transforms for the world poses.
  • Digital twin - Send geometry once at startup, then stream only updated link poses.
  • URDF auditing - Programmatically verify which links ship with visual meshes and what colors are declared.

When Not to Use the Skill

  • You only need link poses - call Get Link Transforms to skip mesh loading entirely.
  • Trimesh is not installed - the first call raises ImportError. Install with pip install trimesh>=4.0 pycollada>=0.7.