CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-trimesh

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

Overview
Eval results
Files

mesh-processing.mddocs/

Mesh Processing and Modification

Advanced mesh processing capabilities including repair operations, boolean operations, remeshing, subdivision, and mesh quality improvement. These functions enable comprehensive mesh manipulation and enhancement workflows.

Capabilities

Boolean Operations

Perform CSG (Constructive Solid Geometry) operations between meshes.

def union(self, other, engine=None, check_volume=True, **kwargs) -> 'Trimesh':
    """
    Boolean union with another mesh.
    
    Parameters:
    - other: Trimesh object or sequence of Trimesh objects to union with
    - engine: str, boolean engine ('manifold' or 'blender')
    - check_volume: bool, check that all meshes are watertight volumes
    - **kwargs: boolean operation options
    
    Returns:
    New Trimesh object containing the union
    """

def intersection(self, other, engine=None, check_volume=True, **kwargs) -> 'Trimesh':
    """
    Boolean intersection with another mesh.
    
    Parameters:
    - other: Trimesh object or sequence of Trimesh objects to intersect with
    - engine: str, boolean engine ('manifold' or 'blender')
    - check_volume: bool, check that all meshes are watertight volumes
    - **kwargs: boolean operation options
    
    Returns:
    New Trimesh object containing the intersection
    """

def difference(self, other, engine=None, check_volume=True, **kwargs) -> 'Trimesh':
    """
    Boolean difference (subtraction) with another mesh.
    
    Parameters:
    - other: Trimesh object or sequence of Trimesh objects to subtract
    - engine: str, boolean engine ('manifold' or 'blender') 
    - check_volume: bool, check that all meshes are watertight volumes
    - **kwargs: boolean operation options
    
    Returns:
    New Trimesh object with other subtracted from self
    """

Mesh Repair and Healing

Fix common mesh problems and improve mesh quality.

def fix_normals(self) -> None:
    """Fix face winding order to ensure consistent normals"""

def fill_holes(self) -> bool:
    """
    Fill holes in the mesh surface.
    
    Returns:
    bool, True if holes were filled
    """


def remove_duplicate_faces(self) -> None:
    """Remove faces that are duplicated"""

def remove_degenerate_faces(self, height=1e-12) -> None:
    """
    Remove degenerate faces (zero area or invalid).
    
    Parameters:
    - height: float, minimum face area threshold
    """

def remove_unreferenced_vertices(self) -> None:
    """Remove vertices not referenced by any face"""

def merge_vertices(self, merge_tex=False, merge_norm=False, digits_vertex=None) -> None:
    """
    Merge vertices closer than tolerance.
    
    Parameters:
    - merge_tex: bool, merge texture coordinates
    - merge_norm: bool, merge vertex normals  
    - digits_vertex: int, decimal places for vertex precision
    """

def process(self, validate=True, merge_tex=False, merge_norm=False) -> None:
    """
    Apply standard mesh processing pipeline.
    
    Parameters:
    - validate: bool, run mesh validation
    - merge_tex: bool, merge texture coordinates
    - merge_norm: bool, merge vertex normals
    """

Remeshing and Subdivision

Modify mesh resolution and topology.

def subdivide(self, face_index=None) -> 'Trimesh':
    """
    Subdivide mesh faces to increase resolution.
    
    Parameters:
    - face_index: array of face indices to subdivide (None for all)
    
    Returns:
    New subdivided mesh
    """

def subdivide_loop(self, iterations=1) -> 'Trimesh':
    """
    Apply Loop subdivision for smooth surfaces.
    
    Parameters:
    - iterations: int, number of subdivision iterations
    
    Returns:
    Subdivided mesh with smooth surface
    """

def smoothed(self, **kwargs) -> 'Trimesh':
    """
    Return smoothed version using Laplacian smoothing.
    
    Parameters:
    - **kwargs: smoothing parameters
    
    Returns:
    Smoothed mesh
    """

