Formlabs Developers
Download PreForm Insider to start developing with the PreForm API.

Validate

The printability checks report, per model, whether a scene will print as it is: a hole in the mesh, a wall too thin, a cup that traps resin during printing, a minima the supports miss, or a model outside the build volume. Each check reads the scene and returns the results for each model on the scene.

An L bracket on supports with a triangular hole in the top of its horizontal arm, which the manifold check reports.

A block on supports with a 0.3 mm fin standing on its top face, which the thin-wall check reports.

How a check runs#

You call a check on a scene, PreForm analyzes its models, and the answer holds one result per model, keyed by model ID, under per_model_results. For example a cup check on a scene with two models will return:

JSON
{
  "per_model_results": {
    "c2a37eb2-8e4b-4b8e-9f37-1f5f2c1a9d10": { "cup_count": 0 },
    "9b1dd8a0-4f6e-45c2-9a3e-77a01f2b6c55": { "cup_count": 2 }
  }
}

After running a check you can also check the status of the validation on a model by checking the model properties such as model.cup_count

Similar to PreForm, the results are invalidated after you move, reorient, or support a model, to get the validation results you have to run the check again.

Mesh checks#

The manifold and thin-wall checks only look at the mesh, so you can run them right after you import a model:

Python
# Each check answers per model: per_model_results maps a model ID to its result.
manifold = preform.validate_manifoldness(scene_id=scene.scene_id)
for model_id, result in manifold.per_model_results.additional_properties.items():
    if not result.is_manifold:
        print(f"{model_id} has holes: {result.status}")

thin = preform.validate_thin_features(scene_id=scene.scene_id, threshold_mm=0.5)
for model_id, result in thin.per_model_results.additional_properties.items():
    if result.has_thin_walls:
        print(f"{model_id}: {result.thin_region_count} region(s) under 0.5 mm")

The example imports the model with repair_behavior=RepairBehavior.IGNORE, so a mesh with holes is imported as it is and the manifold check can find the holes. To fix a model that isn't manifold, call repair_models. Hollowing and drilling only work on manifold models.

Set threshold_mm to the thinnest wall your material can print at your layer thickness. If the thin-wall check can't analyze a model, for example because the mesh has holes, the model's status is not ANALYZED.

Orientation and support checks#

Cups depend on how a model is oriented, and unsupported minima and undersupported areas depend on its supports. Run these checks after you orient and support your models:

Python
preform.auto_orient_models(scene_id=scene.scene_id)
preform.auto_support_models(scene_id=scene.scene_id)
preform.auto_layout_models(scene_id=scene.scene_id)

# The cup, minima and supportedness checks always analyze the whole scene.
cups = preform.validate_cups(scene_id=scene.scene_id)
minima = preform.validate_minima(scene_id=scene.scene_id)
supported = preform.validate_supportedness(scene_id=scene.scene_id)
for model_id, result in cups.per_model_results.additional_properties.items():
    print(model_id, "cups:", result.cup_count)
for model_id, result in minima.per_model_results.additional_properties.items():
    print(model_id, "unsupported minima:", result.minima_count)
for model_id, result in supported.per_model_results.additional_properties.items():
    print(model_id, f"{result.percent_unsupported:.1f}% undersupported")

These checks always run on every printable model in the scene, and they can take tens of seconds. The SDK runs them as an operation and waits for the result. The cup and minima checks fail with OPERATION_FAILED if a model is outside the build volume, so lay out your models before you run them.

To fix a model with cups, reorient it or add drain holes. To fix unsupported minima or undersupported areas, generate the supports again or increase their density.

Fit and collision checks#

The fit and collision checks look at the models where they are on the build platform:

Python
# Read the scene as it stands: nothing is moved to make a model fit.
fits = preform.validate_in_bounds(scene_id=scene.scene_id)
collisions = preform.validate_interferences(scene_id=scene.scene_id)
print(fits.to_dict())
print("colliding pairs:", collisions.model_ids)

The fit check includes the supports. A model that sticks out of the build volume is reported as in_bounds: false, even if it would fit in another orientation. Adding supports can also push a model out of bounds. If you move, scale, or reorient models yourself, they can overlap. The collision check returns each pair of overlapping models.

The checks#

CheckMethodResult per modelRun it after
Manifoldvalidate_manifoldnessis_manifoldImport
Thin wallsvalidate_thin_featureshas_thin_walls, thin_region_count, thin_volume_mm3Import
Cupsvalidate_cupscup_countOrientation
Unsupported minimavalidate_minimaminima_countSupports
Undersupported areavalidate_supportednesspercent_unsupported, 0 to 100Supports
Fitvalidate_in_boundsin_boundsLayout
Collisionsvalidate_interferencesPairs of overlapping models, in model_idsLayout

To check only some models, pass model_ids to the manifold, thin-wall, or fit check. For the fields and error codes of each check, see the Printability Checks endpoints. For a script that checks every part in an order, see Printability report.

What's next#

Feedback & Bug Reports