CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-trimesh

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

Overview
Eval results
Files

analysis.mddocs/

Analysis and Measurement

Comprehensive geometric analysis including mass properties, curvature analysis, mesh quality metrics, inertia calculations, and geometric measurements. These tools enable detailed mesh characterization and engineering analysis.

Capabilities

Mass Properties and Inertia

Calculate physical properties assuming uniform density.

@property
def mass_properties(self) -> dict:
    """
    Calculate mass properties including center of mass and inertia tensor.
    
    Returns:
    dict with keys:
    - 'volume': float, mesh volume
    - 'mass': float, mass (volume * density)
    - 'density': float, material density
    - 'center_mass': (3,) center of mass
    - 'inertia': (3, 3) inertia tensor
    """

@property
def moment_inertia(self) -> np.ndarray:
    """
    Moment of inertia tensor around center of mass.
    
    Returns:
    (3, 3) inertia tensor matrix
    """

@property
def principal_inertia_components(self) -> np.ndarray:
    """
    Principal moments of inertia (eigenvalues of inertia tensor).
    
    Returns:
    (3,) principal inertia values in ascending order
    """

@property
def principal_inertia_vectors(self) -> np.ndarray:
    """
    Principal inertia axes (eigenvectors of inertia tensor).
    
    Returns:
    (3, 3) matrix where columns are principal axes
    """

@property
def center_mass(self) -> np.ndarray:
    """
    Center of mass (volume-weighted centroid).
    
    Returns:
    (3,) center of mass coordinates
    """

Surface Curvature Analysis

Analyze mesh curvature properties and surface characteristics.

def discrete_gaussian_curvature_measure(self) -> np.ndarray:
    """
    Discrete Gaussian curvature at each vertex.
    
    Returns:
    (n,) Gaussian curvature values at vertices
    """

def discrete_mean_curvature_measure(self) -> np.ndarray:
    """
    Discrete mean curvature at each vertex.
    
    Returns:
    (n,) mean curvature values at vertices
    """

def vertex_defects(self) -> np.ndarray:
    """
    Angular defect at each vertex (2π - sum of incident angles).
    
    Returns:
    (n,) angular defects at vertices
    """

def face_angles(self) -> np.ndarray:
    """
    Interior angles of each face.
    
    Returns:
    (m, 3) angles for each face corner
    """

def face_angles_sparse(self) -> np.ndarray:
    """
    Sparse representation of face angles.
    
    Returns:
    (3*m,) flattened face angles
    """

Geometric Measurements

Basic geometric properties and measurements.

@property
def area(self) -> float:
    """Total surface area"""

@property
def area_faces(self) -> np.ndarray:
    """
    Surface area of each face.
    
    Returns:
    (m,) area values for each face
    """

@property
def volume(self) -> float:
    """
    Mesh volume (positive for watertight meshes).
    
    Returns:
    float, volume value
    """

@property
def bounds(self) -> np.ndarray:
    """
    Axis-aligned bounding box.
    
    Returns:
    (2, 3) array: [[min_x, min_y, min_z], [max_x, max_y, max_z]]
    """

@property
def extents(self) -> np.ndarray:
    """
    Size in each dimension.
    
    Returns:
    (3,) array: [width, height, depth]
    """

@property
def scale(self) -> float:
    """Scaling factor relative to unit cube"""

@property
def centroid(self) -> np.ndarray:
    """
    Geometric centroid (average of vertices).
    
    Returns:
    (3,) centroid coordinates
    """

Mesh Quality Metrics

Analyze mesh quality and identify potential issues.

@property
def euler_number(self) -> int:
    """
    Euler characteristic (V - E + F).
    
    Returns:
    int, Euler number (2 for closed surfaces)
    """

@property
def is_watertight(self) -> bool:
    """True if mesh is watertight (manifold and closed)"""

@property
def is_winding_consistent(self) -> bool:
    """True if face winding is consistent"""

@property
def is_volume(self) -> bool:
    """True if mesh encloses a volume"""

@property
def face_adjacency(self) -> np.ndarray:
    """
    Face adjacency matrix.
    
    Returns:
    (m, m) sparse matrix showing face connectivity
    """

