CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-trimesh

Import, export, process, analyze and view triangular meshes.

Overview
Eval results
Files

visualization.mddocs/

Visualization and Rendering

Interactive 3D visualization, material and texture support, scene management, and integration with various rendering systems. Trimesh provides comprehensive tools for displaying, rendering, and exporting 3D content.

Capabilities

Interactive 3D Viewing

Display meshes and scenes in interactive 3D viewers.

def show(self, viewer=None, **kwargs) -> None:
    """
    Display mesh in interactive 3D viewer.
    
    Parameters:
    - viewer: str, viewer type ('gl', 'notebook', 'pyglet')
    - **kwargs: viewer-specific options like window size, lighting
    """

def scene(self) -> Scene:
    """
    Create Scene object containing this mesh.
    
    Returns:
    Scene object with mesh added
    """

class Scene:
    """Scene graph container for multiple geometries"""
    
    def show(self, viewer=None, **kwargs) -> None:
        """Display scene in interactive viewer"""
    
    def save_image(self, resolution=(1920, 1080), **kwargs) -> bytes:
        """
        Render scene to image.
        
        Parameters:
        - resolution: (width, height) image size
        - **kwargs: rendering options
        
        Returns:
        bytes, PNG image data
        """

Visual Properties and Materials

Control appearance through colors, materials, and textures.

@property
def visual(self):
    """Visual properties interface"""

class ColorVisuals:
    """Simple color-based visual properties"""
    
    @property
    def face_colors(self) -> np.ndarray:
        """
        Face colors as (m, 4) RGBA array.
        
        Returns:
        (m, 4) face colors in RGBA format
        """
    
    @face_colors.setter
    def face_colors(self, colors: np.ndarray) -> None:
        """Set face colors"""
    
    @property
    def vertex_colors(self) -> np.ndarray:
        """
        Vertex colors as (n, 4) RGBA array.
        
        Returns:
        (n, 4) vertex colors in RGBA format
        """
    
    @vertex_colors.setter
    def vertex_colors(self, colors: np.ndarray) -> None:
        """Set vertex colors"""

class TextureVisuals:
    """Texture-based visual properties"""
    
    @property
    def material(self):
        """Material properties object"""
    
    @property
    def uv(self) -> np.ndarray:
        """
        UV texture coordinates.
        
        Returns:
        (n, 2) UV coordinates for vertices
        """
    
    def copy(self) -> 'TextureVisuals':
        """Create copy of texture visuals"""

Scene Management

Manage complex scenes with multiple objects and transformations.

class Scene:
    """Scene graph for multiple geometries with transforms"""
    
    @property
    def geometry(self) -> dict:
        """Dictionary of geometry objects in scene"""
    
    @property
    def graph(self) -> dict:
        """Scene graph with transformation hierarchy"""
    
    @property
    def bounds(self) -> np.ndarray:
        """Combined bounds of all geometries"""
    
    @property
    def extents(self) -> np.ndarray:
        """Size of scene bounding box"""
    
    @property
    def centroid(self) -> np.ndarray:
        """Geometric center of scene"""
    
    def add_geometry(self, geometry, node_name=None, geom_name=None, parent_node_name=None, transform=None) -> str:
        """
        Add geometry to scene.
        
        Parameters:
        - geometry: Trimesh or other geometry object
        - node_name: str, name for scene graph node
        - geom_name: str, name for geometry object  
        - parent_node_name: str, parent node for hierarchy
        - transform: (4, 4) transformation matrix
        
        Returns:
        str, name of created node
        """
    
    def delete_geometry(self, names) -> None:
        """
        Remove geometry from scene.
        
        Parameters:
        - names: str or list of geometry names to remove
        """
    
    def set_camera_transform(self, transform=None, angles=None, distance=None, center=None) -> None:
        """
        Set camera position and orientation.
        
        Parameters:
        - transform: (4, 4) camera transformation matrix
        - angles: (3,) camera rotation angles
        - distance: float, distance from center
        - center: (3,) point to look at
        """

Lighting and Shading

Control lighting conditions and shading models.

def set_lights(self, lights=None) -> None:
    """
    Set scene lighting.
    
    Parameters:
    - lights: list of light dictionaries or None for default
    """

class DirectionalLight:
    """Directional light source"""
    def __init__(self, direction=[0, 0, -1], color=[1, 1, 1], intensity=1.0):
        """
        Parameters:
        - direction: (3,) light direction vector
        - color: (3,) RGB color
        - intensity: float, light intensity
        """

class PointLight:
    """Point light source"""
    def __init__(self, position=[0, 0, 0], color=[1, 1, 1], intensity=1.0):
        """
        Parameters:
        - position: (3,) light position
        - color: (3,) RGB color  
        - intensity: float, light intensity
        """

Export and Rendering

Export scenes and render to various formats.

def export(self, file_obj=None, file_type=None, **kwargs):
    """
    Export scene to file.
    
    Parameters:
    - file_obj: file path or file-like object
    - file_type: str, export format
    - **kwargs: format-specific options
    
    Returns:
    bytes if file_obj is None
    """

