Skip to content

Scripting API

Decimator

from ArtisanPlugin.Scripting import MeshApi as mesh

Repaired and scanned meshes are heavy — millions of faces that slow down slicers, viewers and file transfers. Two reducers, with opposite priorities: Decimate hits a face count and lets the shape suffer; DecimateToTolerance guarantees the shape stays within a deviation budget and takes whatever face count falls out. For final delivery of jewellery geometry, the tolerance-driven one is usually the right tool.

Both replace each mesh in place, keeping its Guid, so wrap the calls in a Transaction. In both, objectIds = None (or empty) means the current selection, and non-mesh objects are skipped silently.

Decimate

Rhino’s quadric edge-collapse reduction (the ArtisanMeshDecimate command, headless). Distortion is allowed: the reducer prioritises hitting the target face count over shape fidelity, so heavy percentages give a faceted low-poly look.

r = mesh.Decimate(objectIds = None, percentage = 50)
ParameterDefaultMeaning
objectIdsNone = current selectionMeshes to decimate
percentage50Faces to remove, 1–99. percentage = 80 keeps 20% of the faces

The target is floored at 4 faces, so a tiny mesh never collapses to nothing. A mesh whose reduction fails is skipped and simply not counted.

Returns a DecimateResult with the totals, so the script can report “N meshes: X faces → Y faces”:

FieldTypeMeaning
MeshesDecimatedintMeshes actually replaced
FacesBeforeintTotal faces across those meshes, before
FacesAfterintTotal faces after

Validation that throws:

  • Out-of-range percentage: "Percentage must be between 1 and 99."
  • No meshes at all: "Nothing to decimate: select (or pass) at least one mesh."

DecimateToTolerance

Reduces each mesh as much as a deviation budget allows (the ArtisanMeshDecimateTolerance command, headless): the mesh is taken to the heaviest reduction whose result still stays within toleranceMm of the original surface. The shape is guaranteed; the face count is whatever falls out.

r = mesh.DecimateToTolerance(objectIds = None, toleranceMm = 0)
ParameterDefaultMeaning
objectIdsNone = current selectionMeshes to decimate
toleranceMm0 = 0.05Maximum deviation from the original surface, in millimetres, regardless of the document’s units. Valid range 0.001–100

A mesh that cannot lose even one percent within the tolerance is left untouched and counted in MeshesUnchanged — the call never makes a mesh worse than the budget just to shrink it.

Returns a DecimateToleranceResult:

FieldTypeMeaning
MeshesDecimatedintMeshes replaced
MeshesUnchangedintMeshes left untouched because nothing fit the budget
TrianglesBeforeintTotal triangles before, across the decimated meshes
TrianglesAfterintTotal triangles after
MaxDeviationMmfloatLargest deviation across every decimated mesh (mm) — always ≤ toleranceMm

The counts are in triangles, not faces: the reducer triangulates quads first, so a quad mesh’s face count is not comparable with the result’s.

Validation that throws:

  • Out-of-range tolerance: "Tolerance must be between 0.001 and 100 mm."
  • No meshes at all: "Nothing to decimate: select (or pass) at least one mesh."
from ArtisanPlugin.Scripting import MeshApi as mesh, Transaction

with Transaction.Begin("Decimate for delivery"):
    r = mesh.DecimateToTolerance(toleranceMm = 0.05)
    print(f"{r.MeshesDecimated} meshes: {r.TrianglesBefore} -> {r.TrianglesAfter} triangles, "
          f"max deviation {r.MaxDeviationMm:.3f} mm ({r.MeshesUnchanged} unchanged)")