Skip to content

Filter Mesh Using Quadric Decimation ​

SUMMARY

Filter Mesh Using Quadric Decimation simplifies a datatypes.Mesh3D to at most a target number of triangles.

It repeatedly collapses the edge whose removal least changes the surface (quadric error metric decimation), then removes degenerate and duplicated triangles and unused vertices. The overall shape and bounds are preserved closely, so the result is a lighter stand-in for the original mesh. This Skill operates on a datatypes.Mesh3D, not a datatypes.PointCloud.

Use this Skill when a dense CAD or scanned mesh is too heavy for pose estimation, collision checking, or visualization and you need the same shape with far fewer triangles.

The Skill ​

python
from telekinesis import vitreous

simplified_mesh = vitreous.filter_mesh_using_quadric_decimation(
    mesh=mesh,
    target_number_of_triangles=5000,
)
API Reference
Full parameter and return type documentation for filter_mesh_using_quadric_decimation.
View Reference →

Data Transfer Notice

There is no longer a fixed limit of 1 million points per request. However, very large datasets may result in slower data transfer and processing times. We are continuously optimizing performance as part of our beta program, with ongoing improvements to enhance speed and reliability.

The Code ​

python
"""
Demonstrates simplifying a dense mesh to a target triangle count while preserving its shape.
"""

from loguru import logger
import rerun as rr

from telekinesis import vitreous, datatypes


def filter_mesh_using_quadric_decimation_example():
    """
    Simplifies a mesh using quadric error metric decimation.

    Collapses the edges whose removal least changes the surface until the mesh
    has at most the target number of triangles, producing a lighter mesh with
    the same overall shape.
    """
    # ===================== Load Data ==========================================
    mesh_url = "https://assets.telekinesis.ai/examples/v1/meshes/beer_can.glb"
    mesh = datatypes.Mesh3D.from_url(url=mesh_url, use_cache=True)

    # ===================== Run Skill ==========================================
    simplified_mesh = vitreous.filter_mesh_using_quadric_decimation(
        mesh=mesh,
        target_number_of_triangles=5000,
    )

    # ===================== Log ================================================
    logger.success(f"Simplified {mesh} using quadric decimation")
    logger.success(f"Results: {simplified_mesh}")
    logger.info(
        f"Triangles: {len(mesh.triangle_indices)} -> "
        f"{len(simplified_mesh.triangle_indices)}, vertices: "
        f"{len(mesh.vertex_positions)} -> {len(simplified_mesh.vertex_positions)}"
    )

    # ===================== Visualization  (Optional) ===========================
    rr.init("filter_mesh_using_quadric_decimation_example", spawn=True)
    datatypes.visualize(mesh, entity_path="/1-original_mesh")
    datatypes.visualize(simplified_mesh, entity_path="/2-simplified_mesh")


if __name__ == "__main__":
    filter_mesh_using_quadric_decimation_example()

Runnable examples are available in the Telekinesis examples repository.

Follow the README in that repository to set up the environment, run this specific example with:

bash
cd telekinesis-examples
python examples/point_cloud/filter_mesh_using_quadric_decimation.py

Parameter Configuration ​

ParameterTypeDefaultDescription
meshdatatypes.Mesh3DrequiredThe mesh to simplify. Must contain triangles. Not a datatypes.PointCloud
target_number_of_trianglesdatatypes.Int | intrequiredThe maximum number of triangles in the simplified mesh. Must be > 0. A mesh that already has this many triangles or fewer is returned unchanged

Returns ​

TypeDescription
datatypes.Mesh3DThe simplified mesh, with at most target_number_of_triangles triangles. Use len(mesh.triangle_indices) for the triangle count and len(mesh.vertex_positions) for the vertex count. Vertex normals present on the input are recomputed for the simplified surface.

Raises ​

ExceptionCondition
TypeErrorA parameter's value does not match its expected type (see the Parameter Configuration table above)
ValueErrortarget_number_of_triangles is not positive (must be > 0)
ConfigurationErrorThe TELEKINESIS_API_KEY environment variable is not set
SerializationErrorThe request input failed to serialize, the response was not returned as an Arrow stream, or the response failed to deserialize
RequestTimeoutErrorThe request to the Vitreous service timed out
TransportErrorA network failure occurred before a response was received
ClientErrorThe Vitreous service rejected the request due to invalid or malformed input, such as a mesh without triangles (HTTP 400/422), an unrecognized endpoint (HTTP 404), or another unexpected 4xx response
AuthenticationErrorThe API key was rejected as invalid or expired (HTTP 401)
AuthenticationServiceErrorThe authentication service returned an invalid response, was temporarily unavailable, or timed out (HTTP 502/503/504)
ServerErrorThe Vitreous service returned a 5xx or otherwise unexpected error response

How to Tune the Parameters ​

filter_mesh_using_quadric_decimation exposes one parameter.

target_number_of_triangles

  • Controls: The size of the simplified mesh — the result has at most this many triangles.
  • Must be > 0 — zero or a negative value raises a ValueError
  • Increase → keeps more detail, at the cost of a heavier mesh
  • Decrease → a lighter, faster mesh; very low targets round off small features such as edges, threads, and holes
  • Typical range: 5,000–50,000 for pose estimation and collision checking of a single part; 1,000–5,000 for coarse visualization or proxies

TIP

Best practice: Pick the lowest target at which the features your downstream Skill relies on (edges for pose estimation, contact surfaces for grasping) are still visible. Compare the original and simplified meshes in Rerun before fixing the value.

Where to Use the Skill ​

Common pipelines include:

  • Pose estimation preprocessing – Simplifying a dense CAD model before estimate_pose_using_foundation_pose to reduce rendering cost per hypothesis
  • Collision geometry – Producing a lighter mesh for planning-scene collision checks
  • Visualization – Keeping large scanned or CAD meshes responsive in viewers
  • Data transfer – Reducing payload size before sending a mesh to other Skills

Alternative Skills ​

SkillComparison with Filter Mesh Using Quadric Decimation
reconstruct_mesh_using_convex_hullProduces a much coarser convex envelope and loses all concave features. Use it only when a convex bound is enough.
convert_mesh_to_point_cloudUse it when the downstream Skill needs points rather than a lighter mesh.

When Not to Use the Skill ​

Do not use Filter Mesh Using Quadric Decimation when:

  • The input is a point cloud – this Skill requires a datatypes.Mesh3D; reconstruct a mesh first, or use a point-cloud downsampling Skill such as filter_point_cloud_using_voxel_downsampling
  • Exact geometry is required – decimation approximates the surface; keep the original mesh for metrology or tight-tolerance inspection
  • Fine features matter at a low target – thin walls, small holes, and sharp edges are the first details to be lost