def save_image(self, resolution=(1920, 1080), visible=True, **kwargs) -> bytes:
    """
    Render scene to image.
    
    Parameters:
    - resolution: (width, height) pixel resolution
    - visible: bool, show viewer window during render
    - **kwargs: rendering options
    
    Returns:  
    bytes, PNG image data
    """

def to_gltf(self, merge_buffers=True, **kwargs) -> dict:
    """
    Convert scene to GLTF format.
    
    Parameters:
    - merge_buffers: bool, combine binary data
    - **kwargs: GLTF export options
    
    Returns:
    dict, GLTF scene data
    """

Jupyter Notebook Integration

Display meshes and scenes in Jupyter notebooks.

def scene_to_notebook(scene, height=500, **kwargs):
    """
    Display scene in Jupyter notebook.
    
    Parameters:
    - scene: Scene object to display
    - height: int, viewer height in pixels
    - **kwargs: notebook viewer options
    
    Returns:
    Interactive 3D widget for notebook
    """

def scene_to_html(scene, **kwargs) -> str:
    """
    Generate HTML for scene visualization.
    
    Parameters:
    - scene: Scene object
    - **kwargs: HTML generation options
    
    Returns:
    str, HTML content for 3D visualization
    """

def in_notebook() -> bool:
    """
    Check if running in Jupyter notebook.
    
    Returns:
    bool, True if in notebook environment
    """

Viewer Customization

Customize viewer appearance and behavior.

class SceneViewer:
    """Interactive OpenGL scene viewer"""
    
    def __init__(self, scene, start_loop=True, **kwargs):
        """
        Parameters:
        - scene: Scene object to display
        - start_loop: bool, start event loop immediately
        - **kwargs: viewer options
        """
    
    def save_image(self, filename=None) -> None:
        """Save current view as image"""
    
    def reset_view(self) -> None:
        """Reset camera to default position"""
    
    def on_key_press(self, symbol, modifiers) -> None:
        """Handle keyboard input"""
    
    def on_mouse_press(self, x, y, button, modifiers) -> None:
        """Handle mouse input"""

Color and Texture Utilities

Work with colors, textures, and visual materials.

def random_color() -> np.ndarray:
    """
    Generate random RGBA color.
    
    Returns:
    (4,) RGBA color array
    """

def interpolate_color(color_a, color_b, factor) -> np.ndarray:
    """
    Interpolate between two colors.
    
    Parameters:
    - color_a: (3,) or (4,) first color
    - color_b: (3,) or (4,) second color  
    - factor: float, interpolation factor (0-1)
    
    Returns:
    Interpolated color array
    """

def to_rgba(colors) -> np.ndarray:
    """
    Convert colors to RGBA format.
    
    Parameters:
    - colors: color array in various formats
    
    Returns:
    (n, 4) RGBA color array
    """

def vertex_colors_from_face_colors(mesh, face_colors) -> np.ndarray:
    """
    Convert face colors to vertex colors by averaging.
    
    Parameters:
    - mesh: Trimesh object
    - face_colors: (m, 3) or (m, 4) face colors
    
    Returns:
    (n, 4) vertex colors
    """

Usage Examples

Basic Visualization

import trimesh
import numpy as np

# Load and display mesh
mesh = trimesh.load('model.stl')
mesh.show()  # Opens interactive 3D viewer

# Create scene with multiple objects
scene = trimesh.Scene()

# Add meshes to scene
box = trimesh.primitives.Box(extents=[1, 1, 1])
sphere = trimesh.primitives.Sphere(radius=0.5)

# Position objects with transforms
box_transform = trimesh.transformations.translation_matrix([2, 0, 0])
sphere_transform = trimesh.transformations.translation_matrix([-2, 0, 0])

scene.add_geometry(box, transform=box_transform)
scene.add_geometry(sphere, transform=sphere_transform)
scene.add_geometry(mesh)  # At origin

# Display scene
scene.show()

Colors and Materials

# Set solid colors
mesh.visual.face_colors = [255, 0, 0, 255]  # Red faces
mesh.visual.vertex_colors = np.random.randint(0, 255, (len(mesh.vertices), 4))  # Random vertex colors

# Color faces by height
face_centers = mesh.triangles_center
heights = face_centers[:, 2]  # Z-coordinates
normalized_heights = (heights - heights.min()) / (heights.max() - heights.min())

# Create color map
import matplotlib.pyplot as plt
colors = plt.cm.viridis(normalized_heights)
mesh.visual.face_colors = (colors * 255).astype(np.uint8)

mesh.show()

# Color vertices by curvature
if hasattr(mesh, 'discrete_mean_curvature_measure'):
    curvature = mesh.discrete_mean_curvature_measure()
    curvature_normalized = (curvature - curvature.min()) / (curvature.max() - curvature.min())
    
    curvature_colors = plt.cm.coolwarm(curvature_normalized)
    mesh.visual.vertex_colors = (curvature_colors * 255).astype(np.uint8)
    mesh.show()

Scene Management

# Create complex scene
scene = trimesh.Scene()