def simplify_quadratic_decimation(self, face_count=None, **kwargs) -> 'Trimesh':
    """
    Simplify mesh using quadratic error decimation.
    
    Parameters:
    - face_count: int, target number of faces
    - **kwargs: decimation options
    
    Returns:
    Simplified mesh
    """

Convex Operations

Work with convex hulls and convex decomposition.

@property
def convex_hull(self) -> 'Trimesh':
    """Convex hull of the mesh vertices"""

def convex_decomposition(self, **kwargs) -> list:
    """
    Decompose mesh into convex components.
    
    Parameters:
    - **kwargs: decomposition parameters
    
    Returns:
    List of convex Trimesh objects
    """

def is_convex(self) -> bool:
    """Check if mesh is convex"""

Mesh Slicing and Sectioning

Cut meshes with planes and extract cross-sections.

def slice_plane(self, plane_normal, plane_origin, **kwargs):
    """
    Slice mesh with a plane.
    
    Parameters:
    - plane_normal: (3,) plane normal vector
    - plane_origin: (3,) point on plane
    - **kwargs: slicing options
    
    Returns:
    List of mesh pieces or cross-section paths
    """

def section(self, plane_normal, plane_origin) -> 'Path3D':
    """
    Get 2D cross-section of mesh at plane.
    
    Parameters:
    - plane_normal: (3,) plane normal vector
    - plane_origin: (3,) point on plane
    
    Returns:
    Path3D object representing cross-section
    """

def section_multiplane(self, plane_normal, plane_origins) -> list:
    """
    Get multiple parallel cross-sections.
    
    Parameters:
    - plane_normal: (3,) plane normal vector
    - plane_origins: (n, 3) points on planes
    
    Returns:
    List of Path3D cross-section objects
    """

Smoothing Operations

Apply various smoothing algorithms to improve mesh quality.

def smooth_laplacian(self, lamb=0.5, iterations=1, implicit_time_integration=False, volume_constraint=True) -> 'Trimesh':
    """
    Laplacian mesh smoothing.
    
    Parameters:
    - lamb: float, smoothing strength (0-1)
    - iterations: int, number of smoothing iterations
    - implicit_time_integration: bool, use implicit integration
    - volume_constraint: bool, preserve volume during smoothing
    
    Returns:
    Smoothed mesh
    """

def smooth_taubin(self, lamb=0.5, mu=-0.53, iterations=10) -> 'Trimesh':
    """
    Taubin smoothing (reduces shrinkage compared to Laplacian).
    
    Parameters:
    - lamb: float, positive smoothing factor
    - mu: float, negative smoothing factor
    - iterations: int, number of iterations
    
    Returns:
    Smoothed mesh
    """

Mesh Registration and Alignment

Align meshes to each other or to coordinate systems.

def register(self, other, samples=500, scale=False, icp_first=10, icp_final=50) -> tuple:
    """
    Register mesh to another using ICP algorithm.
    
    Parameters:
    - other: Trimesh to register to
    - samples: int, number of sample points
    - scale: bool, allow scaling transformation
    - icp_first: int, iterations for initial ICP
    - icp_final: int, iterations for final ICP
    
    Returns:
    tuple: (transform_matrix, cost, iterations)
    """

def rezero(self) -> 'Trimesh':
    """Center mesh at origin"""

def apply_obb(self) -> 'Trimesh':
    """Apply oriented bounding box transformation"""

def principal_inertia_transform(self) -> np.ndarray:
    """Get transformation matrix aligning to principal inertia axes"""

Mesh Generation and Modification

Create new mesh geometry and modify existing meshes.

def extrude_polygon(polygon, height, **kwargs) -> 'Trimesh':
    """
    Extrude 2D polygon to create 3D mesh.
    
    Parameters:
    - polygon: Path2D or (n, 2) polygon vertices
    - height: float, extrusion height
    - **kwargs: extrusion options
    
    Returns:
    Extruded Trimesh object
    """

