MCP: let a caller find out its face/edge ids went stale

snaporca-rgbj measured the damage: four chamfers on a box remove
0.400/0.397/0.397/0.395 mm3 when each id is re-read, and
0.400/0.008/0.397/0.280 when the four ids are captured up front. The kernel is
right in both runs — the second one asks for the wrong edges. Neither errors,
because a stale id still resolves to a real edge, just not the one that was
measured.

That makes it an API problem rather than a script bug. Reading the scene once and
then issuing several operations is the natural way to drive a socket, it is what
every agent will write, and it produced silently wrong geometry with nothing
anywhere reporting it.

CadDocument::topo_generation is bumped where the bodies are replaced — the single
line in recompute() where the face and edge maps actually change, so a feature
type added later cannot forget to bump it, which a per-mutator counter would
invite. describe_scene and query_topology return it. A caller may pass it back as
"generation" on any call, and a mismatch is refused with a message that says what
to do about it.

Two deliberate choices:

OPTIONAL, not mandatory. Every existing script keeps working unchanged; passing
the generation is what buys the guarantee. Making it required would break every
caller to fix a mistake only some of them make.

CHECKED AT THE DISPATCHER, not in each handler. One site covers fillet, chamfer,
shell, draft, coordsys, thicken, cut, project, delete_face and everything added
after them. A per-handler check is a list that goes stale the first time someone
adds a method in a hurry.

Not serialized: an id means something only within the run that produced it, so
persisting the counter would promise a stability the ids themselves do not have.
No recipe version change.

describe_tools now carries an id_lifetime note, because the guard only helps a
caller who knows to ask for it.

Kernel suite 167 cases / 2277 assertions green; libslic3r_gui builds. The guard
itself is NOT exercised — it needs the socket, so it is on snaporca-bdco.
snaporca-o1l2.
This commit is contained in:
Tommaso Bianchi
2026-08-12 23:27:11 +02:00
parent 9125e0b4f8
commit a3398c6609
3 changed files with 57 additions and 1 deletions
+5
View File
@@ -3404,6 +3404,11 @@ bool CadDocument::recompute()
}
}
bodies = std::move(built);
// The face and edge maps have just been rebuilt, so every global id handed out before this
// point now means something else. Bump here rather than in each mutator: this is the single
// line where the topology is actually replaced, so it cannot be forgotten by a new feature
// type the way a per-mutator bump would be.
++topo_generation;
// Face-drift fingerprint for FaceAndDirection CoordSys connectors. This runs AFTER the
// bodies are final and APPENDS to mate_conflicts (detect_mate_conflicts() cleared it at