# Add multiple geometries with different materials
geometries = [
    (trimesh.primitives.Box(extents=[1, 1, 1]), [1, 0, 0], [0, 0, 0]),      # Red box at origin
    (trimesh.primitives.Sphere(radius=0.7), [0, 1, 0], [3, 0, 0]),         # Green sphere
    (trimesh.primitives.Cylinder(radius=0.5, height=2), [0, 0, 1], [0, 3, 0]),  # Blue cylinder
]

for geom, color, position in geometries:
    # Set color
    geom.visual.face_colors = color + [1.0]  # Add alpha
    
    # Create transform
    transform = trimesh.transformations.translation_matrix(position)
    
    # Add to scene
    scene.add_geometry(geom, transform=transform)

# Set camera position
scene.set_camera_transform(
    distance=10,
    center=[1.5, 1.5, 0],
    angles=[np.pi/6, np.pi/4, 0]
)

# Display scene
scene.show()

# Save scene as image
image_data = scene.save_image(resolution=(1920, 1080))
with open('scene_render.png', 'wb') as f:
    f.write(image_data)

Custom Lighting

# Create scene with custom lighting
scene = trimesh.Scene([mesh])

# Define multiple light sources
lights = [
    {
        'type': 'DirectionalLight',
        'direction': [1, -1, -1],
        'color': [1.0, 1.0, 1.0],
        'intensity': 0.8
    },
    {
        'type': 'DirectionalLight', 
        'direction': [-1, 1, 0.5],
        'color': [0.8, 0.9, 1.0],  # Slightly blue
        'intensity': 0.4
    },
    {
        'type': 'PointLight',
        'position': [0, 0, 5],
        'color': [1.0, 0.8, 0.6],  # Warm color
        'intensity': 0.6
    }
]

scene.set_lights(lights)
scene.show()

Jupyter Notebook Visualization

# In Jupyter notebook
import trimesh
from trimesh.viewer import scene_to_notebook

# Create scene
mesh = trimesh.load('model.stl')
scene = mesh.scene()

# Display in notebook with custom height
scene_to_notebook(scene, height=600)

# Or generate HTML for embedding
html_content = trimesh.viewer.scene_to_html(scene)
from IPython.display import HTML
HTML(html_content)

Advanced Visualization Techniques

# Transparency and advanced materials
mesh.visual.face_colors = [128, 128, 255, 100]  # Semi-transparent blue

# Wireframe visualization  
edges = mesh.edges_unique
edge_viz = trimesh.load_path(mesh.vertices[edges])
edge_viz.colors = [255, 255, 255, 255]  # White edges

# Combine mesh and wireframe in scene
scene = trimesh.Scene([mesh, edge_viz])
scene.show()

# Vertex highlighting
# Find boundary vertices (if mesh has boundary)
boundary_edges = mesh.edges[mesh.face_adjacency_edges[mesh.face_adjacency_unshared]]
boundary_vertices = np.unique(boundary_edges)

# Create vertex color array
vertex_colors = np.full((len(mesh.vertices), 4), [200, 200, 200, 255])  # Gray default
vertex_colors[boundary_vertices] = [255, 0, 0, 255]  # Red boundary vertices

mesh.visual.vertex_colors = vertex_colors
mesh.show()

# Normal visualization
face_centers = mesh.triangles_center
face_normals = mesh.face_normals
normal_length = 0.1

# Create line segments for normals
normal_lines = []
for center, normal in zip(face_centers, face_normals):
    normal_lines.extend([center, center + normal * normal_length])

normal_path = trimesh.load_path(np.array(normal_lines).reshape(-1, 3))
normal_path.colors = [0, 255, 0, 255]  # Green normals

# Show mesh with normals
scene = trimesh.Scene([mesh, normal_path])
scene.show()

Export and Rendering

# Render high-quality images
scene = mesh.scene()

# Set up professional lighting
scene.set_lights([
    {'type': 'DirectionalLight', 'direction': [1, -1, -1], 'intensity': 0.8},
    {'type': 'DirectionalLight', 'direction': [-1, 1, 0.5], 'intensity': 0.3},
])

# Render at different resolutions
resolutions = [(1920, 1080), (3840, 2160), (1024, 1024)]
for i, res in enumerate(resolutions):
    image_data = scene.save_image(resolution=res)
    with open(f'render_{res[0]}x{res[1]}.png', 'wb') as f:
        f.write(image_data)

# Export scene to various formats
scene.export('scene.gltf')  # GLTF with materials
scene.export('scene.obj')   # OBJ format
scene.export('scene.dae')   # COLLADA format

# Export to web-friendly format
gltf_data = scene.to_gltf(merge_buffers=True)
import json
with open('scene_web.gltf', 'w') as f:
    json.dump(gltf_data, f, indent=2)

Install with Tessl CLI

npx tessl i tessl/pypi-trimesh

docs

advanced-features.md

analysis.md

core-operations.md

file-io.md

index.md

mesh-processing.md

point-clouds.md

spatial-queries.md

visualization.md

tile.json