ifc-lite-processing 4.7.0

Shared IFC processing pipeline and types used by server and FFI
Documentation
# Module-size ratchet allowlist (see module_size_ratchet.rs).
# Non-generated, non-test Rust source files currently over the ~400-line
# house rule (AGENTS.md). Each line is '<budget> <path>'; the budget is the
# line count at the time it was recorded. The ratchet test fails if any of
# these grows PAST its budget, or if a NEW file crosses 400 without an entry.
# The rule: shrink or split. When you split a file below 400, delete its row
# (the total must trend DOWN). Only ADD a row with a written justification.
# Regenerated against the branch's merge base; refresh on rebase if a listed
     756 apps/server/src/services/parquet_data_model.rs
     581 apps/server/src/services/parquet_optimized.rs
     522 apps/server/src/services/parquet.rs
# +8: add set_entity_index setter so the processor can install its inline-built index (perf/single-scan).
# +50: add the per-worker placement-transform memo (field + take/set/get/cache methods), mirroring point_cache (perf/placement-cache).
    1064 rust/core/src/decoder.rs
     793 rust/core/src/georef.rs
     445 rust/core/src/model_bounds.rs
     601 rust/core/src/parser/scanner.rs
     463 rust/core/src/parser/tokenizer.rs
# +3: Arc<Vec<AttributeValue>> so DecodedEntity clone is a refcount bump not a deep attribute-tree clone (perf/decode-churn).
    553 rust/core/src/schema_gen.rs
# schema_helpers.rs row removed: the merged upstream #1969 split its tests into
# schema_helpers_tests.rs, dropping the file to 305 lines (under the 400 budget),
# same as the tree main converged on independently.
    990 rust/core/src/units.rs
# +4: build the index once in parallel on the fail-closed try_/project_glb_size large-model GLB paths (perf/parallel-scan).
# +81: emissive-material knob for KMZ/Google Earth (#1427) - make_material lit/unlit/emissive branch + emissive param threaded through build_gltf/export_glb_from_meshes and their tests.
    4028 rust/export/src/gltf.rs
# COLLADA (.dae) exporter that embeds geometry in the KMZ (#1427); cohesive single-purpose module.
# -205: #2628 review follow-up split the inline #[cfg(test)] mod out to collada_tests.rs
# (ratchet-exempt) to make room for the composed KMZ heading+up-axis orientation
# invariant test without growing this file; budget refreshed downward.
    430 rust/export/src/collada.rs
     468 rust/export/src/model.rs
# -140 net: text-level STEP primitives (escape/detect_schema/refs_in_line/
# split_top_level_args/apply_attr_mutations) split out to step_text.rs, making
# room for the backslash-doubling fix to escape() without raising this
# budget. step_text.rs's own #[cfg(test)] block was further split into
# step_text_tests.rs (ratchet-exempt via the _tests.rs suffix), leaving
# step_text.rs at 196 lines of production code (under 400, no row needed).
     471 rust/export/src/step.rs
# +45: reject non-positive SegmentLength/HorizontalLength (malformed-input NaN guard) + regression test.
    1170 rust/geometry/src/alignment.rs
# +19: split_on_edge now sets a failed flag and bails to the ear-clip fallback instead of the lone .expect() panic.
# +48: triangulate_pslg — conforming CDT over an arbitrary PSLG (open seam
# polylines as constraints, all hull triangles emitted, caller classifies);
# the prism-cut path's cap/decompose triangulator. Skips the ring depth-parity
# flood that open segments would corrupt.
     1617 rust/geometry/src/cdt.rs
     956 rust/geometry/src/csg/consolidate.rs
# -159: inline `mod tests` split out to csg/csg_tests.rs (ratchet-exempt) to make room for the
# degenerate-triangle NaN-normal fix and its two regression tests; budget refreshed downward.
# -117: the vertex-vs-plane classification epsilon (per-axis f32 rounding noise
# projected onto the clip plane's own normal, floored at 1e-6) and the
# clip_triangle body that consumes it moved out to csg/plane_eps.rs (365 lines,
# under the house limit, no row), taking their derivations with them; net down
# despite the new scaling logic; budget refreshed downward.
     671 rust/geometry/src/csg/mod.rs
 # -73: #1806 watertight-extrude tests split out to extrusion_watertight_tests.rs (ratchet-exempt); budget refreshed downward.
