Repository navigation
Compute each distinct dielectric sheet once (same output) - #34
Merged
Merged
Conversation
Dielectrics crossed by the same drills get the same sheet: cut and extrude it once and move the mesh to the other dielectrics' heights (LayerMesh::restacked). Copper and paste layers crossed by the same drills share one hole cutter, and hole cuts are no longer cloned per layer. The GLB stays byte-for-byte the same.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
testcase1-RevC-full (IPC consortium Testcase1, 58 MB XML) has 11 dielectric layers. Each sheet is the outline minus the holes that cross it, and with only through holes all 11 are identical (7.0 MB each, 4.2 M of 17.25 M triangles). The converter cut, triangulated and extruded each one separately: in WASM "cut and sheets" took 1.2–1.3 s and "extrude" 0.9 s of a 5.4–6 s conversion (
perf-findings.md).What this PR does (no profile change, same output)
through()as before; drills that don't cross a layer don't count) have the same cuts. Each dielectric whose set matches an earlier dielectric's gets no sheet of its own in "cut and sheets"; in "extrude" it takes the earlier dielectric's mesh moved to its own heights.LayerMesh::restacked(from, to)(boardui-geom): moves a mesh of extruded regions from heightsfromtoto. Extrusion writes exactly two heights (z_min as f32for bottom vertices,z_max as f32for top ones), and triangulation doesn't depend on them, so the result is exactly the mesh that extruding attogives (positions, indices, feature ranges and bounds). It returnsNonewhen either range is one extrusion rejects or the source heights coincide inf32; then, and when the first sheet failed to mesh (so the warning names the right layer), the pipeline extrudes the sheet again as before. Unit test plus a proptest (restacked == extruded again, including ranges that collapse inf32).HoleCutter(R-tree), built once per set instead of once per layer, and the per-layer hole cuts are no longer cloned for the soldermask and dielectric unions (they take references, in the same order). Soldermask sheets can't be shared (each side has its own openings), and a shared hole union would change the boolean operations' input order and so the output bytes, so I left those alone.Output: byte for byte the same
BOARDUI_CONFORMANCE_OUT,cmp) and for testcase1-RevC-full (CLI). No snapshot changes.v[2](glTF z, i.e. −board y) instead ofv[1](board height), so its copied sheets were flattened, not moved.Sharing per sample (sets of crossing drills = distinct sheet geometries, checked from the GLBs): testcase1-RevC-full 11 dielectrics → 1 sheet; blind-buried-vias (KiCad, blind and buried vias) 23 → 3; testcase11-rdgflx-RevC-full 5 → 2; royalblue54l-feather 7 → 1; IPC-2581-8-Layer-Design 7 → 1; fomu-pvt 3 → 3.
Numbers (testcase1-RevC-full)
docker-server (8 cores), master b6932ae vs this branch, alternating runs, medians. The machine is shared with other sessions; this series ran at load average 6–8 (an earlier one at 5–7 gave the same picture: WASM cut and sheets 1.29 → 0.84 s, extrude 0.93 → 0.67 s).
WASM (Node 24,
packages/converterdist +wasm-bindgenoutput, nowasm-opt; first conversion in a fresh process; n = 7):Native CLI (release, rayon; n = 14): total wall 1.50 → 1.43 s, cut and sheets 0.204 → 0.150 s, extrude 0.153 → 0.135 s, peak memory 1,397 → 1,312 MB. Native gains less: the 11 sheets were cut in parallel there already.
Blind/buried vias: blind-buried-vias (KiCad sample, 23 dielectrics → 3 sheets) is tiny (48 ms in WASM either way, "cut and sheets" 3 → 2 ms). testcase11-rdgflx-RevC-full (5 → 2): WASM 0.49 → 0.44 s (median of 5), "cut and sheets" 28 → 18 ms.
Test evidence
In
boardui-dev:1:cargo fmt --all --check,cargo clippy --workspace --all-targets --locked -- -D warnings,BOARDUI_REQUIRE_IPC_TESTCASES=1 cargo test --workspace --locked(conformance 51/51 with the fetched IPC test cases),cargo build -p boardui-wasm --target wasm32-unknown-unknown --release --locked: all pass. Nopackages/changes.Spec changes
None.
Known gaps / follow-ups
LayerMesh::restackedagain, since nothing moves meshes once they're shared; if only this PR is merged, it stays.