Version v1.0.0-alpha (latest)
Printability Checks
Scene printability checks. These endpoints analyze the scene and report problems. They never modify it.
Detect cups#
POST/v1/scene/model/validate/cups/
Analyze every printable model in the scene for cups: cavities that face the build platform and seal against the resin surface as the part prints. Cups trap air or resin, causing suction forces during peel that lead to print failure, and trapped uncured resin in the finished part.
The check runs per model and returns the number of cups found in each. A cup_count of 0 means the model's current orientation produces no cups. To fix a model with cups, reorient it (manually or with /v1/scene/model/auto-orient/) or add drain holes (/v1/scene/model/drill/).
The whole scene is always analyzed. There is no model selection for this endpoint. Detection can take tens of seconds on complex scenes, so prefer ?async=true and poll the returned operation.
This endpoint reads the scene without modifying it. It is a POST because its input travels in the request body. The body carries only the scene reference.
Error codes#
| HTTP | error.code | Cause |
|---|---|---|
| 400 | JSON_PARSE_ERROR | The request body is not a valid JSON object. |
| 400 | MISSING_PARAMETER | The body has no scene_id field. |
| 400 | INPUT_ERROR | scene_id is not a well-formed UUID, or no scene with that id exists. |
| 400 | INVALID_QUERY_PARAMETER | async is present but not true or false. |
| 400 | OPERATION_FAILED | The detection task itself failed. The message carries the underlying reason. |
Query parameters
asyncbooleanWhen
true, returns202 Acceptedimmediately with the operation's id and itsoperation_urlto poll for the result, instead of blocking until the operation completes.
Request bodyobject
scene_idstring (uuid)RequiredThe id of the scene to analyze.
Returns 200 OKobject
per_model_resultsmap of CupDetectionResultRequiredMap of model id to that model's cup-detection result.
Show child attributes
cup_countintegerRequiredNumber of cup cavities detected in the model's current orientation. 0 means no suction risk from cups.
Detection completed. One entry per printable model in the scene, keyed by model id. An empty per_model_results means the scene contains no printable models.
Returns 202 AcceptedOperationAccepted
operation_idstring (uuid)RequiredRandomly generated id of the tracked operation.
operation_urlstringRequiredServer-relative URL of this operation's record:
/v1/operation/get/?operation_id=<operation_id>.GETit to follow progress and retrieve the result.messagestringRequiredHuman-readable pointer to where the result will appear. Purely informational. Use
operation_urlprogrammatically.
Detection started asynchronously (?async=true). Poll the operations endpoints with the returned id.
Response headers (202)
LocationstringServer-relative URL of the accepted operation's record, identical to the response body's
operation_url.GETit to follow progress and retrieve the result.
/v1/scene/model/validate/cups/from formlabs_sdk import FormlabsClient
with FormlabsClient() as client:
preform = client.preform.connect()
result = preform.validate_cups(
scene_id="3fa85f64-5717-4562-b3fc-2c963f66afa6",
)curl -X POST "http://localhost:44388/v1/scene/model/validate/cups/" \
-H "Content-Type: application/json" \
-d '{
"scene_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}'{
"per_model_results": {
"c2a37eb2-8e4b-4b8e-9f37-1f5f2c1a9d10": {
"cup_count": 0
},
"9b1dd8a0-4f6e-45c2-9a3e-77a01f2b6c55": {
"cup_count": 2
}
}
}{
"per_model_results": {}
}{
"operation_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"operation_url": "/v1/operation/get/?operation_id=7c9e6679-7425-40de-944b-e07fc1f90ae7",
"message": "Operation accepted. Poll GET /v1/operation/get/?operation_id=7c9e6679-7425-40de-944b-e07fc1f90ae7 until 'status' is SUCCEEDED or FAILED; the endpoint's response will appear in the 'result' field there."
}Detect unsupported minima#
POST/v1/scene/model/validate/minima/
Analyze every printable model in the scene for unsupported minima: local low points on the surface that the model's current supports don't reach. Unsupported minima may break off the part during printing and lead to print failures.
The check runs per model and returns the number of unsupported minima found in each. A minima_count of 0 means every low point on the model is currently supported. To fix a model with minima, add supports manually or regenerate them (/v1/scene/model/auto-support/).
The whole scene is always analyzed. There is no model selection for this endpoint. Detection can take tens of seconds on complex scenes, so prefer ?async=true and poll the returned operation.
Error codes#
| HTTP | error.code | Cause |
|---|---|---|
| 400 | JSON_PARSE_ERROR | The request body is not a valid JSON object. |
| 400 | MISSING_PARAMETER | The body has no scene_id field. |
| 400 | INPUT_ERROR | scene_id is not a well-formed UUID, or no scene with that id exists. |
| 400 | INVALID_QUERY_PARAMETER | async is present but not true or false. |
| 400 | OPERATION_FAILED | The detection task itself failed. The message carries the underlying reason. |
Query parameters
asyncbooleanWhen
true, returns202 Acceptedimmediately with the operation's id and itsoperation_urlto poll for the result, instead of blocking until the operation completes.
Request bodyobject
scene_idstring (uuid)RequiredThe id of the scene to analyze.
Returns 200 OKobject
per_model_resultsmap of MinimaDetectionResultRequiredMap of model id to that model's minima-detection result.
Show child attributes
minima_countintegerRequiredNumber of unsupported local minima detected on the model. 0 means every low point is currently supported.
Detection completed. One entry per printable model in the scene, keyed by model id. An empty per_model_results means the scene contains no printable models.
Returns 202 AcceptedOperationAccepted
operation_idstring (uuid)RequiredRandomly generated id of the tracked operation.
operation_urlstringRequiredServer-relative URL of this operation's record:
/v1/operation/get/?operation_id=<operation_id>.GETit to follow progress and retrieve the result.messagestringRequiredHuman-readable pointer to where the result will appear. Purely informational. Use
operation_urlprogrammatically.
Detection started asynchronously (?async=true). Poll the operations endpoints with the returned id.
Response headers (202)
LocationstringServer-relative URL of the accepted operation's record, identical to the response body's
operation_url.GETit to follow progress and retrieve the result.
/v1/scene/model/validate/minima/from formlabs_sdk import FormlabsClient
with FormlabsClient() as client:
preform = client.preform.connect()
result = preform.validate_minima(
scene_id="3fa85f64-5717-4562-b3fc-2c963f66afa6",
)curl -X POST "http://localhost:44388/v1/scene/model/validate/minima/" \
-H "Content-Type: application/json" \
-d '{
"scene_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}'{
"per_model_results": {
"c2a37eb2-8e4b-4b8e-9f37-1f5f2c1a9d10": {
"minima_count": 0
},
"9b1dd8a0-4f6e-45c2-9a3e-77a01f2b6c55": {
"minima_count": 3
}
}
}{
"per_model_results": {}
}{
"operation_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"operation_url": "/v1/operation/get/?operation_id=7c9e6679-7425-40de-944b-e07fc1f90ae7",
"message": "Operation accepted. Poll GET /v1/operation/get/?operation_id=7c9e6679-7425-40de-944b-e07fc1f90ae7 until 'status' is SUCCEEDED or FAILED; the endpoint's response will appear in the 'result' field there."
}Detect undersupported area#
POST/v1/scene/model/validate/supportedness/
Analyze every printable model in the scene for how much of its surface is undersupported. This is the same calculation behind the desktop app's "Undersupported Models" red-shading toggle.
The check runs per model and returns percent_unsupported, on a 0-100 scale. 0 means the model is fully supported in its current orientation and support configuration. Higher values mean more of the surface is at risk of printing incompletely or breaking off during the print.
The whole scene is always analyzed. There is no model selection for this endpoint. Detection can take tens of seconds on complex scenes, so prefer ?async=true and poll the returned operation.
Error codes#
| HTTP | error.code | Cause |
|---|---|---|
| 400 | JSON_PARSE_ERROR | The request body is not a valid JSON object. |
| 400 | MISSING_PARAMETER | The body has no scene_id field. |
| 400 | INPUT_ERROR | scene_id is not a well-formed UUID, or no scene with that id exists. |
| 400 | INVALID_QUERY_PARAMETER | async is present but not true or false. |
| 400 | OPERATION_FAILED | The detection task itself failed. The message carries the underlying reason. |
Query parameters
asyncbooleanWhen
true, returns202 Acceptedimmediately with the operation's id and itsoperation_urlto poll for the result, instead of blocking until the operation completes.
Request bodyobject
scene_idstring (uuid)RequiredThe id of the scene to analyze.
Returns 200 OKobject
per_model_resultsmap of SupportednessDetectionResultRequiredMap of model id to that model's supportedness-detection result.
Show child attributes
percent_unsupportednumberRequiredPercentage of the model's surface that is undersupported in its current orientation and support configuration. 0 means fully supported.
Detection completed. One entry per printable model in the scene, keyed by model id. An empty per_model_results means the scene contains no printable models.
Returns 202 AcceptedOperationAccepted
operation_idstring (uuid)RequiredRandomly generated id of the tracked operation.
operation_urlstringRequiredServer-relative URL of this operation's record:
/v1/operation/get/?operation_id=<operation_id>.GETit to follow progress and retrieve the result.messagestringRequiredHuman-readable pointer to where the result will appear. Purely informational. Use
operation_urlprogrammatically.
Detection started asynchronously (?async=true). Poll the operations endpoints with the returned id.
Response headers (202)
LocationstringServer-relative URL of the accepted operation's record, identical to the response body's
operation_url.GETit to follow progress and retrieve the result.
/v1/scene/model/validate/supportedness/from formlabs_sdk import FormlabsClient
with FormlabsClient() as client:
preform = client.preform.connect()
result = preform.validate_supportedness(
scene_id="3fa85f64-5717-4562-b3fc-2c963f66afa6",
)curl -X POST "http://localhost:44388/v1/scene/model/validate/supportedness/" \
-H "Content-Type: application/json" \
-d '{
"scene_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}'{
"per_model_results": {
"c2a37eb2-8e4b-4b8e-9f37-1f5f2c1a9d10": {
"percent_unsupported": 0
},
"9b1dd8a0-4f6e-45c2-9a3e-77a01f2b6c55": {
"percent_unsupported": 42.5
}
}
}{
"per_model_results": {}
}{
"operation_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"operation_url": "/v1/operation/get/?operation_id=7c9e6679-7425-40de-944b-e07fc1f90ae7",
"message": "Operation accepted. Poll GET /v1/operation/get/?operation_id=7c9e6679-7425-40de-944b-e07fc1f90ae7 until 'status' is SUCCEEDED or FAILED; the endpoint's response will appear in the 'result' field there."
}Detect thin walls#
POST/v1/scene/model/validate/thin-features/
Analyze the selected models for walls thinner than threshold_mm: regions likely to be fragile, warp, or fail to cure fully during printing.
Unlike the other printability-check endpoints, this one takes an explicit model selection (model_ids) and a required threshold, rather than always scanning every printable model in the scene. Omitting model_ids (or passing an empty array) analyzes every model currently in the scene, including non-printable ones.
The check runs per model and returns an aggregate summary (has_thin_walls, thin_volume_mm3, thin_region_count) plus, when thin walls were found, a thin_regions breakdown of each connected thin region's volume and bounding box.
Detection can take a while on complex scenes or a large model selection, so prefer ?async=true and poll the returned operation.
Error codes#
| HTTP | error.code | Cause |
|---|---|---|
| 400 | INVALID_QUERY_PARAMETER | async is present but not true or false. |
| 400 | JSON_PARSE_ERROR | The request body is not a valid JSON object. |
| 400 | JSON_SCHEMA_MATCH_ERROR | scene_id is missing, threshold_mm is missing or not a positive number, model_ids is present but not an array of strings, or an unrecognized field is present. |
| 400 | INPUT_ERROR | scene_id is not a well-formed UUID, or no scene with that id exists. |
| 400 | OPERATION_FAILED | The detection task failed, including when model_ids names an id that does not exist in the scene. The message carries the underlying reason. |
Query parameters
asyncbooleanWhen
true, returns202 Acceptedimmediately with the operation's id and itsoperation_urlto poll for the result, instead of blocking until the operation completes.
Request bodyThinWallDetectionRequest
scene_idstring (uuid)RequiredThe id of the scene containing the models.
model_idsarray of string (uuid)sIds of the models to analyze. Omitted or empty means every model in the scene, including non-printable ones.
threshold_mmnumberRequiredWall thickness threshold, in millimeters. Regions thinner than this are flagged as thin.
Returns 200 OKobject
per_model_resultsmap of ThinWallDetectionResultRequiredMap of model id to that model's thin-wall-detection result.
Show child attributes
statusstringRequiredPer-model analysis outcome.
ANALYZED: analysis ran (see the other fields).TOO_SMALL: too small/thin to voxelize (sub-~2-voxel extent or sub-voxel shell).TOO_LARGE: too large to voxelize within the memory budget at this resolution (often a units mistake).MESH_ERROR: the mesh could not be rasterized (degenerate/broken geometry). For any non-ANALYZEDstatus the model could not be assessed:has_thin_wallsis false andthin_regionsis empty. These are per-model outcomes, not request errors, and other models still return normally.ANALYZEDTOO_SMALLTOO_LARGEMESH_ERROR
has_thin_wallsbooleanRequiredWhether any thin region was found.
thin_volume_mm3numberRequiredSum of all detected thin regions' volumes, in cubic millimeters. 0 if
has_thin_wallsis false.thin_region_countintegerRequiredNumber of distinct thin regions detected, equal to the length of
thin_regions.thin_regionsarray of objectsRequiredPer-region breakdown, sorted by volume descending. Empty if
has_thin_wallsis false.Show child attributes
volume_mm3numberRequiredVolume of this connected thin region, in cubic millimeters.
bounding_boxobjectRequiredAxis-aligned bounding box of the region, in scene coordinates.
Show child attributes
min_cornerScenePositionA position within a printer's build volume, in millimeters, in user coordinate space.
Show child attributes
xnumberRequiredX position. 0 is the center of the build volume. Positive moves right as you face the printer.
ynumberRequiredY position. 0 is the center of the build volume. Positive moves away from you as you face the printer.
znumberRequiredVertical position. 0 is the surface of the build platform.
max_cornerScenePositionA position within a printer's build volume, in millimeters, in user coordinate space.
Show child attributes
xnumberRequiredX position. 0 is the center of the build volume. Positive moves right as you face the printer.
ynumberRequiredY position. 0 is the center of the build volume. Positive moves away from you as you face the printer.
znumberRequiredVertical position. 0 is the surface of the build platform.
Detection completed. One entry per analyzed model, keyed by model id. An empty per_model_results means the scene (or the requested model_ids) contains no models.
Returns 202 AcceptedOperationAccepted
operation_idstring (uuid)RequiredRandomly generated id of the tracked operation.
operation_urlstringRequiredServer-relative URL of this operation's record:
/v1/operation/get/?operation_id=<operation_id>.GETit to follow progress and retrieve the result.messagestringRequiredHuman-readable pointer to where the result will appear. Purely informational. Use
operation_urlprogrammatically.
Detection started asynchronously (?async=true). Poll the operations endpoints with the returned id.
Response headers (202)
LocationstringServer-relative URL of the accepted operation's record, identical to the response body's
operation_url.GETit to follow progress and retrieve the result.
/v1/scene/model/validate/thin-features/from formlabs_sdk import FormlabsClient
with FormlabsClient() as client:
preform = client.preform.connect()
result = preform.validate_thin_features(
scene_id="3fa85f64-5717-4562-b3fc-2c963f66afa6",
threshold_mm=0.5,
)curl -X POST "http://localhost:44388/v1/scene/model/validate/thin-features/" \
-H "Content-Type: application/json" \
-d '{
"scene_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"threshold_mm": 0.5
}'from formlabs_sdk import FormlabsClient
with FormlabsClient() as client:
preform = client.preform.connect()
result = preform.validate_thin_features(
scene_id="3fa85f64-5717-4562-b3fc-2c963f66afa6",
model_ids=["c2a37eb2-8e4b-4b8e-9f37-1f5f2c1a9d10", "9b1dd8a0-4f6e-45c2-9a3e-77a01f2b6c55"],
threshold_mm=0.6,
)curl -X POST "http://localhost:44388/v1/scene/model/validate/thin-features/" \
-H "Content-Type: application/json" \
-d '{
"scene_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"model_ids": [
"c2a37eb2-8e4b-4b8e-9f37-1f5f2c1a9d10",
"9b1dd8a0-4f6e-45c2-9a3e-77a01f2b6c55"
],
"threshold_mm": 0.6
}'{
"per_model_results": {
"c2a37eb2-8e4b-4b8e-9f37-1f5f2c1a9d10": {
"status": "ANALYZED",
"has_thin_walls": false,
"thin_volume_mm3": 0,
"thin_region_count": 0,
"thin_regions": []
},
"9b1dd8a0-4f6e-45c2-9a3e-77a01f2b6c55": {
"status": "ANALYZED",
"has_thin_walls": true,
"thin_volume_mm3": 12.4,
"thin_region_count": 2,
"thin_regions": [
{
"volume_mm3": 9.1,
"bounding_box": {
"min_corner": {
"x": -10,
"y": -5,
"z": 0
},
"max_corner": {
"x": -6,
"y": 5,
"z": 3
}
}
},
{
"volume_mm3": 3.3,
"bounding_box": {
"min_corner": {
"x": 4,
"y": -2,
"z": 8
},
"max_corner": {
"x": 7,
"y": 2,
"z": 10
}
}
}
]
}
}
}{
"operation_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"operation_url": "/v1/operation/get/?operation_id=7c9e6679-7425-40de-944b-e07fc1f90ae7",
"message": "Operation accepted. Poll GET /v1/operation/get/?operation_id=7c9e6679-7425-40de-944b-e07fc1f90ae7 until 'status' is SUCCEEDED or FAILED; the endpoint's response will appear in the 'result' field there."
}Detect colliding models#
POST/v1/scene/model/validate/interferences/
Find pairs of models in the scene that overlap by more than the collision-detection offset. Models scaled, moved, or reoriented without re-validating the layout (see /v1/scene/model/scale/, /v1/scene/model/translate/, and /v1/scene/model/orient/, each of which recommends calling this endpoint afterwards) may end up overlapping without any other feedback.
Every visible, printable model in the scene is considered. There is no model selection for this endpoint.
collision_offset_mm, an optional body field, overrides the scene's own configured visual collision offset for this call only. If it is absent, the scene's configured offset is used.
Unlike the other printability-check endpoints, this one does not support ?async=true: colliding-models detection always runs synchronously.
Error codes#
| HTTP | error.code | Cause |
|---|---|---|
| 400 | JSON_PARSE_ERROR | The request body is not a valid JSON object. |
| 400 | JSON_SCHEMA_MATCH_ERROR | scene_id is missing, collision_offset_mm is not a number, or an unrecognized field is present. |
| 400 | INPUT_ERROR | scene_id is not a well-formed UUID, or no scene with that id exists. |
| 400 | OPERATION_FAILED | The detection task itself failed. The message carries the underlying reason. |
Request bodyobject
scene_idstring (uuid)RequiredThe id of the scene to analyze.
collision_offset_mmnumberMinimum gap, in millimeters, models must keep to not be reported as colliding. Negative values allow a controlled amount of overlap. Defaults to the scene's own configured visual collision offset.
Returnsobject
model_idsarray of array of string (uuid)sRequiredEach entry is one colliding pair: a 2-element array of the two models' ids. A model can appear in more than one pair.
Detection completed. Empty model_ids means no colliding pairs were found.
/v1/scene/model/validate/interferences/from formlabs_sdk import FormlabsClient
with FormlabsClient() as client:
preform = client.preform.connect()
result = preform.validate_interferences(
scene_id="3fa85f64-5717-4562-b3fc-2c963f66afa6",
)curl -X POST "http://localhost:44388/v1/scene/model/validate/interferences/" \
-H "Content-Type: application/json" \
-d '{
"scene_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}'from formlabs_sdk import FormlabsClient
with FormlabsClient() as client:
preform = client.preform.connect()
result = preform.validate_interferences(
scene_id="3fa85f64-5717-4562-b3fc-2c963f66afa6",
collision_offset_mm=0.5,
)curl -X POST "http://localhost:44388/v1/scene/model/validate/interferences/" \
-H "Content-Type: application/json" \
-d '{
"scene_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"collision_offset_mm": 0.5
}'{
"model_ids": [
[
"c2a37eb2-8e4b-4b8e-9f37-1f5f2c1a9d10",
"9b1dd8a0-4f6e-45c2-9a3e-77a01f2b6c55"
]
]
}{
"model_ids": []
}Check models are manifold#
POST/v1/scene/model/validate/manifoldness/
Validate that the selected models are manifold solids: closed, watertight meshes where every edge is shared by exactly two triangles. Non-manifold geometry (holes, open boundaries, bowtie vertices, self-inconsistent triangulation) can slice incorrectly and cause print failures.
The check runs per model using the manifold library and reports each model's verdict. A model that is not manifold can be repaired with /v1/scene/model/repair/.
Some operations require manifold input: /v1/scene/model/hollow/ and /v1/scene/model/drill/ do not work on non-manifold models (/v1/scene/model/dental-hollow/ is unaffected because it rebuilds the surface rather than operating on the input topology). Run this check, and repair if it fails, before relying on those endpoints.
Omitting model_ids checks every model in the scene. This endpoint reads the scene without modifying it, and is a POST only because its input travels in the request body.
Error codes#
| HTTP | error.code | Cause |
|---|---|---|
| 400 | JSON_PARSE_ERROR | The request body is not a valid JSON object. |
| 400 | JSON_SCHEMA_MATCH_ERROR | The body does not match the request schema: scene_id missing, a field has the wrong type, model_ids is present but not an array of strings, or an unknown field is present. |
| 400 | INPUT_ERROR | scene_id is not a well-formed UUID, or no scene with that id exists. |
| 400 | INVALID_QUERY_PARAMETER | async is present but not true or false. |
| 400 | OPERATION_FAILED | The check itself failed. The message carries the underlying reason. |
| 404 | NOT_FOUND | A model in model_ids does not exist in the scene. |
Query parameters
asyncbooleanWhen
true, returns202 Acceptedimmediately with the operation's id and itsoperation_urlto poll for the result, instead of blocking until the operation completes.
Request bodyCheckManifoldRequest
scene_idstring (uuid)RequiredThe id of the scene containing the models.
model_idsarray of string (uuid)sIds of the models to check. Omitted or empty means every model in the scene.
Returns 200 OKobject
per_model_resultsmap of ManifoldCheckResultRequiredMap of model id to that model's manifold-check result.
Show child attributes
is_manifoldbooleanRequiredWhether the model's mesh is a manifold solid. Equivalent to
status == "MANIFOLD".The manifold library's verdict on a mesh. Only
MANIFOLDmeans the mesh is a valid manifold solid.MANIFOLD- The mesh is a closed manifold solid.
NOT_MANIFOLD- The mesh has non-manifold geometry, such as open boundaries, holes, or edges/vertices shared inconsistently between triangles.
NON_FINITE_VERTEX- The mesh contains a vertex with a NaN or infinite coordinate.
OTHER_ERROR- The manifold library rejected the mesh for another reason.
The check completed. One entry per selected model, keyed by model id. An empty per_model_results means the selection matched no models.
Returns 202 AcceptedOperationAccepted
operation_idstring (uuid)RequiredRandomly generated id of the tracked operation.
operation_urlstringRequiredServer-relative URL of this operation's record:
/v1/operation/get/?operation_id=<operation_id>.GETit to follow progress and retrieve the result.messagestringRequiredHuman-readable pointer to where the result will appear. Purely informational. Use
operation_urlprogrammatically.
The check started asynchronously (?async=true). Poll the operations endpoints with the returned id.
Response headers (202)
LocationstringServer-relative URL of the accepted operation's record, identical to the response body's
operation_url.GETit to follow progress and retrieve the result.
/v1/scene/model/validate/manifoldness/from formlabs_sdk import FormlabsClient
with FormlabsClient() as client:
preform = client.preform.connect()
result = preform.validate_manifoldness(
scene_id="3fa85f64-5717-4562-b3fc-2c963f66afa6",
)curl -X POST "http://localhost:44388/v1/scene/model/validate/manifoldness/" \
-H "Content-Type: application/json" \
-d '{
"scene_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}'from formlabs_sdk import FormlabsClient
with FormlabsClient() as client:
preform = client.preform.connect()
result = preform.validate_manifoldness(
scene_id="3fa85f64-5717-4562-b3fc-2c963f66afa6",
model_ids=["c2a37eb2-8e4b-4b8e-9f37-1f5f2c1a9d10"],
)curl -X POST "http://localhost:44388/v1/scene/model/validate/manifoldness/" \
-H "Content-Type: application/json" \
-d '{
"scene_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"model_ids": [
"c2a37eb2-8e4b-4b8e-9f37-1f5f2c1a9d10"
]
}'{
"per_model_results": {
"c2a37eb2-8e4b-4b8e-9f37-1f5f2c1a9d10": {
"is_manifold": true,
"status": "MANIFOLD"
},
"9b1dd8a0-4f6e-45c2-9a3e-77a01f2b6c55": {
"is_manifold": false,
"status": "NOT_MANIFOLD"
}
}
}{
"operation_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"operation_url": "/v1/operation/get/?operation_id=7c9e6679-7425-40de-944b-e07fc1f90ae7",
"message": "Operation accepted. Poll GET /v1/operation/get/?operation_id=7c9e6679-7425-40de-944b-e07fc1f90ae7 until 'status' is SUCCEEDED or FAILED; the endpoint's response will appear in the 'result' field there."
}Check models fit in the build volume#
POST/v1/scene/model/validate/in-bounds/
Report whether each selected model, at its current position, orientation and scale, fits inside the build volume of the scene's printer type.
This is a direct read of scene state, not a computation: it never reorients, rescales, moves or re-lays-out anything, and it does not report whether a model could fit in some other pose. A model that would fit if rotated is still reported in_bounds: false while it sticks out where it currently sits.
The verdict includes a model's supports, so adding supports can take an in-bounds model out of bounds. It is the same verdict as the in_bounds field of /v1/scene/model/list/; this endpoint exists so that callers whose only question is "does it fit?" can ask it directly rather than reading and filtering full model state.
Models out of the build volume are an ordinary, expected result here, reported as in_bounds: false with a 200. Unlike /v1/scene/model/validate/cups/ and /v1/scene/model/validate/minima/, this endpoint does not fail with OPERATION_FAILED when a model does not fit.
Omitting model_ids checks every model in the scene. This endpoint reads the scene without modifying it, and is a POST only because its input travels in the request body. The check is immediate, so there is no async form.
Error codes#
| HTTP | error.code | Cause |
|---|---|---|
| 400 | JSON_PARSE_ERROR | The request body is not a valid JSON object. |
| 400 | JSON_SCHEMA_MATCH_ERROR | The body does not match the request schema: scene_id missing, a field has the wrong type, model_ids is present but not an array of strings, or an unknown field is present. |
| 400 | INPUT_ERROR | scene_id is not a well-formed UUID, or no scene with that id exists. |
| 404 | NOT_FOUND | A model in model_ids does not exist in the scene. |
Request bodyInBoundsDetectionRequest
scene_idstring (uuid)RequiredThe id of the scene containing the models.
model_idsarray of string (uuid)sIds of the models to check. Omitted or empty means every model in the scene.
Returnsobject
per_model_resultsmap of InBoundsResultRequiredMap of model id to that model's build-volume verdict.
Show child attributes
in_boundsbooleanRequiredWhether the model, including its supports, fits inside the build volume at its current position, orientation and scale. The same verdict as the
in_boundsfield of/v1/scene/model/list/.
all_in_boundsbooleanRequiredWhether every selected model is in bounds.
truewhenper_model_resultsis empty.
The check completed. One entry per selected model, keyed by model id. An empty per_model_results means the selection matched no models, in which case all_in_bounds is true.
/v1/scene/model/validate/in-bounds/from formlabs_sdk import FormlabsClient
with FormlabsClient() as client:
preform = client.preform.connect()
result = preform.validate_in_bounds(
scene_id="3fa85f64-5717-4562-b3fc-2c963f66afa6",
)curl -X POST "http://localhost:44388/v1/scene/model/validate/in-bounds/" \
-H "Content-Type: application/json" \
-d '{
"scene_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}'from formlabs_sdk import FormlabsClient
with FormlabsClient() as client:
preform = client.preform.connect()
result = preform.validate_in_bounds(
scene_id="3fa85f64-5717-4562-b3fc-2c963f66afa6",
model_ids=["c2a37eb2-8e4b-4b8e-9f37-1f5f2c1a9d10"],
)curl -X POST "http://localhost:44388/v1/scene/model/validate/in-bounds/" \
-H "Content-Type: application/json" \
-d '{
"scene_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"model_ids": [
"c2a37eb2-8e4b-4b8e-9f37-1f5f2c1a9d10"
]
}'{
"per_model_results": {
"c2a37eb2-8e4b-4b8e-9f37-1f5f2c1a9d10": {
"in_bounds": true
},
"9b1dd8a0-4f6e-45c2-9a3e-77a01f2b6c55": {
"in_bounds": false
}
},
"all_in_bounds": false
}