# +9: #1806 review — extrude_profile_watertight rejects < 3-vertex hole rings before
# triangulation (triangulate_constrained drops them from the cap while create_side_walls
# still emits their walls → cracked mesh); erroring defers the cut to the exact kernel.
    1078 rust/geometry/src/extrusion.rs
# +4: refine_high_aspect_slivers routes its rebuild through Mesh::rebuilt_like so a slivered host keeps its local-frame origin + #1474 placement capture (B7 metadata-loss fix).
# +1: SNAP_GRID/NORMAL_QUANT single-homed to kernel::mesh_bridge / crate::grid (import replaces local const; doc rewrap costs a line).
# +150: Holter void fast-path perf — raw no-sliver pre-scan (skips the O(V) canonicalization on
# clean cuts), region-scoped refine_high_aspect_slivers_within (prism path refines only the
# cut region, batching disjoint splits per round with a finite-aspect guard + hard split
# budget so a degenerate needle can't double its fragments every round; unscoped callers
# keep the byte-pinned one-edge-per-round behavior).
# +24: the raw pre-scan needs its OWN wider region padding (2x EDGE_SLACK) than the
# canonical scans, because canonicalization can move a vertex one dedup cell INTO the
# region — with a single padding the pre-scan could wrongly early-out on a triangle the
# canonical scan would refine. Plus the #[cfg(test)] include for facet_weld_scoped_tests.rs
# (the test file itself is ratchet-exempt).
# -45: local-frame anchor for the plane-offset math (n.v amplified a per-facet normal
# error by the world-frame position magnitude at site coordinates; the anchor is the
# bbox-min corner, a function of the vertex SET, so triangulation order cannot change the
# weld; engagement gated to coordinates that need it). The derivation lives inline at the
# anchor (Step 1.5); its regression tests moved to facet_weld_scoped_tests.rs
# (ratchet-exempt), netting the module below the prior budget; budget refreshed downward.
          907 rust/geometry/src/facet_weld.rs
     633 rust/geometry/src/kernel/arrangement/classify.rs
     566 rust/geometry/src/kernel/fixed.rs
# NEW (#1655): register-resident FixedInt<K> newtype backing the exact predicate cascade; large because it is a drop-in for bnum's I512 and must carry the full num_traits + std::ops trait surface (16 impls) the fixed_impl! macro binds. Its differential fuzz is split into the sibling tests.rs, kept under budget.
     630 rust/geometry/src/kernel/fixed_int/mod.rs
# +39: begin()/tripped() budget-guard added to the union & intersection kernel entries (#1109 parity with subtract).
# +7: union_many threads/documents union_all's new (union, conforming) signal (B8 arrange-many parity).
# +12: near_band_from_extent (the snap-scatter band formula) single-homed here, next to canonical SNAP_GRID; tritri/classify import it instead of mirroring the expression.
# -420: inline `mod tests` split out to the ratchet-exempt sibling mesh_bridge_tests.rs
#       when `intersection_tris` was added for the clash intersection solid; the module
#       itself shrank, so the budget ratchets DOWN to match rather than absorbing the growth.
     484 rust/geometry/src/kernel/mesh_bridge.rs
     700 rust/geometry/src/kernel/predicates.rs
# -31: extracted the final conformity audit + traversal recovery into kernel/retriangulate_audit.rs and phase-D recovery into retriangulate_recover.rs (issue #098 dense faceted-reveal walls); net down.
              935 rust/geometry/src/kernel/retriangulate.rs
# split out of retriangulate.rs: phase-D constraint recovery (recover_subsegment/enforce_constraint/between + the Sloan recover_via_traversal fallback for dense reveal pockets, issue #098).
         438 rust/geometry/src/kernel/retriangulate_recover.rs
