MAX_PLACEMENT_DEPTH

Constant MAX_PLACEMENT_DEPTH 

Source
pub const MAX_PLACEMENT_DEPTH: usize = 100;
Expand description

Maximum IfcLocalPlacement.PlacementRelTo chain any walk in this workspace will follow. A chain longer than this composes only its first MAX_PLACEMENT_DEPTH + 1 placements and the rest is dropped — silently, on every site that uses it.

Shared because two walks follow the SAME attribute of the SAME entity and their bounds must agree: ifc_lite_geometry::router::transforms (the mesh path) and ifc_lite_geometry::profile_extractor (the 2D drawing path). They disagreed — 32 against 100 — and because both exceed-branches return the IDENTITY rather than an error, an element on a 33-to-101-link chain was drawn in two different places by the two paths with nothing reported. #2873

§Why 100 and not 32

The 32 carried the rationale “keep low for WASM — each frame uses ~2KB+ of stack”. The wasm bundles are linked with -zstack-size=8388608 (.cargo/config.toml and both extra bundles in scripts/build-wasm.sh), so the budget is 8 MiB and the cap’s own worst case is ~0.1% of it; native hosts give the geometry pool 256 MiB (rust/ffi, rust/python). Measured rather than assumed: see the frame figures in #2873. PlacementRelTo is a single reference, so this walk has fan-out 1 and costs O(depth) — the breadth blow-up that makes a depth cap the wrong instrument elsewhere (see AGENTS.md) does not apply here.

The two candidates are not symmetric. Equalising UP lets the mesh path compose chains it currently flattens; equalising DOWN would make the 2D path start flattening chains it composes correctly today, silently. Across the 111 fixtures in tests/models that contain placements the deepest chain is 7 links, so neither value binds on any file in the corpus and the choice is decided entirely by which failure is worse on a file that does exceed it.

This bounds one path’s LENGTH only. A walk over a chain that can revisit also needs a cycle guard; see the module docs above.