@property
def face_adjacency_edges(self) -> np.ndarray:
    """
    Edges between adjacent faces.
    
    Returns:
    (p, 2) array of face indices sharing edges
    """

def face_adjacency_convex(self, tolerance=0.0) -> np.ndarray:
    """
    Check if adjacent faces form convex angles.
    
    Parameters:
    - tolerance: float, angle tolerance
    
    Returns:
    (p,) boolean array indicating convex adjacencies
    """

def face_normals_from_vertices(self) -> np.ndarray:
    """
    Calculate face normals from vertex positions.
    
    Returns:
    (m, 3) face normal vectors
    """

Statistical Analysis

Compute statistical properties of mesh geometry.

def vertex_degree(self) -> np.ndarray:
    """
    Number of faces incident to each vertex.
    
    Returns:
    (n,) vertex degrees
    """

def edge_lengths(self) -> np.ndarray:
    """
    Length of each unique edge.
    
    Returns:
    (e,) edge length values
    """

def edge_lengths_histogram(self, bins=20) -> tuple:
    """
    Histogram of edge lengths.
    
    Parameters:
    - bins: int, number of histogram bins
    
    Returns:
    tuple: (counts, bin_edges)
    """

def face_areas_histogram(self, bins=20) -> tuple:
    """
    Histogram of face areas.
    
    Parameters:
    - bins: int, number of histogram bins
    
    Returns:
    tuple: (counts, bin_edges)
    """

Mesh Comparison and Metrics

Compare meshes and compute similarity metrics.

def hausdorff_distance(self, other) -> float:
    """
    Hausdorff distance to another mesh.
    
    Parameters:
    - other: Trimesh object
    
    Returns:
    float, maximum distance between meshes
    """

def symmetric_difference_volume(self, other) -> float:
    """
    Volume of symmetric difference with another mesh.
    
    Parameters:
    - other: Trimesh object
    
    Returns:
    float, volume of non-overlapping regions
    """

def difference_volume(self, other) -> float:
    """
    Volume difference with another mesh.
    
    Parameters:
    - other: Trimesh object
    
    Returns:
    float, volume difference
    """

Advanced Geometric Analysis

Specialized geometric analysis functions.

def integral_gaussian_curvature(self) -> float:
    """
    Total Gaussian curvature (should equal 4π for closed surfaces).
    
    Returns:
    float, integrated Gaussian curvature
    """

def integral_mean_curvature(self) -> float:
    """
    Total mean curvature over surface.
    
    Returns:
    float, integrated mean curvature
    """

def sphericity(self) -> float:
    """
    Sphericity measure (how sphere-like the mesh is).
    
    Returns:
    float, sphericity value (1.0 for perfect sphere)
    """

def compactness(self) -> float:
    """
    Compactness measure (surface area vs volume ratio).
    
    Returns:  
    float, compactness value
    """

Usage Examples

Mass Properties Analysis

import trimesh
import numpy as np

# Load mesh
mesh = trimesh.load('part.stl')

# Set material density (kg/m³)
mesh.density = 7850  # Steel density

# Get complete mass properties
props = mesh.mass_properties
print(f"Volume: {props['volume']:.6f} m³")
print(f"Mass: {props['mass']:.3f} kg") 
print(f"Center of mass: {props['center_mass']}")
print(f"Inertia tensor:\n{props['inertia']}")

# Principal inertia analysis
principal_values = mesh.principal_inertia_components
principal_vectors = mesh.principal_inertia_vectors

print(f"Principal moments: {principal_values}")
print(f"Principal axes:\n{principal_vectors}")

# Transform to principal axes
transform = mesh.principal_inertia_transform
aligned_mesh = mesh.copy()
aligned_mesh.apply_transform(transform)

Curvature Analysis

# Calculate curvature properties
gaussian_curvature = mesh.discrete_gaussian_curvature_measure()
mean_curvature = mesh.discrete_mean_curvature_measure()

# Analyze curvature distribution  
print(f"Gaussian curvature range: {gaussian_curvature.min():.4f} to {gaussian_curvature.max():.4f}")
print(f"Mean curvature range: {mean_curvature.min():.4f} to {mean_curvature.max():.4f}")