# new row: adds from_spans (build the index from pre-collected IfcRelAssociatesMaterial spans, no re-walk) + the MaterialLayerFlat wire codec (to_flat/from_flat) + round-trip tests, so the streaming pre-pass ships the index to workers once instead of each worker re-scanning the file (perf/single-scan #563).
     563 rust/geometry/src/material_layer_index.rs
    1529 rust/geometry/src/mesh.rs
     919 rust/geometry/src/processors/boolean/mod.rs
     486 rust/geometry/src/processors/brep/faceted.rs
     402 rust/geometry/src/processors/csg_primitive.rs
     608 rust/geometry/src/processors/sectioned.rs
     758 rust/geometry/src/profile_extractor.rs
     598 rust/geometry/src/profiles/curves_2d.rs
     709 rust/geometry/src/profiles/curves_3d.rs
# +1: `mod steel_shapes;` for the shapes.rs split, which removed the 594-line shapes.rs row (net down).
     899 rust/geometry/src/profiles/mod.rs
     706 rust/geometry/src/profiles/simplify.rs
# +26: cap the fast-path opening count (O(N^3) DoS guard) + regression test.
     807 rust/geometry/src/rect_fast.rs
     586 rust/geometry/src/router/diagnostics.rs
     659 rust/geometry/src/router/layers.rs
# +1: unify body-rep predicate — added is_direct_body_representation + docs; net removes ~60 lines from processing.rs and ~12 from layers.rs (crate trends down).
# +65: promote the per-router IfcMappedItem source cache to a model-wide SharedMappedItemCache (type alias + field + new_/enable_ setters + unique-count diagnostic), meshing each source once model-wide (#1623).
# +38: #1623 Phase 2 don't-bake — MappedInstancePlan type alias + output_instancing_plan field + enable_/getter + `mod instancing` decl.
# +28: #858 palette guard — indexed_colour_split_ids field + enable_indexed_colour_split_guard setter + is_indexed_colour_split_source accessor (routes an indexed-colour mapped source to the flat per-palette split instead of a colour-collapsing instance placeholder).
# +42: #1623 Phase 3 batch-local template mode — instancing_batch_local flag + instanced_sources_materialized tracker fields + set_/getter/mark_source_materialized_if_first methods (browser per-batch don't-bake).
# +1: #1293 dedup rep_identity: build_dedup_extra_enabled/set_build_dedup_extra_override gate + DEDUP_EXTRA_OVERRIDE static; net +1 after the ItemDedupCache doc consolidation.
# +1: #1781 `mod textured;` — texture channel split OUT of processing.rs (that file drops ~90 lines below its budget; crate trends down).
     749 rust/geometry/src/router/mod.rs
# +65: #1623 Phase 2 don't-bake — the top-level mapped-item intercept (template retag + instance placeholder) + the public/impl process_element_with_submeshes split; the two eligibility/ensure helpers were extracted to router/instancing.rs (new, 92 lines) to hold the net down.
# +7: #858 palette guard — exclude an indexed-colour single-solid source from the don't-bake decision (one .filter on the resolved solid id + explanatory comment) so its per-triangle palette survives the flat split.
# +16: #1623 Phase 3 — thread the batch-local vs global template decision through the mapped-item intercept (is_template match arm + retag guard).
# +3: hoist the item-dedup mesh clone out of the cache Mutex critical section (let-binding + 2-line rationale) so a dedup miss no longer serializes the worker pool on a deep-copy.
# +18: #1293 dedup rep_identity: store rep beside the cached mesh, split tag_direct_instance into direct_rep_identity + stamp_direct_instance, and the flagged IFC_LITE_DEDUP_EXTRA type gate in item_dedup_key.
    1183 rust/geometry/src/router/processing.rs
# +26: is_rtc_votable_representation predicate + doc — Surface3D is meshable but must NOT cast RTC votes (#1526 pollution via absolute-coord surfaces).
# +7: #1910 detect_rtc_offset_from_first_element now also samples an exceptional representationless-spatial-container instance (see schema_helpers.rs) so RTC detection and meshing agree on what counts as geometry.
     479 rust/geometry/src/router/rtc_offset.rs