def extrude_path(self, path, **kwargs) -> 'Trimesh':
    """
    Extrude mesh along path.
    
    Parameters:
    - path: Path3D or (n, 3) path points
    - **kwargs: extrusion options
    
    Returns:
    Extruded mesh
    """

def thicken(self, thickness, **kwargs) -> 'Trimesh':
    """
    Thicken surface mesh to create solid.
    
    Parameters:
    - thickness: float, thickness amount
    - **kwargs: thickening options
    
    Returns:
    Thickened solid mesh
    """

Usage Examples

Boolean Operations

import trimesh

# Create primitive shapes
box = trimesh.primitives.Box(extents=[2, 2, 2])
sphere = trimesh.primitives.Sphere(radius=1.5)
cylinder = trimesh.primitives.Cylinder(radius=0.5, height=3)

# Boolean operations
union_result = box.union(sphere)
intersection_result = box.intersection(sphere)
difference_result = box.difference(cylinder)

# Chain operations
complex_shape = box.union(sphere).difference(cylinder)

# Check results
print(f"Original box volume: {box.volume}")
print(f"Union volume: {union_result.volume}")
print(f"Intersection volume: {intersection_result.volume}")

Mesh Repair and Processing

# Load a potentially problematic mesh
mesh = trimesh.load('broken_model.stl')

print(f"Initial: {len(mesh.vertices)} vertices, {len(mesh.faces)} faces")
print(f"Is watertight: {mesh.is_watertight}")

# Apply repair operations
mesh.remove_duplicate_faces()
mesh.remove_degenerate_faces()
mesh.remove_unreferenced_vertices()
mesh.fill_holes()
mesh.fix_normals()

# Merge nearby vertices
mesh.merge_vertices()

# Full processing pipeline
mesh.process(validate=True)

print(f"After repair: {len(mesh.vertices)} vertices, {len(mesh.faces)} faces")
print(f"Is watertight: {mesh.is_watertight}")

Subdivision and Smoothing

# Load base mesh
mesh = trimesh.load('low_poly_model.obj')

# Subdivision for higher resolution
high_res = mesh.subdivide_loop(iterations=2)
print(f"Original: {len(mesh.faces)} faces")
print(f"After subdivision: {len(high_res.faces)} faces")

# Smoothing operations
laplacian_smooth = mesh.smooth_laplacian(lamb=0.6, iterations=5)
taubin_smooth = mesh.smooth_taubin(iterations=10)

# Compare results
mesh.show()  # Original
laplacian_smooth.show()  # Laplacian smoothed
taubin_smooth.show()  # Taubin smoothed

Mesh Slicing

import numpy as np

# Slice mesh with horizontal planes
plane_normal = np.array([0, 0, 1])  # Z-axis
plane_origins = np.array([[0, 0, z] for z in np.linspace(-1, 1, 10)])

# Get cross-sections
sections = mesh.section_multiplane(plane_normal, plane_origins)

# Export each section
for i, section in enumerate(sections):
    if section is not None:
        section.export(f'section_{i}.svg')

# Slice mesh in half
plane_origin = np.array([0, 0, 0])
pieces = mesh.slice_plane(plane_normal, plane_origin)
if len(pieces) == 2:
    pieces[0].export('bottom_half.stl')
    pieces[1].export('top_half.stl')

Mesh Registration

# Register two similar meshes
mesh1 = trimesh.load('scan1.ply')
mesh2 = trimesh.load('scan2.ply')

# Perform registration
transform, cost, iterations = mesh1.register(mesh2, samples=1000)

print(f"Registration cost: {cost}")
print(f"Iterations: {iterations}")

# Apply transformation
mesh1.apply_transform(transform)

# Check alignment quality
aligned_mesh = mesh1.copy()
distance = np.mean(aligned_mesh.nearest.vertex(mesh2.vertices)[1])
print(f"Mean distance after alignment: {distance}")

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