# Find high curvature regions
high_curvature_threshold = np.percentile(np.abs(mean_curvature), 90)
high_curvature_vertices = np.where(np.abs(mean_curvature) > high_curvature_threshold)[0]

print(f"High curvature vertices: {len(high_curvature_vertices)}")

# Visualize curvature
if mesh.visual.kind == 'vertex':
    # Color vertices by curvature
    curvature_normalized = (mean_curvature - mean_curvature.min()) / (mean_curvature.max() - mean_curvature.min())
    colors = plt.cm.viridis(curvature_normalized)[:, :3] * 255
    mesh.visual.vertex_colors = colors.astype(np.uint8)
    mesh.show()

Mesh Quality Assessment

# Basic quality checks
print(f"Is watertight: {mesh.is_watertight}")
print(f"Is winding consistent: {mesh.is_winding_consistent}")
print(f"Euler number: {mesh.euler_number}")
print(f"Vertex count: {len(mesh.vertices)}")
print(f"Face count: {len(mesh.faces)}")

# Geometric properties
print(f"Volume: {mesh.volume:.6f}")
print(f"Surface area: {mesh.area:.6f}")
print(f"Bounds: {mesh.bounds}")
print(f"Extents: {mesh.extents}")

# Quality metrics
print(f"Sphericity: {mesh.sphericity():.4f}")
print(f"Compactness: {mesh.compactness():.4f}")

# Edge and face statistics
edge_lengths = mesh.edge_lengths()
face_areas = mesh.area_faces

print(f"Edge length range: {edge_lengths.min():.6f} to {edge_lengths.max():.6f}")
print(f"Face area range: {face_areas.min():.6f} to {face_areas.max():.6f}")
print(f"Mean edge length: {edge_lengths.mean():.6f}")
print(f"Mean face area: {face_areas.mean():.6f}")

Mesh Comparison

# Load two meshes to compare
mesh1 = trimesh.load('original.stl')
mesh2 = trimesh.load('modified.stl')

# Hausdorff distance (measure of maximum deviation)
hausdorff_dist = mesh1.hausdorff_distance(mesh2)
print(f"Hausdorff distance: {hausdorff_dist:.6f}")

# Volume comparison
vol_diff = abs(mesh1.volume - mesh2.volume)
vol_percent = (vol_diff / mesh1.volume) * 100
print(f"Volume difference: {vol_diff:.6f} ({vol_percent:.2f}%)")

# Symmetric difference volume
sym_diff_vol = mesh1.symmetric_difference_volume(mesh2)
print(f"Symmetric difference volume: {sym_diff_vol:.6f}")

# Surface area comparison
area_diff = abs(mesh1.area - mesh2.area)
area_percent = (area_diff / mesh1.area) * 100
print(f"Surface area difference: {area_diff:.6f} ({area_percent:.2f}%)")

Statistical Analysis

import matplotlib.pyplot as plt

# Vertex degree distribution
vertex_degrees = mesh.vertex_degree()
print(f"Vertex degree range: {vertex_degrees.min()} to {vertex_degrees.max()}")
print(f"Mean vertex degree: {vertex_degrees.mean():.2f}")

# Edge length histogram
edge_lengths = mesh.edge_lengths()
counts, bin_edges = mesh.edge_lengths_histogram(bins=50)

plt.figure(figsize=(10, 6))
plt.subplot(1, 2, 1)
plt.hist(edge_lengths, bins=50, alpha=0.7)
plt.xlabel('Edge Length')
plt.ylabel('Count')
plt.title('Edge Length Distribution')

# Face area histogram  
face_areas = mesh.area_faces
plt.subplot(1, 2, 2)
plt.hist(face_areas, bins=50, alpha=0.7)
plt.xlabel('Face Area')
plt.ylabel('Count')
plt.title('Face Area Distribution')

plt.tight_layout()
plt.show()

# Find outliers
edge_mean = edge_lengths.mean()
edge_std = edge_lengths.std()
edge_outliers = np.where(edge_lengths > edge_mean + 3*edge_std)[0]
print(f"Edge length outliers: {len(edge_outliers)} edges")

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