# +1: reveal-quads comment expanded to 2 lines (dead-symbol reference fix, no code change).
     619 rust/geometry/src/router/voids/aabb_clip.rs
     871 rust/geometry/src/router/voids/geom.rs
# +10: extract min_opening_volume(quality) tier->floor helper shared by the batch
# admission gate and the sequential CSG path so they can't diverge on the
# High/Highest small-opening floor (B11 regression, issue #976).
# +32: engulf-cutter #635 AABB box-cut suppression on a #1109 budget trip (drop `!capped`) + its rewritten rationale comment and a diag_warn! else-branch (correctness: an engulfing box-cut would DELETE the host).
# +5: ENGULF_TOLERANCE / ENGULF_TOLERANCE_F32 single-homed (3 sites shared one literal 0.03 tolerance, now one named const each).
# +2: #1623 Phase 2 — route the voided sub-mesh path through process_element_with_submeshes_impl(allow_instancing=false) so cut occurrences never instance an un-cut template.
# +42: analytic convex-prism fast-path wiring — module decl + apply_void_context
# call site with residual composition and cut-effect diagnostics parity.
# +27: #129 coaxial-union prepass wiring — module decl + feature-gated stats
# re-export + the pre-batch `coaxial_union_prepass` call and its consumed-skip.
     2054 rust/geometry/src/router/voids/mod.rs
# NEW: analytic prism (stepped-extrusion) subtraction on the host mesh — the
# CSG-heavy-corpus lever (ISSUE_098/129: exact void booleans are ~75-82% of
# geometry time; rebated masonry openings on brep/clipped hosts had no fast
# path). One cohesive algorithm: stack detection via normal clustering +
# cross-section slicing, canonical-order crossing cache, conforming CDT
# decomposition, parity-classified reveal caps with cross-face breakpoint
# injection, flush cap/edge extension, volume-identity + closed-surface
# self-checks. Tests live in prism_cut_tests.rs (exempt).
# +79: #1112 roof-opening fixes — collinear profile simplification (unblocks
# the flush-strip edge extension), exact-kernel-matched flush band, and the
# self-checked post-cut sliver refinement (final cuts only).
# +24: #1806 review correctness guards — bounds-check the host (ptris_from_mesh)
# BEFORE the panic-prone closure audits, merge cutters only across a
# numerically-coincident (8·SNAP_GRID) interface not a 2 mm gap/overlap, and
# re-audit AFTER clean_degenerate so the EMITTED mesh is validated — keeping the
# already-closed pre-clean construction when hygiene would crack it (vs deferring
# the whole host to the exact kernel), which preserves the analytic hit-rate.
# +147: #1806 CodeRabbit review guards — validate profile-edge extensions stay
# SIMPLE and still contain the authored profile (ring_is_simple + boundary-
# tolerant point_in_or_on/ring_contains_ring; a folded non-convex ring passes
# ccw_area); prefilter occupancy against the SUPPLIED footprint bbox not pf.bb;
# merge prisms only across an identical basis (u/v/d), not just a shared depth
# axis; carry the host face normal onto resolve_crossings' new points; and
# feature-gate the process-global diagnostic counters (default build carries no
# hot-path atomics — also removes the parallel-test race).
# +105: #1806 CodeRabbit round-2 — the hairline self-check (the whole prism
# safety net) replaced its midpoint-proximity boundary matcher with a rigorous
# per-supporting-line SIGNED-multiplicity coverage sweep (true collinearity +
# full-interval coverage + multiplicity, rejecting a long open edge that a short
# reverse edge merely grazed). Lines are seeded longest-edge-first so genuine
# collinear hairline covers are not fragmented into phantom-gap groups (keeps the
# analytic hit-rate on the dense faceted-reveal walls). Plus a positions/indices
# %3 malformed-mesh guard at the top of ptris_from_mesh and the PROFILE_FUSE_TOL
# (8·SNAP_GRID) weld for profile-equality fusion.
# +54: Holter perf — capture committed-cutter AABBs (post-extension) and run the
# post-cut sliver refinement REGION-SCOPED (refine_high_aspect_slivers_within) so
# only rim slivers the cut created are bisected, not the host's authored
# long-thin faces; skip the probe/audit tail when the fixpoint was a no-op.
    3160 rust/geometry/src/router/voids/prism_cut.rs
