Reconstruction graph
Swift only — the reconstruct_* tools require the Swift occtmcp-server.
This recipe walks the annotate-and-persist layer over an attributed reconstruction graph. OCCTMCP exposes topology as nodes addressed <kind>:<index> (e.g. face:3) and lets an LLM write per-node reconstruct.* attributes: decisions, fit overrides, and instance membership. The fitting engine lives in OCCTReconstruct; reconstruct_force_fit records an override attribute — it does not re-fit.
See the Reconstruction graph reference for full parameter tables.
1. Start a session
Call reconstruct_get_graph with a bodyId to open a session. The returned sessionId is the handle for every subsequent call.
{ "bodyId": "scan_part" }
{
"sessionId": "scan_part",
"topologyCounts": { "face": 12, "edge": 30, "vertex": 20 },
"annotatedNodes": [],
"instanceClusters": []
}
The graph has 12 faces, 30 edges, and 20 vertices — all unannotated so far. Resume an existing session by passing sessionId instead of bodyId.
2. Annotate a node’s decision
Use reconstruct_set_decision to record who made a fit decision and whether it is accepted. Supply at least one of decidedBy or accepted.
{
"sessionId": "scan_part",
"node": "face:3",
"decidedBy": "human",
"accepted": true
}
{
"sessionId": "scan_part",
"node": "face:3",
"updated": {
"reconstruct.decidedBy": "human",
"reconstruct.accepted": true
}
}
Repeat for each node you want to annotate. A subsequent reconstruct_get_graph call (with sessionId) will list all annotated nodes.
3. Override a surface type
If a face was fitted as plane but you know it should be cylinder, record the override with reconstruct_force_fit. This writes reconstruct.forcedSurfaceType onto the node; the OCCTReconstruct engine honours it on its next pass.
{
"sessionId": "scan_part",
"node": "face:5",
"surfaceType": "cylinder"
}
{
"sessionId": "scan_part",
"node": "face:5",
"forcedSurfaceType": "cylinder"
}
Valid values for surfaceType: plane, cylinder, cone, sphere, torus.
4. Confirm a congruence cluster
When you identify a set of nodes that form one part definition (congruent instances), call reconstruct_confirm_instances. Every listed node is tagged with the clusterId and the confirmed flag.
{
"sessionId": "scan_part",
"clusterId": "flange_boss",
"nodes": ["face:2", "face:6", "face:9"],
"confirmed": true
}
{
"sessionId": "scan_part",
"clusterId": "flange_boss",
"nodes": ["face:2", "face:6", "face:9"],
"confirmed": true
}
Pass "confirmed": false to reject a cluster the engine proposed.
5. Persist the session
reconstruct_export_session writes a byte-stable JSON snapshot. The default path is <output_dir>/reconstruct/<sessionId>.session.json.
{ "sessionId": "scan_part" }
{
"sessionId": "scan_part",
"path": "/Users/you/Library/Mobile Documents/com~apple~CloudDocs/OCCTSwiftScripts/output/reconstruct/scan_part.session.json"
}
The snapshot is byte-stable: the same session state always produces identical bytes, so it is safe to checksum or diff across saves. Pass an optional path to write elsewhere.
6. Reload a session
reconstruct_import_session reads a snapshot file back into memory and returns the full graph state. Use this after a server restart or to hand off a session between runs.
{
"path": "/Users/you/Library/Mobile Documents/com~apple~CloudDocs/OCCTSwiftScripts/output/reconstruct/scan_part.session.json"
}
{
"sessionId": "scan_part",
"topologyCounts": { "face": 12, "edge": 30, "vertex": 20 },
"annotatedNodes": [
{
"node": "face:3",
"attributes": {
"reconstruct.decidedBy": "human",
"reconstruct.accepted": true
}
},
{
"node": "face:5",
"attributes": {
"reconstruct.forcedSurfaceType": "cylinder"
}
}
],
"instanceClusters": [
{ "clusterId": "flange_boss", "nodes": ["face:2", "face:6", "face:9"], "confirmed": true }
]
}
sessionId defaults to the file stem (scan_part here); pass an explicit sessionId to assign a different handle.