# NEW: #129 coaxial footprint-union for OVERLAPPING opening clusters. One cohesive
# algorithm: extended-AABB overlap clustering (union-find), coaxial detection, 2.5D
# depth-slicing with per-slab i_overlay footprint union + watertight re-extrude to
# disjoint prisms (fed to subtract_mesh_many), and a 3D union_many fallback — plus
# the mesh-cap footprint projection, orthonormal frame, and feature-gated telemetry.
# +92 (CodeRabbit #1815): equivalence guards so an approximate union is NEVER consumed
# as an exact cut — near-exact coaxial gate (1−1e-6) routes tilt to the exact union;
# per-cutter prism reconciliation (area·depth ≈ |vol|) defers non-prisms; and a
# removed-volume upper bound (Σ extended-cutter volume) rejects an over-cut before it
# commits, while a through-cut of a host thicker than the opening is not mistaken for one.
# +9 (#2616): doc-only comments recording the z_tol coalescing rationale at the
# depth-guard call sites; no code change.
     704 rust/geometry/src/router/voids/coaxial_union.rs
# probe.rs +134: the 2D bool-path host/opening extraction — `extruded_solid_from_item`
# (unwrap IfcMappedItem chains to a single IfcExtrudedAreaSolid + composed transform),
# `host_extruded_solid` and `opening_extruded_solids` (single-body eligibility gates).
# +10: mapped-item completeness guard — a non-null MappingTarget must parse and the
# mapped representation must hold exactly one item, else the opening defers to exact.
# +87 (#1806 CodeRabbit): body_representation_items now mirrors the mesh path's
# effective_rep_type + is_body_representation selection (incl. MappedRepresentation
# de-dup, collecting items across ALL body reps so a multi-rep body defers) instead of
# a raw RepresentationType match, and mapping_origin_is_identity defers the fast path
# when an IfcMappedItem's RepresentationMap.MappingOrigin is non-identity (the mesh
# path drops it) — both keep the analytic cut bit-consistent with the rendered solid.
# +6 (#1806 CodeRabbit round-2): reject non-finite rectangle dims/extrusion depth
# (is_finite guards) so an inf depth can no longer slip past the `> 0.0` / `<= 0.0`
# gates into the fast path.
     858 rust/geometry/src/router/voids/probe.rs
    1002 rust/geometry/src/router/voids/synthesis.rs
    1472 rust/geometry/src/space_dcel/mod.rs
     525 rust/geometry/src/transform.rs
     782 rust/geometry/src/triangulation.rs
     745 rust/geometry/src/void_index.rs
     499 rust/processing/src/determinism.rs
# +48: #1623 Phase 2 don't-bake — ProducedElementMeshes.instance_occurrences + threading it through produce_inner (tuple returns), and emit_sub_meshes converting empty-with-InstanceMeta placeholders into RawInstanceOccurrences.
# +19: #1781 textured occurrence sub-meshes — emit_sub_meshes attaches UVs+texture (length-guarded) and the non-void path calls the texture-aware router entry.
# +18: #1891 follow-on — ProducedElementMeshes.geometry_aabb (the world box from the SAME hashing pass) plus the emit-together match that keeps it index-parallel with geometry_hash at the FFI boundary.
# +35: #1891 closedness — ProducedElementMeshes.geometry_volume + .geometry_closure (the volume and the four-clause verdict that gates it), the widened emit-together match, and threading orient_mesh_outward_verdict's per-mesh verdict from BOTH orient call sites into the hasher. The verdict has to be taken exactly where the orienter already runs and handed to the hasher segment it describes, so it cannot move out of this decision tree; the gate's own 190 lines of rationale live in rust/geometry/src/geom_closure.rs (new, sub-400) rather than here.
# -22: #1891 review (PR #1993) — the f32-collapse degenerate backstop (env switch, the drop, the per-element tally) moved to the child module element_degenerate.rs (new, 72), which is where the ordering story now belongs: the tally stopped being a diagnostic and became the input to the closure retraction. Budget refreshed downward; the retraction call site itself costs 7 lines here.
     910 rust/processing/src/element.rs
# +9: #2019 — canonicalise each host's opening order so the world geometry
# hash stops depending on IFCRELVOIDSELEMENT statement order (sequential void
# cuts are not associative). Three lines of code plus the why.
     781 rust/processing/src/prepass.rs
# +24: build the entity index INLINE in the scan loop instead of a separate build_entity_index pass (perf/single-scan; one file walk instead of two).
# +15: try_lock the per-worker point cache to fix the nested-par_iter re-entrancy self-deadlock (#1572 regression).
# +20: add the per-worker placement-transform cache store + its try_lock slot acquisition, mirroring the point cache (perf/placement-cache).
# +8: construct one model-wide shared IfcMappedItem source cache per process_geometry pass and inject it into each per-job router (#1623).
# +74: #1623 Phase 2 don't-bake — ProcessingResult.instances field + StreamingOptions.enable_instancing + the scan-built MappedInstancePlan + the plan/collector threaded into process_entity_job + the finalize call; the finalize/orphan-recovery bodies were extracted to processor/instancing.rs (new, 147 lines) to hold the net down.
# +27: #858 palette guard — build the indexed_colour_split_ids set from the indexed-colour map keys (armed only with the plan) + thread it into process_entity_job so an indexed-colour mapped source stays flat (keeps its per-triangle palette).
# +19: #1910 schedule a representationless spatial container (IfcBuilding et al.) for meshing when it exceptionally carries a non-null Representation, instead of silently dropping its geometry.
    1661 rust/processing/src/processor/mod.rs
# +410: NEW row — #858 palette guard added the indexed_colour_split_ids param to process_entity_job (already the extracted per-job worker body from the #1623 file split), pushing this existing large module one line over 400; splitting the single job function further would fragment the tightly-coupled worker setup.
     410 rust/processing/src/processor/jobs.rs
# +6: wire per-batch point-cache hit/miss stats into record_pipeline_batch (perf/brep-point-cache-instrumentation).
# +13: attach the per-worker shared IfcMappedItem source cache to each batch router, mirroring the item-dedup attach (#1623).
# +155: #1623 Phase 3 browser don't-bake — produce_batch gains arm_instancing (batch-local plan arm + occurrence collection + finalize call/return-tuple change) and the partitioned path folds the kept occurrences into the IFNS shard as empty-geometry refs; the finalize + recovery bodies were extracted to gpu_meshes/instancing.rs (new, ~165 lines) to hold the net down.
# +4: #1891 follow-on — carry ProducedElementMeshes.geometry_aabb through ElementMeshOutput to push_geometry_hash on both the flat and partitioned paths.
# +31: #1891 closedness — ElementMeshOutput gains geometry_volume + geometry_closure_bits, and the ONE ElementMeshOutput::fingerprint() builder both push sites now call (net shorter than the two struct literals it replaces, and the flat/partitioned paths can no longer fill different subsets of the index-parallel arrays). The fingerprint is taken into a local before each loop moves `out.meshes`, with a one-line note at both sites so the ordering is not "tidied" back into a borrow error.
     976 rust/wasm-bindings/src/api/gpu_meshes/batch.rs
# +108: build the referenced-repmaps + instantiated-type-id sets and the material-layer index ONCE in the streaming pre-pass (from spans this scan already collected) and emit them as a `prepass-columns` event, so every geometry worker skips its own full-file walk on the first batch (perf/single-scan #957/#563).
# +14: #1623 Phase 3 — tally the don't-bake MappedInstancePlan from the same IfcMappedItem spans and emit it on the prepass-columns event (mirrors the referenced-repmaps ship).
# +9: cap the entity-index up-front reservation (PREPASS_INDEX_RESERVE_CAP) so a ~4GB file does not reserve ~1GB of slots on top of the resident file and abort the wasm32 4GB address space before the scan (huge-file graceful-4gb).
# +17: #1910 mirrors the identical processor/mod.rs exception — schedule an exceptional representationless-spatial-container job so the browser/wasm viewer doesn't silently drop the same geometry the server would now mesh.
     797 rust/wasm-bindings/src/api/gpu_meshes/prepass.rs
     436 rust/wasm-bindings/src/api/grid_lines.rs
# +75: add the setReferencedRepmaps / setInstantiatedTypeIds / setMaterialLayerIndex wasm setters that install the pre-pass-computed per-content structures into the worker's IfcAPI (perf/single-scan #957/#563), mirroring setEntityIndex.
# +23: add the cached_source_bytes session field (doc + init + clearPrePassCache drop) for cold-load lever 1c (setSourceBytes); the setter + FromSource batch variants live in the new sub-400 gpu_meshes/batch_from_source.rs, not here (perf/coldload-setsourcebytes).
# +37: hold the per-worker shared IfcMappedItem source cache field + drop it on content swap / setEntityIndex / setTessellationQuality, mirroring cached_item_dedup (#1623).
# +10: drop the shared mapped-item cache in set_skip_small_cuts too (boolean-processor swap; #1623 P1 settings-hole fix).
# +65: #1623 Phase 3 — cached_mapped_instance_plan field (doc + init + clear on clearPrePassCache/setEntityIndex) + setMappedInstancePlan wasm setter + mapped_instance_plan accessor (mirrors setReferencedRepmaps).
# +3: three disjoint one-line additions that each landed at exactly the old
# budget alone and only breach in combination: the `clash_solid` mod
# declaration (#2573), the `set_panic_hook()` call that keeps init()'s
# panic-location stash (#2539), and the geometry-hash tolerance clamp doc
# (#2528). Splitting this file is the real fix and is tracked separately; it
# would conflict with all three of those PRs at once.
# +1: #2573 landing on main: `mod clash_solid;` was anticipated in the note
# above but had not actually merged yet — main's 1091 only carried #2539 and
# #2528. This is that fourth, previously-uncounted line.
     1092 rust/wasm-bindings/src/api/mod.rs
# +61: #1781 external image textures — textureId/textureUrl fields + getters, set_texture_ref, and the get/takeMesh/Clone field threading.
# +17: #1891 follow-on — geometry_aabb_values field + geometryAabbValues getter (the doc carries the Y-up frame contract and the world-box rationale so a future reader does not re-derive them), the four constructor/Clone initializers, and the #[cfg(test)] include for mesh_tests.rs (the test file itself is ratchet-exempt). Net +17 and not +56, because the two Z-up→Y-up conversion helpers moved out to a new sibling frame_swap.rs (107 lines, under the house limit, no row): the box swap is now shared by the f32 local bounds and the f64 world AABB, so the min/max reversal lives in exactly one place.
# -46: #1891 closedness added geometry_volume_values + geometry_closure_flags, and the whole per-entity fingerprint surface (the five index-parallel arrays' getters — including the Y-up swap on the way out — plus GeometryFingerprint and push_geometry_hash) moved OUT to the child module zero_copy/mesh_fingerprint.rs (new, 161 lines, under the house limit, no row) — net down despite two new arrays; budget refreshed downward.
# +3: #2049 — `set_texture` was the one 8-arg fn in this crate missing the
# `#[allow(clippy::too_many_arguments)]` its 21 peers carry. The crate's lint
# has never run in CI (`--exclude ifc-lite-wasm`), which is how it drifted.
     727 rust/wasm-bindings/src/zero_copy/mesh.rs
     743 rust/wasm-bindings/src/zero_copy/symbolic.rs
# +65: #1910 follow-up — buildPrePassOnce's combined_pre_pass is a third
# geometry-job discovery path with the same has_geometry_by_name gap as the
# serial/sharded scans; adds the instance-level exception plus its regression
# test (combined_pre_pass_issue_1910_tests).
# +22: #1910 review follow-up — the exception test only proved a storey WITH a
# Representation gets a job, so forcing nth_attribute_is_present to always
# report "present" left it passing (demonstrated by mutation). Adds the null-
# Representation negative case and the shared storey_jobs helper it needs.
     527 rust/wasm-bindings/src/api/styling/prepass.rs