Add three-axis milling with independent CAM and Fusion validation (#1682)
Thanks @CypherNaught-0x.
This commit is contained in:
1 parent
dd5278a402
commit
737c9358d0
85 files changed
+14487
-43
No files matched your search
@@ -0,0 +1,102 @@
|
||||
# First milling milestone acceptance
|
||||
|
||||
Audit date: 2026-10-16. Scope: rectangular stock, fixed-axis three-axis facing,
|
||||
2D contouring, pockets with islands, and simple/peck drilling. The planned workflow
|
||||
is implemented and the initial four-strategy Fusion comparison gate passes.
|
||||
This is machining-result equivalence for the recorded reference corpus, not a
|
||||
claim about all Fusion Manufacturing features or physical controller qualification.
|
||||
|
||||
## Requirement-to-evidence audit
|
||||
|
||||
Paths below identify committed implementation and independently authored tests.
|
||||
Fusion captures and their derived reports remain ignored local evidence.
|
||||
|
||||
| Plan requirement | Implementation and acceptance evidence |
|
||||
| --- | --- |
|
||||
| Pure-Rust L1 CAM core, document/engine/IO separation | `crates/cam/Cargo.toml`, `crates/doc/src/document.rs`, `crates/engine/src/manufacturing/`, `crates/io/src/cam/`; workspace layer and Wasm gates enforce dependencies. |
|
||||
| Persistent setups, stock, fixtures, tools, ordered operations and programs | `cam/model.rs` validates definitions, rigid frames, IDs and program membership. The pending manufacturing format extension preserves explicit drilling coordinates; older documents receive empty manufacturing. Engine `save_undo_and_stale_generation`, `legacy_document_has_no_manufacturing`, and reopen tests assert actual values. |
|
||||
| Flat mills/drills with cutting, shank and holder geometry; explicit machining settings | `cam/model.rs`, `generate.rs`, `collision.rs`; cone-depth cases distinguish tip and full-diameter depth. No inferred feeds or spindle speeds. |
|
||||
| CAD bodies, occurrences, planar boundaries and selected holes | Engine snapshot and profile resolution plus `cmd/cam_holes_tests.rs` cover exact occurrence frames, edited profiles, lost/ambiguous references, wrong drill diameters and rejected tilted selections. Native recovery includes lost-profile reselection. |
|
||||
| Shared commands, editing and operation ordering | `engine/cmd/cam.rs` registers editing, generation, status/cancel, inspection, simulation and export commands used by UI/CLI/MCP. `operation_order_survives_reopen_undo_redo_and_controls_generated_sequence` checks two operations, invalid permutations, undo/redo, persistence and actual block order. |
|
||||
| Derived caches and stale/failed posting refusal | Fingerprints include geometry, definitions and generator version. Save/reopen rejects old job IDs; edits invalidate jobs; undo can restore freshness. Tests reject stale, cancelled, failed and inconclusive results, including completed-but-uncollected exports. |
|
||||
| Immutable background generation, progress and cancellation | `engine/manufacturing.rs` tests deferred immutable preparation, worker snapshot release, preparation cancellation and no revival. Browser futures have bounded checkpoints; native preparation and exports run on workers. Native simulation cancellation is exercised. |
|
||||
| Facing, contour offsets, pockets/islands, drilling | `cam/generate.rs` and original `corpus.rs` fixtures plus `corpus/{extended,through,exterior,channel}.rs`: nine recipes, fourteen operation stages. All four strategies also have complete local Fusion packages. |
|
||||
| Direction, depths, allowance, entry, leads, ramps, clearances and deterministic order | Independent posted-NC direction tests in `cam/tests/milling_direction.rs`; multi-stage rough/finish recipes, both contour sides, shifted origins, tool changes, through holes and pecks. Inaccessible necks, oversized tools and protected-geometry lead gouges fail. |
|
||||
| Bounded Cavalier adapter; degeneracy and curve accuracy | Exact `cavalier_contours 0.9.0` pin with finite/size checks, crossing/touch/backtracking rejection, winding/island cases, dense convex/concave and translated/scaled regressions. CAD curve sampling and fixed-tolerance meshing reject exhausted accuracy budgets. See `cam-crates.md`. |
|
||||
| Typed motions/events and provenance | `cam/model.rs`, NC post/reader and engine inspection retain operation/block/record links. `diagnostic_inspection_identifies_posted_operation_and_rejects_stale_results` checks actual NC line, operation and transformed world point. |
|
||||
| Manufacture workspace, tree, dialogs, stock/fixtures, paths and playback | `ui-egui/src/manufacturing.rs` and `ui-egui/tests/cam_workflow.rs`, plus four original native strategy walkthroughs. Playback shows motion and machine state; initial/final stock is displayed. Recovery captures cover reselection, fixture issue location/correction, cancellation and stale edits. |
|
||||
| Adaptive stock simulation; cutter/shank/holder/fixture and rapid checks | `cam/verify.rs`, `collision.rs`, `dimensions.rs`, `surface.rs` use independent NC and conservative bounds. Tests cover thin swept obstacles, stationary overlap, enclosed fixtures/cavities, insufficient cutting length, holder/shank interference and rapid-through-stock. Unknown topology or exhausted budgets remain inconclusive. |
|
||||
| Explicit reference post; arcs and no implicit controller behavior | `cam/nc.rs` initializes units, absolute coordinates, plane, arc-center mode, feed mode, work offset, compensation/cycle cancellation and spindle/coolant state. Drilling is expanded and compensation geometric. `machine_state.rs` checks modal/tool/spindle/coolant semantics independently. Unsupported words fail. |
|
||||
| Five exports with provenance and no stale publication | IO emits NC, toolpath JSON, setup HTML, stock STL and validation JSON. Serializer tests check all JSON fields, HTML escaping and exact NC/STL bytes. Background tests assert no file before collection, single collection, cancellation and stale rejection. Native all-format export and actual system-dialog posting pass. |
|
||||
| Reproducible Fusion packages and clean-room storage | `xtask/src/cam/reference.rs` requires capture identity/version, capabilities, post identity/hash/properties, source geometry, reconciled inputs, NC, setup values/HTML, stock, simulation findings and hashes. All four required local packages are complete. No Fusion-produced files are committed. |
|
||||
| Input equality before comparison | Oracle requires matching stock, frames, tools, operations and budgets, recomputes fingerprints and checks artifact hashes. Mismatches invalidate the case. |
|
||||
| Independent G-code semantics and post round trip | Strict parser consumes every word; hand-authored modal programs, equivalent inch/mm positions, opposite arc sweeps, unknown words and stopped-spindle cuts test semantics. Round trip compares pre-post IR and interpreted NC within 0.001 mm, including state transitions and startup records. |
|
||||
| Machined result and local surface distances | Both programs use the same independent verifier. `compare.rs` compares SolidCraft NC/Fusion NC, SolidCraft NC/Fusion STL, and Fusion NC/Fusion STL directly. Protected geometry and allowed rough stock are checked per stage; finished regions require dimensional pass. Small local gouges cannot be hidden by aggregate volume. |
|
||||
| Verifier qualification and deliberate fault injection | Hand-calculated face volume and drill-cone heights; independent analytic probes, missing cuts/holes, shifted holes, wrong tools/depths, unsafe rapids and malformed meshes. Coverage gaps and unresolved intervals cannot pass. Stock exports are reimported and compared to conservative intervals. |
|
||||
| Setup values, order and metrics | Oracle checks setup/tool/operation values and order, records cutting/rapid distance, retracts, feed-time estimates and volume intervals. HTML includes overlays and line-linked failures; JSON retains findings and provenance. |
|
||||
| Ordinary CI and local oracle gates | `cargo xtask cam-validate` runs nine recipes/fourteen stages in CI. `cargo xtask cam-oracle --dir …` requires all four strategies and fails missing/incomplete packages. Full CI includes formatting, clippy, tests, assets, layers and portable-crate Wasm checks. |
|
||||
|
||||
## Upstream integration
|
||||
|
||||
The historical acceptance below was recorded before rebasing onto upstream.
|
||||
The current integration includes `650ba567` (0.14.0 and subsequent merges) and adopts SolidCraft naming, pending document migrations,
|
||||
copy-on-write sessions, asynchronous file dialogs and the current viewport pipeline.
|
||||
Fresh analytic acceptance passes all nine recipes/fourteen stages. Input reconciliation
|
||||
and the independent oracle were rerun against the same immutable Fusion captures:
|
||||
all four packages pass. The rebased native facing workflow passes generation,
|
||||
simulation, posting, save/reopen and regeneration. Its actual Manufacture window
|
||||
was inspected, including blue cutting paths, amber clearances and Pass/Pass status.
|
||||
First Save changes the design name and conservatively invalidates the prior cache;
|
||||
regeneration restores freshness. On the intermediate `9d82b944` base, formatting,
|
||||
Clippy, assets, layers and the 12-crate Wasm check passed. The full native run found
|
||||
UI integration regressions; their fixes are included, but local reruns were stopped
|
||||
after disk exhaustion and severe host overload. Final validation on `650ba567` is
|
||||
pending in upstream PR #1682. Its initial locked-build failure was corrected for
|
||||
the 0.14.0 release, and profile-sampling tests now cover upstream's degree-9 Beziers.
|
||||
Historical timings and captures alone do not qualify these integration changes.
|
||||
|
||||
## Recorded local acceptance
|
||||
|
||||
The four complete facing/contour/pocket/drill packages pass input reconciliation,
|
||||
both programs' clearance and finished-dimension checks, and all three stock
|
||||
comparisons per case. Acceptance remains **0.01 mm**, with **0.001 mm** post error
|
||||
and **0.0025 mm** verifier uncertainty budgets. The latest report's stock hashes
|
||||
match the current files. Contour/pocket/drill were re-exported at maximum Fusion
|
||||
Stock Accuracy after playback to completion; the user confirmed no collisions.
|
||||
Fusion's unexposed numeric resolution remains `not_reported`, not a fabricated value.
|
||||
|
||||
Local reproducibility locations (deliberately untracked):
|
||||
|
||||
- `plan/fusion/cam/capture-recovered/comparison/report.{json,html}`: four cases,
|
||||
generator `cam/18`, comparator `cam-oracle/2`, post `solidcraft-reference-3axis/2`.
|
||||
- `target/cam-native-acceptance/`: native four-strategy create/generate/simulate/
|
||||
post/reopen/edit/regenerate workflows.
|
||||
- `target/cam-native-recovery/`: reference, collision, cancellation and stale-edit
|
||||
recovery captures. Preparation cancellation is an engine test, not a manual UI claim.
|
||||
- `target/cam-native-export/artifact-manifest.json`: all five background exports.
|
||||
- `target/cam-native-audit/save-acceptance.json`: actual native Save dialog created
|
||||
a 146,348-byte NC file identical to the registered-command export. Job status
|
||||
remained fresh, verified and Pass/Pass with export idle after UI collection.
|
||||
Post-save screenshot capture was unavailable; this does not claim a fresh screenshot.
|
||||
- `target/cam-web-probe/`: original release-Wasm timing and cancellation probes.
|
||||
|
||||
## Bounded scope and computational limits
|
||||
|
||||
Browser execution is cooperative, with finite input, work, motion, mesh and output
|
||||
caps. The four-ms scheduler target is checked between polls, not a hard deadline.
|
||||
Measured opaque steps on the validation machine remain about 21.2 ms for a dense
|
||||
offset, 90.8 ms for a radius-5000 mm body tessellation, and 8 ms for a long single
|
||||
reference encoding. Those are explicit latency limits of this implementation;
|
||||
they do not weaken physical tolerances or permit partial results. Incremental
|
||||
large-artifact probes measured batches at most 4.3 ms. Timings are machine-specific.
|
||||
|
||||
Verification is for vertical height-field machining. It refines uncertainty and
|
||||
fails closed when limits prevent a conclusion. Initial pose is a declared tool-tip
|
||||
position at clearance; travel from an unknown physical machine pose is outside
|
||||
the reference dialect. Final stock display is not animated stock removal at each
|
||||
playback frame. Finishing uses explicit zero-allowance operations after roughing.
|
||||
|
||||
These limits satisfy the bounded first workflow; they are not general Fusion or
|
||||
machine certification. Adaptive clearing, 3D roughing/finishing, indexed/multi-axis
|
||||
machining, turning, additive, inspection and manufacturing extensions remain later
|
||||
or excluded scope. New supported geometry and post dialects need their own fixtures.
|
||||
@@ -0,0 +1,113 @@
|
||||
# CAM crate assessment
|
||||
|
||||
Research date: 2026-10-15. This assessment supplements [the CAM implementation status](cam.md).
|
||||
Versions below are the releases inspected, not a promise that every upstream `latest` page is
|
||||
current. The initial assessment changed no dependencies. Subsequent implementation pinned Parry
|
||||
0.31.1 for collision queries and robust 1.2.0 for independent projected-coverage predicates.
|
||||
Other candidates remain proposals;
|
||||
see the current quality-gate results for target compilation evidence.
|
||||
|
||||
## Recommended order
|
||||
|
||||
| Candidate | Inspected version / license | Proposed use and decision |
|
||||
| --- | --- | --- |
|
||||
| [parry3d-f64](https://docs.rs/parry3d-f64/0.31.1/parry3d_f64/query/index.html) | 0.31.1; [Apache-2.0](https://github.com/dimforge/parry) | Implemented behind a private adapter: distance and swept collision queries refine fixture, holder and shank checks. Conservative fallback remains. |
|
||||
| [proptest](https://docs.rs/proptest/1.12.0/proptest/) | 1.12.0; [MIT OR Apache-2.0](https://github.com/proptest-rs/proptest) | Add as a development dependency for generated cases and shrinking failures to small reproducible examples. |
|
||||
| [stl_io](https://docs.rs/stl_io/0.11.0/stl_io/) | 0.11.0; [MIT](https://github.com/hmeyer/stl_io) | Evaluate for bounded ASCII/binary import and binary stock export. This simplifies file handling; our independent conforming stock boundary extractor supplies the geometry. |
|
||||
| [robust](https://docs.rs/robust/1.2.0/robust/) | 1.2.0; [MIT OR Apache-2.0](https://github.com/georust/robust) | Implemented as a pinned direct dependency for independent stock-mesh coverage and sidedness checks. Exact predicate signs prevent near-collinear coverage errors; guarded plane intervals still account for dimensional uncertainty. |
|
||||
| [static_aabb2d_index](https://docs.rs/crate/static_aabb2d_index/2.1.0) | 2.1.0; MIT OR Apache-2.0 | Already present through Cavalier. Benchmark against the verifier's current XY index before replacing it. Keep unsafe optimizations disabled. |
|
||||
| [gcode](https://docs.rs/gcode/0.7.0/gcode/) | 0.7.0; [MIT OR Apache-2.0](https://docs.rs/crate/gcode/0.7.0) | Useful as a second parser in differential tests. It handles syntax and source spans, not modal machine semantics. Keep SolidCraft's independent interpreter and rejection of unsupported behavior. |
|
||||
|
||||
Keep [cavalier_contours 0.9.0](https://docs.rs/crate/cavalier_contours/0.9.0), already pinned in
|
||||
`solidcraft-cam`. Its [Rust core](https://github.com/jbuckmccready/cavalier_contours) supports
|
||||
line/arc offsets and regions with islands under MIT OR Apache-2.0. It also documents limitations:
|
||||
rounded offset joins, arc segments of at most a half-circle, and nonintersecting closed loops for
|
||||
multi-loop regions. Our bounded adapter and invalid-region tests remain necessary. The adapter now uses explicit
|
||||
1e-8 mm position/join and 1e-7 mm offset-distance tolerances, with a round-island regression
|
||||
that exposed a slice-merging failure under upstream defaults.
|
||||
The six-case corpus also exposed degenerate tangencies in multi-loop offsets. Pocket offsets
|
||||
reserve an additional 0.000001 mm of clearance, within the existing post error budget, while
|
||||
the independent verifier checks the unchanged requested geometry and allowance. Debug builds
|
||||
exercise the concave/two-island recipes as part of `cam-validate`. This is a bounded numerical
|
||||
mitigation, not a general proof of the upstream stitcher: the
|
||||
[0.9.0 release notes](https://github.com/jbuckmccready/cavalier_contours/releases)
|
||||
say the shape offset algorithm has not received the polyline stitching update, and
|
||||
[issue 66](https://github.com/jbuckmccready/cavalier_contours/issues/66) records threshold/tangency
|
||||
limitations. Keep the pin, native error guard and impossible-region checks; do not adopt a new
|
||||
geometry dependency or disable debug assertions to hide these failures.
|
||||
|
||||
A 2026-10-16 original 10,000-vertex circle also exposed a short-segment cross-product
|
||||
threshold failure. The adapter now normalizes coordinates by an exact power of two and
|
||||
scales physical distance tolerances with them, then restores output to millimetres. It
|
||||
retains every input vertex. Native debug regressions cover dense convex/concave offsets,
|
||||
shifted/scaled coordinates and independent distance expectations. The release-Wasm dense
|
||||
concave probe still measured a 21.2 ms atomic offset batch, an explicit scheduling limit
|
||||
recorded in the [acceptance audit](cam-acceptance.md).
|
||||
|
||||
## Portability and integration
|
||||
|
||||
- **Parry:** use double precision and a private adapter from SolidCraft geometry types. The
|
||||
inspected API uses its own math types; avoid exposing these in persisted models. Start with
|
||||
sequential queries and no optional Rayon feature. Native and `wasm32-unknown-unknown` compilation,
|
||||
dependency/license review, and bounded execution measurements are adoption gates. The upstream
|
||||
[manifest](https://github.com/dimforge/parry/blob/master/crates/parry3d-f64/Cargo.toml) exposes
|
||||
optional parallelism and enhanced determinism; exact release features must be pinned and tested.
|
||||
- **Proptest:** keep it out of runtime dependencies. Native CI can run the broad randomized suite.
|
||||
Browser tests need a separate feature configuration: its [defaults](https://docs.rs/crate/proptest/1.12.0/features)
|
||||
include process-based fork/timeout functionality. Save seeds and minimized regressions.
|
||||
- **STL:** use memory readers/writers in the portable layers. Enforce our byte/triangle caps and
|
||||
finite-value checks around the library. Measure float serialization error against the artifact
|
||||
tolerance budget. A portable I/O abstraction alone is not evidence of a passing Wasm build.
|
||||
- **Existing geometry crates:** `robust 1.2.0`, `spade 2.15.1`, and `static_aabb2d_index 2.1.0` are
|
||||
already in this worktree's lockfile and were included in the previous workspace Wasm gate.
|
||||
Any new direct adapter still needs its own tests.
|
||||
- **G-code:** the crate explicitly targets no-std/WebAssembly. Treat any parser diagnostic as a
|
||||
rejection in validation; error recovery must never silently remove machine behavior.
|
||||
|
||||
## Other candidates
|
||||
|
||||
[spade 2.15.1](https://docs.rs/spade/2.15.1/spade/) provides constrained 2D triangulation and
|
||||
already exists transitively. The 2026-10-16 meshing profile justified using its `bulk_load_cdt`
|
||||
API for empty boundary triangulations, replacing expensive sequential point location. The vendor
|
||||
manifest now requires at least the inspected 2.15.1 release. No constraints are passed during
|
||||
bulk loading; rounded positions (including duplicates and signed zero) map back to vertex
|
||||
handles before the existing constraint insertion loop. Nonempty or failed loads retain the
|
||||
sequential path. The installed release's API documentation and implementation were inspected;
|
||||
workspace native/Wasm gates and analytic kernel tests exercise the adapter. Combined with an
|
||||
original conservative boundary candidate index, the original large-cylinder browser measurement
|
||||
fell from about 1087 ms to 91 ms without changing its measured chord error or triangle count.
|
||||
This is a concrete reuse of an existing dependency, not a new mesh Boolean or solid-boundary
|
||||
library. It does not supply stock side-wall stitching; the remaining atomic browser latency
|
||||
is recorded in the acceptance audit.
|
||||
|
||||
[rstar](https://docs.rs/crate/rstar/0.13.0) is an alternative spatial index. Defer an additional
|
||||
index dependency until profiling shows a need beyond the existing XY index or Parry's structures.
|
||||
|
||||
[csgrs](https://github.com/timschmidt/csgrs) is MIT licensed and worth a separate mesh-Boolean
|
||||
experiment, but is not a recommended dependency for this milestone yet. The inspected
|
||||
[published 0.20.1 documentation](https://docs.rs/crate/csgrs/0.20.1) describes BSP operations,
|
||||
while the current repository describes a substantially different Hypermesh/Hypercurve stack and
|
||||
0.23.0 API. Resolve the exact published release and audit its dependency graph before evaluating
|
||||
it. Neither upstream feature claims nor a successful Boolean operation establish our CAM error
|
||||
budget or performance at hundreds of thousands of cells.
|
||||
|
||||
## Concrete adoption experiments
|
||||
|
||||
1. **Collision refinement:** cast the cutter, shank and holder against fixture triangles. Cover
|
||||
a clear near miss, grazing contact, an initial overlap, a thin obstacle crossed between
|
||||
endpoints, shifted setup frames, and degenerate triangles. Linear shape casts fit fixed-axis
|
||||
motions; arc subdivision needs conservative inflation for chord error. Unsupported shape
|
||||
pairs and numerical failures remain inconclusive. Preserve operation, motion and NC-line IDs.
|
||||
2. **Generated tests:** exercise winding reversal, translation, inch/mm equivalence, post
|
||||
round trips, cancellation boundaries, non-finite values, malformed NC, and budget exhaustion.
|
||||
Cross-check indexed candidate sets against brute force on small fixtures.
|
||||
3. **Stock artifacts:** round-trip ASCII and binary STL against analytic solids, reject malformed
|
||||
and oversized files, and compare sizes. Independently implement or qualify conforming surface
|
||||
extraction; verify edge incidence, orientation, volume and local surface error. A valid STL
|
||||
container is insufficient evidence of a watertight stock mesh.
|
||||
4. **Interpreter independence:** compare parser tokens/spans on the supported dialect, then use
|
||||
hand-calculated machine-state expectations and deliberate faults. Never reuse toolpath
|
||||
generation algorithms as the semantic oracle.
|
||||
|
||||
These crates reduce implementation effort. Broader dimensional and uncertainty coverage,
|
||||
and complete Fusion reference captures still require project-specific work.
|
||||
@@ -0,0 +1,92 @@
|
||||
# Adaptive clearing and 3D milling
|
||||
|
||||
Status: planned implementation following the first milling PR. The strategies and
|
||||
ball-end tooling below are not implemented or qualified yet.
|
||||
|
||||
## Scope and delivery order
|
||||
|
||||
Retain vertical, fixed-axis three-axis machining, rectangular stock, rigid setups,
|
||||
explicit feeds/speeds and fail-closed posting. Indexed/multi-axis work and physical
|
||||
controller qualification remain outside scope.
|
||||
|
||||
1. **Tool and verifier foundation.** Add ball-end mills with explicit cutting length,
|
||||
shank and holder dimensions, a pending document migration, command/UI editing and
|
||||
tool-tip semantics. Qualify swept spherical cutting envelopes independently on
|
||||
stationary, horizontal and sloping motions, including holder/shank clearance.
|
||||
2. **Adaptive clearing.** Introduce explicit optimal load, maximum stepdown, entry
|
||||
and linking settings. Maintain material state during planning; bound actual radial
|
||||
engagement through corners and narrow passages. Generate smooth clearing loops
|
||||
with proved entry/link clearances. Ordinary offset pocketing is not adaptive clearing.
|
||||
3. **3D roughing.** Slice the protected target at bounded Z levels, include radial
|
||||
and axial stock allowances, and support rest roughing from a fingerprinted preceding
|
||||
stock state. Reject unsupported undercuts, uncertain topology and inaccessible
|
||||
regions. Removed material must never be inferred solely from a preceding path's name.
|
||||
4. **3D finishing.** Deliver parallel finishing for shallow surfaces and constant-Z
|
||||
finishing for steep surfaces, with ball tools, cutter-contact offsets, bounded
|
||||
chord error and explicit cusp/stepover settings. Scallop finishing follows only
|
||||
after its surface-spacing and connector bounds are independently qualified.
|
||||
5. **Integrated acceptance.** Exercise editing, generation/cancellation, simulation,
|
||||
diagnosis, exports, save/reopen and stale-result refusal through commands and the
|
||||
visible Manufacture workspace. Keep portable jobs incremental and bounded.
|
||||
|
||||
## Independent validation
|
||||
|
||||
Keep the generator, NC interpreter and stock verifier separate. Extend typed motions
|
||||
and provenance only where required; preserve the reference post's initialized machine
|
||||
state and reject unsupported controller behavior. Inspect every emitted NC block.
|
||||
|
||||
Original fixtures cover a sloped plane, convex dome, concave bowl, saddle, stepped
|
||||
boss, steep wall, islands connected by a narrow neck, interrupted cuts, rest stock,
|
||||
shifted origins and tool changes. Each fixture declares protected surfaces, allowed
|
||||
rough stock, finished regions, accessibility and independent dimensional expectations.
|
||||
Hand-calculated sphere-plane contact and cusp-height cases qualify the verifier first.
|
||||
Fault injections include the wrong ball radius, omitted roughing stock, excess
|
||||
engagement, reversed arcs, connecting gouges, rapid-through-stock and holder contact.
|
||||
|
||||
Acceptance retains 0.01 mm dimensional tolerance, 0.001 mm post/interpolation budget
|
||||
and 0.0025 mm verifier uncertainty. Local surface distances and hole/wall dimensions
|
||||
accompany volume differences. Refine uncertain regions; exhausting resources yields
|
||||
inconclusive and blocks posting. For roughing, verify protected geometry and allowed
|
||||
stock per operation instead of requiring identical intermediate material removal.
|
||||
Engagement checks report their definition, sampling/bound uncertainty and the NC line.
|
||||
|
||||
## Fusion comparison packages
|
||||
|
||||
Use the same original recipes in local Fusion and SolidCraft. Reconcile units, tools,
|
||||
stock, frames, allowances, entry/links and operation settings before comparison.
|
||||
Record version, available capabilities, post identity/hash/properties and timestamps.
|
||||
Capture NC Program output, setup HTML and final simulation stock after every operation;
|
||||
use Save Stock when automated export is unavailable. Preserve the actual Accuracy
|
||||
setting and report an unexposed numeric resolution as not reported.
|
||||
|
||||
Both posted programs pass through the independent interpreter and verifier. Compare
|
||||
each against intended geometry and Fusion stock, with line-linked diagnostics, path
|
||||
overlays, surface differences, volume, distance, retract count and time estimates.
|
||||
Missing artifacts or unavailable licensed strategies cannot count as passing parity.
|
||||
Require complete passing packages for each delivered strategy before declaring parity.
|
||||
All Fusion-produced artifacts and derived comparisons stay in ignored local storage;
|
||||
commit only original recipes, harness code and independently authored expectations.
|
||||
|
||||
## Dependency decisions
|
||||
|
||||
Keep the existing pinned Cavalier 0.9.0 adapter for planar offsets/islands and Parry
|
||||
0.31.1 for bounded collision/distance queries. Both need geometry-specific guards;
|
||||
neither provides an adaptive machining algorithm or an independent stock proof.
|
||||
Cavalier documents rounded joins and arc-size constraints; retain current degeneracy
|
||||
and scale tests. Parry's double-precision mesh and point-query APIs are candidates for
|
||||
cutter-contact acceleration; benchmark against a simple original implementation first.
|
||||
No additional runtime dependency is justified yet. Reuse the existing robust predicates,
|
||||
Spade and spatial index; consider property testing as a development-only dependency.
|
||||
|
||||
Primary references inspected on 2026-10-16:
|
||||
|
||||
- [Autodesk adaptive roughing overview](https://help.autodesk.com/cloudhelp/ENU/Fusion-CAM/files/3D-ADAPTIVE-READ.htm)
|
||||
- [Autodesk adaptive parameters](https://help.autodesk.com/cloudhelp/ENU/Fusion-CAM/files/GUID09E44604-DAD8-47D6-ADC6-C100869DE724.htm)
|
||||
- [Autodesk parallel finishing](https://help.autodesk.com/cloudhelp/ENU/Fusion-CAM/files/3D-PARALLEL-STEPS.htm)
|
||||
- [Cavalier 0.9.0](https://docs.rs/crate/cavalier_contours/0.9.0)
|
||||
- [Parry 0.31.1 triangle mesh](https://docs.rs/parry3d-f64/0.31.1/parry3d_f64/shape/struct.TriMesh.html)
|
||||
- [Parry 0.31.1 point queries](https://docs.rs/parry3d-f64/0.31.1/parry3d_f64/query/point/trait.PointQuery.html)
|
||||
|
||||
Each implementation arc runs focused analytic/fault tests, then repository quality
|
||||
and Wasm gates. The oracle command must require the strategies actually claimed by
|
||||
that milestone, without relaxing the first milestone's completeness requirements.
|
||||
+598
@@ -0,0 +1,598 @@
|
||||
# Three-axis milling and independent validation
|
||||
|
||||
The planned first milling workflow is implemented and its four-strategy Fusion comparison
|
||||
gate passes. See the [requirement-to-evidence audit](cam-acceptance.md) for scope, tests and
|
||||
recorded limitations. This is not parity with all Fusion CAM features. No output is qualified
|
||||
for a physical machine controller.
|
||||
|
||||
## Architecture and commands
|
||||
|
||||
`solidcraft-cam` is pure Rust at L1 and depends on geometry. The document persists manufacturing
|
||||
through the pending `manufacturing` format extension. Older designs receive an empty
|
||||
manufacturing section; drilling coordinates remain explicit without inferred associations. Generated paths and
|
||||
verification results are session caches and are deliberately absent from saved designs.
|
||||
The engine resolves bodies, explicit occurrence paths and durable sketch-profile curve identities
|
||||
into immutable snapshots in setup coordinates. Missing or ambiguous references require reselection.
|
||||
Any document or pending occurrence-placement edit makes the cached job stale; undo can restore it.
|
||||
|
||||
The Manufacture workspace, CLI and MCP share these registered commands:
|
||||
|
||||
| Command | Input / behavior |
|
||||
|---|---|
|
||||
| `cam.setup.put` | `{setup: Setup}`: rectangular stock, right-handed rigid frame, model/fixture references, clearance, retract, G54–G59 |
|
||||
| `cam.tool.put` | `{tool: Tool}`: document-local center-cutting flat mill or twist drill, cutting/shank/holder dimensions |
|
||||
| `cam.holes.from_selection` | `{setup,selections}`: ordered cylindrical-face/circular-profile picks; returns centers, diameters and persistent sources |
|
||||
| `cam.boundary.from_profile` | `{setup, sketch, profile, occurrence?}`: returns sampled boundary and durable source reference |
|
||||
| `cam.operation.put` | `{operation: Operation}`: face, contour, pocket or drill; explicit feed, plunge, spindle and depth settings |
|
||||
| `cam.program.put` | `{program: {id,name,setup,operations}}`: ordered operations, one setup/work offset |
|
||||
| `cam.operation.order` | `{program, operations}`: permutation of existing operations |
|
||||
| `cam.delete` | `{kind,id}`: refuses removal while referenced |
|
||||
| `cam.generate` | `{program, background?}`: immutable job; returns job ID/status |
|
||||
| `cam.job.status`, `cam.job.cancel` | `{job}` |
|
||||
| `cam.inspect` | `{job?, include_path?, include_stock?, motion?, finding?}`: world-space stock display mesh and machine state after the requested number of motion blocks |
|
||||
| `cam.simulate` | `{job, background?}`: independent post round trip and stock/clearance checks |
|
||||
| `cam.post` | `{job,path?,background?}`: requires fresh generated paths and passing verification |
|
||||
| `cam.export` | `{job,format,path?,background?}`: `toolpath`, `setup_sheet`, `stock`, `validation` |
|
||||
| `cam.export.result` | `{job}`: consumes completed background output after checking freshness; writes its requested path or returns content |
|
||||
|
||||
UI export and posting use background jobs: a native worker or the browser's cooperative scheduler
|
||||
builds the complete artifact from the immutable snapshot. `cam.job.status` includes an `export`
|
||||
state (`idle`, `running`, `ready`, `failed`, `cancelled`). `cam.export.result` rechecks document and
|
||||
occurrence freshness before consuming output and atomically writing the requested destination.
|
||||
No file is written before this collection command. Cancellation returns no partial artifact;
|
||||
`cam.job.cancel` cancels the job, including its export. One pending/ready export per job is allowed.
|
||||
The UI collects completion through that same command and displays export progress and errors.
|
||||
Programmatic calls default to the existing synchronous behavior. JSON values and stock geometry
|
||||
are preserved; incremental JSON can use different whitespace and object-key order. Artifacts are
|
||||
bounded to 128 MiB; exhausted output budgets fail explicitly.
|
||||
|
||||
All dimensions are mm; speeds are mm/min and rpm; angles in the command model are radians.
|
||||
The UI displays tool and ramp angles in degrees. IDs must be nonzero and unique per item kind.
|
||||
See the serializable types in `crates/cam/src/model.rs` and original fixtures in
|
||||
`crates/cam/src/corpus.rs` for complete payloads. Without a path, exports return `content`.
|
||||
|
||||
Facing cuts stock with raster passes. Contouring uses geometric inside/outside cutter-radius
|
||||
offsets. Pocketing uses successive offsets, handles islands, and retracts between loops.
|
||||
Drilling expands every peck into ordinary motions and distinguishes tip depth from full-diameter
|
||||
depth. Contours/pockets can use tangential leads and feed-controlled ramps. Allowance means stock
|
||||
to leave; use a separate zero-allowance operation for finishing. Flat mills are explicitly assumed
|
||||
to be center cutting. Entry/lead collisions are checked during simulation, before posting.
|
||||
|
||||
The reference spindle rotates clockwise (M3) with right-handed cutters. Climb milling keeps
|
||||
the finished material to the right of travel: counterclockwise inside walls, clockwise around
|
||||
external bosses and pocket islands. Facing advances rows in +Y and cuts toward -X for climb;
|
||||
conventional reverses each cutting direction. Full-width entry can engage both sides of the
|
||||
cutter. Independent tests interpret posted NC and check travel direction and signed loop area
|
||||
for both settings and both input windings. The convention follows the
|
||||
[Haas mill programming workbook](https://www.haascnc.com/content/dam/haascnc/videos/bonus-content/ep81-essential-9-lines/programming-workbooks/mill---programming-workbook.pdf),
|
||||
printed pages 51 and 61. Generator version `cam/14` invalidates paths made with the earlier
|
||||
reversed direction settings; regenerate and simulate before posting.
|
||||
|
||||
Offsets use exactly `cavalier_contours 0.9.0` (MIT OR Apache-2.0) behind bounded input checks.
|
||||
Crossing/touching loops, nested islands, oversized tools, non-finite values and exceeded budgets
|
||||
are errors. The offset adapter uses 1e-8 mm position/join and 1e-7 mm distance tolerances;
|
||||
these avoid merging small distinct slices in round-island pockets with upstream defaults.
|
||||
Boundary validation queries an edge spatial index instead of charging every possible edge pair
|
||||
against its work budget. Crossings, near touches and adjacent backtracking still fail; candidate
|
||||
work remains capped, with cancellation checkpoints during construction, queries and containment.
|
||||
The offset adapter scales coordinates by a power of two so the shortest edge is at least one
|
||||
library unit, and scales distance tolerances by the same factor. This avoids the library treating
|
||||
short nonparallel segments as parallel through its cross-product epsilon. It removes no vertices
|
||||
and restores output to millimetres; the original input remains the independent verifier's target.
|
||||
Dense convex/concave, reversed-winding, translated/scaled and 100-island regressions cover the
|
||||
adapter. Output retains operation IDs, machine events and linear/planar-arc motions.
|
||||
|
||||
## Reference NC dialect
|
||||
|
||||
The post emits tool-tip coordinates, three linear axes, absolute mm positioning, XY arcs with
|
||||
incremental I/J centers, units-per-minute feed and geometrically applied cutter compensation.
|
||||
Post version `solidcraft-reference-3axis/2` explicitly initializes
|
||||
G21/G90/G17/G91.1/G94/G54–59/G40/G49/G80 and stops the spindle and coolant with M5/M9
|
||||
before the declared initial pose. It emits tool/spindle/coolant events,
|
||||
and expands drilling. Startup is a declared position at clearance; physical travel to that
|
||||
initial pose is outside this reference dialect's contract. There is no machine kinematics,
|
||||
G28/G53 homing, length offset activation, canned cycle or controller-specific behavior.
|
||||
|
||||
The separate NC reader consumes every word and rejects unsupported commands. It supports G20
|
||||
and G91 for comparison, but requires complete absolute XYZ for the initial pose. Modal groups,
|
||||
units, feed, tool changes, spindle state, planar arc radii and program termination are checked.
|
||||
M6 stops the spindle, preserves coolant and the programmed speed, and requires a subsequent
|
||||
M3 before cutting. Speed words take effect before motion and alongside coolant/stop commands.
|
||||
Program end includes spindle/coolant shutdown in the interpreted event stream. Hand-authored
|
||||
modal programs check these transitions and reject cutting with a stopped spindle. The post
|
||||
round trip checks its three startup events separately, without assigning them an operation;
|
||||
subsequent motions are compared against the pre-post typed IR with a 0.001 mm error budget.
|
||||
|
||||
Semantics reference: [NIST RS274/NGC](https://tsapps.nist.gov/publication/get_pdf.cfm?pub_id=823374).
|
||||
The reader is a deliberately strict subset, not a general RS274 interpreter.
|
||||
|
||||
## Verification and present limits
|
||||
|
||||
The independent verifier uses adaptive XY cells with conservative lower/upper stock heights,
|
||||
flat-mill or drill-cone removal, local target-surface checks, and swept rapid/shank/holder bounds.
|
||||
Fixture checks use pinned `parry3d-f64 0.31.1` (Apache-2.0): separate cutter, drill cone, shank and
|
||||
holder shapes are swept against fixture triangles. Initial-distance and closed-volume winding
|
||||
checks catch stationary contact and tools already inside fixtures. Body groups preserve enclosed
|
||||
cavities and prevent opposite winding in separate fixtures from cancelling. Open/nonmanifold
|
||||
meshes, clearance within the interpolation/refinement margin, and failed numerical queries remain
|
||||
**inconclusive**. It does not call offset or toolpath-generation algorithms and observes cancellation
|
||||
during topology preparation and collision queries. The current algorithm fingerprint is `cam/18`;
|
||||
the geometry and tessellation changes invalidate older generated/verified caches.
|
||||
No target fitting, translation, unit guessing or discarded unknown NC commands is allowed.
|
||||
|
||||
Default dimensional tolerance is 0.01 mm; interpolation/post error is 0.001 mm; requested spatial
|
||||
refinement is 0.0025 mm. Reports distinguish requested refinement from the actual maximum stock
|
||||
height interval. Limits are 250,000 cells and 30 million work units by default. Exhaustion or an
|
||||
unresolved collision blocks posting. Remaining-stock volume is an interval, not an exact number.
|
||||
|
||||
Stock STL contains a conforming conservative exterior of the upper height envelope. Shared edges and
|
||||
vertical steps are split, internal walls are removed, and every edge and vertex link is checked
|
||||
for a closed, consistently oriented manifold. Coplanar cells merge exactly without resampling.
|
||||
Vertical drill cones use exact rectangular-cell radial extrema. Adaptive cells can still create
|
||||
tiny saddle contacts: export may fill these upward by at most 0.00001 mm per cell, with no XY
|
||||
snapping or removed material. This declared artifact budget does not alter simulation intervals;
|
||||
analytic artifact checks independently compare the resulting STL against those intervals.
|
||||
Exports are bounded to 60,000 merged cells, 500,000 triangles and 128 MiB. Larger or unresolved
|
||||
non-manifold contacts are rejected explicitly; validation JSON retains the cell intervals. `stock_complete` is
|
||||
false after verification budget exhaustion, which blocks export of a misleading partial stock.
|
||||
A watertight upper-bound mesh does not establish finished-part dimensional accuracy.
|
||||
|
||||
Stock comparisons require declared stock bounds and exact, non-overlapping cell coverage. Older
|
||||
reports without bounds remain inconclusive. Imported reference meshes must be closed, consistently
|
||||
oriented manifolds within those bounds, with downward faces only on the stock bottom. Unsupported
|
||||
undercuts, reversed faces, degenerate triangles and out-of-frame vertices are rejected. Projection
|
||||
coverage uses boundary incidence and pinned `robust 1.2.0` orientation predicates, not sums of
|
||||
triangle areas. Duplicate or overlapping faces cannot counterfeit coverage. Extremely small nonzero
|
||||
XY coordinates below 1e-100 are rejected to avoid predicate underflow; coordinates are never snapped.
|
||||
|
||||
The comparator independently bounds reference heights from triangles, reusing only the validated
|
||||
spatial partition before further adaptive subdivision. It certifies whole-column distances for
|
||||
both remaining material and removed space, in both directions, including the stock exterior.
|
||||
This resolves narrow uncertainty bands at vertical walls without concealing an omitted deep hole.
|
||||
Failures require a definitely present material/void point farther than tolerance from all possible
|
||||
corresponding columns; inconclusive intervals are not failures. Distance maxima describe examined
|
||||
regions; a certified failure may stop at its first witness. Cell/work exhaustion remains inconclusive.
|
||||
Tests include independent analytic round holes, alternate facet layouts, generated drilling-stock
|
||||
round trips, shifted walls, missing holes, incomplete coverage and malformed reference meshes.
|
||||
|
||||
The current passing verification status certifies the implemented no-gouge/clearance checks.
|
||||
The separate `finished_dimensions` status certifies facing planes, analytic drill cylinders/cones,
|
||||
pocket floors and islands, and the selected side of contour walls. The milling verifier uses
|
||||
independent robust winding and point-to-segment distances, with whole-cell signed-distance bounds;
|
||||
it never calls the generator's offset functions. A contour must finish its selected wall and floor
|
||||
within one tool radius of the allowance boundary. Farther stock on the cutting side may remain as
|
||||
roughing stock; it cannot be cut below the specified floor. A pocket must clear its full selected
|
||||
interior to the allowance floor while preserving its islands and outer wall.
|
||||
|
||||
The radial tolerance band reserves half the dimensional tolerance for paired-wall/diameter error,
|
||||
then subtracts the post/interpolation budget. Associated CAD profiles also reserve their chord-error
|
||||
budget, at most 0.0005 mm (and at most 1/16 of operation tolerance), during engine sampling and
|
||||
independent certification. Requested features drive adaptive refinement even if the NC omits them.
|
||||
Multiple operations compose by taking the minimum permitted remaining-height envelopes.
|
||||
Drilling requires zero stock allowance: use explicit depth, since drill paths do not apply milling
|
||||
allowance. Sharp inaccessible internal corners, omitted islands, wrong tools/depths and shifted
|
||||
paths fail dimensional validation and block posting. Exhaustion and unresolved bounds stay
|
||||
inconclusive. Posting requires both clearance and finished dimensions to pass and complete stock.
|
||||
|
||||
Motion queries use an independent XY index and retain original sequence IDs for withdrawals and
|
||||
machine-state checks. Exact item bounds exclude irrelevant candidates; shank/holder radii remain
|
||||
included whenever those components can reach stock. Region predicates have bounded work and
|
||||
cooperative cancellation. The analytic contour/pocket recipes now use an original 128-sided round
|
||||
boundary and matching protected walls/floors; they no longer rely on a plane-only square smoke test.
|
||||
Constant-height and vertical mill sweeps use rectangular-cell lateral bounds: the segment's
|
||||
bounding box tightens minimum distance, and convexity bounds maximum distance at the four corners.
|
||||
This avoids artificial overlap from circumscribed disks along straight walls. Sloping moves retain
|
||||
the common-disk height bound; neither tolerances nor resource limits are relaxed.
|
||||
|
||||
Protected height-field boundaries use local spatial certificates. A conservative upper target
|
||||
height at a neighboring XY point bounds distance to the outside of the protected solid for an
|
||||
entire potentially removed cell column. A gouge is reported only with a definitely removed point
|
||||
inside a protected volume by more than tolerance. Clearance reserves 0.001 mm post/interpolation
|
||||
error plus the 0.0025 mm verifier budget; CAD tessellation uses half that verifier budget as a fixed physical tolerance. It bypasses the
|
||||
display mesher's size-dependent tolerance floor and planar display reprojection. Exhausted edge
|
||||
or surface refinement, non-finite evaluations, missing faces and excessive triangle output fail
|
||||
preparation instead of accepting a coarser or partial target. The original large-cylinder
|
||||
regression (radius 5000 mm) previously had 0.00954 mm radial chord error for a 0.00125 mm
|
||||
request; the verification path reduces it below 0.00125 mm, including through engine snapshot
|
||||
preparation. These checks expose known mesher fallbacks; they are not an analytic approximation
|
||||
proof for arbitrary oscillatory surfaces.
|
||||
Queries use an independent XY index, observe work limits and cancellation, and leave unsuccessful
|
||||
certificates explicitly inconclusive with a `protected_surface_unresolved` finding.
|
||||
|
||||
The original drilling fixture now contains the plate top, hole wall and cone, replacing its former
|
||||
plane-only protected target. Tests cover boundary clearance, shifted-hole and through gouges,
|
||||
sloping surfaces, overlapping projected targets and large-coordinate precision. A native CAD
|
||||
drilled body also passes create/generate/simulate/post/save/reopen through registered commands.
|
||||
This does not establish qualification of arbitrary non-height-field solids.
|
||||
Native CAD pocket and contour workflows also pass through durable sketch-profile references,
|
||||
ramp entry, generation, simulation, posting and save/reopen. All four analytic strategies now
|
||||
require passing finished-dimension checks; independent point probes supplement those certificates.
|
||||
The Fusion oracle requires the same dimensional checks for both programs. Current acceptance
|
||||
evidence and supported limits are:
|
||||
|
||||
- Nine analytic recipes / fourteen operation stages cover concave regions, two islands, a narrow
|
||||
channel, allowances, multiple depths/tools, shifted origins and blind/through drilling. Deliberate
|
||||
faulty programs check missing cuts, protected material, unsafe leads and inaccessible channels.
|
||||
- Fixture regressions cover thin swept obstacles, initial overlap, enclosed volumes and cavities,
|
||||
holder/shank interference, malformed/open meshes and cancellation. Supported stock/model geometry
|
||||
remains vertical height-field scope. Fixture triangles must form closed consistently wound bodies
|
||||
for volume-containment certification; surface contact can still be detected on an open mesh.
|
||||
- Background jobs yield during preparation, boundary validation, between offset queries and every
|
||||
256 emitted motions, as well as during verification, NC round trips, fingerprint encoding and
|
||||
conforming stock extraction. The browser shares a four-ms scheduling target across jobs in
|
||||
round-robin order; status queries advance one checkpoint. This target is checked between polls,
|
||||
so it is not a hard deadline. Measured dense offset, large-body tessellation and long-reference
|
||||
encoding remain atomic for about 21.2, 90.8 and 8 ms respectively on the documented browser.
|
||||
The previously synchronous export path is now incremental: original large export probes measure
|
||||
batches at most4.3ms, with no batch above16ms; direct synchronous command calls remain atomic.
|
||||
The measured geometry calls above remain explicit scheduling limits, not a hard deadline.
|
||||
Native background jobs perform profile sampling, tessellation, transforms and hashing on the
|
||||
worker from an immutable snapshot. Synchronous command calls remain available. Status distinguishes
|
||||
`preparing` from `running`; the fingerprint is null until preparation completes. Cancellation
|
||||
cannot publish a partial path or revive a cancelled job.
|
||||
- Associated CAD curves use second-derivative chord-error bounds after placement, including a
|
||||
numerical reserve and a shared 10,000-vertex boundary limit. Requests exceeding precision or
|
||||
vertex budgets fail explicitly rather than silently loosening the operation tolerance.
|
||||
- The four initial local Fusion reference cases pass. Native desktop walkthroughs cover each
|
||||
strategy through generation, simulation, posting through the system save dialog, save/reopen/
|
||||
edit/regenerate, stock display and playback. Eight additional recovery captures cover lost-profile
|
||||
reselection, line-linked fixture collisions and correction, simulation cancellation and stale
|
||||
feed edits followed by regeneration. Preparation cancellation is covered by an engine regression;
|
||||
it was not manually clicked during that walkthrough.
|
||||
- The [completed acceptance audit](cam-acceptance.md) maps the original requirements to
|
||||
implementation and concrete assertions, including multi-operation ordering and native saving.
|
||||
|
||||
The first milling milestone is complete within these declared limits. The passing reference
|
||||
corpus is evidence for its recorded fixtures, not qualification of arbitrary parts or physical
|
||||
controllers.
|
||||
|
||||
## Reproducible comparisons
|
||||
|
||||
Run `cargo xtask cam-validate`. Original analytic recipes generate input snapshots, canonical paths,
|
||||
NC, stock, setup sheets, validation JSON and an HTML report under ignored `target/cam-validation/`.
|
||||
Nine recipes cover the four initial strategies, a rounded concave pocket with two islands,
|
||||
a four-operation facing → roughing → finishing → peck-drilling program with multiple tools and
|
||||
a shifted G55 setup, two clamped through holes, an external square-boss contour and a narrow capsule channel. The harness
|
||||
verifies prefixes of the actual complete program after every operation, including roughing
|
||||
allowance, coolant transitions and conventional finishing. All fourteen
|
||||
stages require protected-surface, dimensional, point-probe and independent exported-STL checks.
|
||||
The new target surfaces have independently calculated volume expectations; deleting islands,
|
||||
omitting finishing, choosing the wrong tool or changing the work offset must fail. Reports link
|
||||
each stage's NC diagnostics, setup sheet and stock, and include tool order, retract count, cutting
|
||||
and rapid distance, feed-time estimate and a remaining-volume interval. Analytic checks
|
||||
run in ordinary CI and `cargo xtask ci`. Core tests include modal state, inch/mm equivalence, wrong
|
||||
arc direction, deliberate gouges/unsafe rapids, shank interference, fixture overlap, geometry errors,
|
||||
islands, ramps and cancellation. Engine tests cover save/reopen, undo and stale-result rejection.
|
||||
Post validation also compares arc sweeps: a tiny arc rounding to coincident endpoints must not
|
||||
become a full circle. Generated arcs shorter than 0.00025 mm become lines, bounded by their total
|
||||
arc length. Shared reference-mesh edges do not cause false interior height discontinuities;
|
||||
positive-area overlaps retain both heights even for extremely thin regions.
|
||||
|
||||
The through-hole recipe uses both simple and peck drilling with full-diameter depth below the
|
||||
stock bottom, a closed raised clamp between the axes, and an independently calculated perforated
|
||||
plate target. Tests reject missing breakthrough, insufficient cutting length and a rapid crossing
|
||||
the clamp at Z7, identifying its NC line. The external-contour recipe uses a reversed square
|
||||
boundary, four depth passes, tangential leads, ramp entry, 0.2 mm roughing allowance and a separate
|
||||
conventional finish. Wrong-side cutting and omitted finishing cannot pass. The final external
|
||||
contour uses 243,154 cells in the current native run, below the unchanged 250,000-cell default;
|
||||
larger jobs can still return inconclusive when their declared budgets are exhausted.
|
||||
|
||||
The narrow-channel recipe has a 2.2 mm width, 10 mm between semicircle centers and a 1 mm
|
||||
cut depth in a 20 × 20 × 6 mm plate. Its R1.1 ends use 64 original polygon segments per
|
||||
semicircle; a 2 mm cutter must finish the floor and both walls while preserving the surrounding
|
||||
plate. An independent polygon-area formula checks target volume, and point probes check both
|
||||
ends, the center and protected stock. Negative regressions reject a 2.4 mm cutter, detect uncut
|
||||
material in a 1.6 mm neck between accessible R2 lobes, and reject a 5 mm lead that gouges the
|
||||
original target. The lead failure retains its operation/motion/NC-line attribution. These cases
|
||||
exercise the unchanged dimensional, clearance and posting gates; they are original analytic
|
||||
evidence and do not count as additional Fusion reference captures.
|
||||
|
||||
Run `cargo xtask cam-oracle --dir plan/fusion/cam/oracle` for local Fusion packages. The harness
|
||||
requires separate `face`, `contour`, `pocket`, `drill` directories. Missing evidence is a failure
|
||||
to establish parity, never a skipped pass. Each directory requires:
|
||||
|
||||
- `manifest.json`: nonempty `fusion_version`, `captured_at`, `input_fingerprint`,
|
||||
`post_identity`, SHA-256 `post_sha256`, and `capture_complete: true` only after actual capture.
|
||||
`capabilities` records a nonempty `license` string and an array of available `strategies`.
|
||||
`source_geometry` names the captured source file inside the package (for example `source.step`).
|
||||
`artifact_sha256` maps every required artifact below, including source geometry and both input
|
||||
snapshots, to its SHA-256 hash. Hashes bind the captured set and reject stale replacements;
|
||||
they do not establish that the input transcription or original capture was correct.
|
||||
- `post.cps`, `post-properties.json`, `input.json`, independently captured `reference-input.json`.
|
||||
Input snapshots must match exactly, including frames, geometry, tools, allowance and settings.
|
||||
- `reference.nc`, Fusion `setup-sheet.html`, `setup-sheet-values.json` with `setup`, `tools`,
|
||||
`operations` values transcribed from the captured sheet/API, and `simulation.json` as below.
|
||||
- `stock.stl` in setup millimetres, captured after the operation. Each first fixture has one
|
||||
operation; multi-operation coverage must capture and validate every intermediate state.
|
||||
|
||||
`simulation.json` must record `status` (`pass`, `fail`, or `inconclusive`), `complete: true`,
|
||||
`at_program_end: true`, a captured `findings` array, `completed_operations` in canonical input
|
||||
ID order, and `stock_after_operation` equal to the final operation ID. Its `accuracy` object
|
||||
records the actual UI `setting` and positive `resolution_mm` when available. If Fusion does
|
||||
not report a numeric resolution, use `resolution_mm: null` and `resolution_status: "not_reported"`;
|
||||
do not infer a resolution from the slider or confuse it with the independent verifier budget.
|
||||
Missing accuracy/end-position evidence is incomplete. Captured failure or uncertainty prevents
|
||||
a pass even when the independent checks pass. `post-properties.json` must contain valid JSON
|
||||
(an object or array), including an empty object when the post has no properties.
|
||||
Each finding has nonempty `detail` and `severity` (`error`, `unresolved`, or `information`).
|
||||
An error or unresolved finding prevents a pass even if the captured summary says `pass`;
|
||||
unknown severities are rejected. Add operation/motion/line locations when the reference exposes them.
|
||||
|
||||
The harness verifies provenance/input fingerprints and the actual post hash, interprets both
|
||||
programs, simulates them through the same independent verifier, compares local spatial stock
|
||||
bounds and the exported reference STL, checks setup values and reports distance/time/volume
|
||||
deltas. Spatial indexing bounds local comparisons. HTML path overlays link to numbered NC listings and diagnostics. Stock heatmaps show sampled
|
||||
remaining material relative to protected geometry; they are diagnostic views, not acceptance tests. Intermediate roughing must be judged against protected geometry and allowed stock;
|
||||
identical roughing paths, retract counts or execution times are not acceptance criteria.
|
||||
|
||||
All three stock pairs must pass directly: SolidCraft NC versus reference NC, SolidCraft NC
|
||||
versus reference STL, and reference NC versus its own exported STL. Tolerance comparisons
|
||||
are not transitive: two results can each lie within 0.01 mm of a third while differing by
|
||||
0.012 mm from each other. An original analytic regression exercises that failure. Reports
|
||||
retain definite failures even alongside inconclusive checks and include `cam-oracle/2`
|
||||
comparison provenance, capture settings, artifact hashes, generator/post identities and error
|
||||
budgets. The imported NC report identifies the captured post, rather than attributing it to
|
||||
SolidCraft's post. Synthetic unit-test packages are original expectations and never count
|
||||
as Fusion parity evidence.
|
||||
|
||||
Create geometry from the original analytic recipe in each application. Record Fusion version,
|
||||
license/capabilities, all resolved settings and capture timestamps. Use its current
|
||||
[NC Program posting API](https://help.autodesk.com/cloudhelp/ENU/Fusion-360-API/files/PostToolpaths_Sample_Sample.htm)
|
||||
and [Save Stock](https://www.autodesk.com/support/technical/article/caas/sfdcarticles/sfdcarticles/How-to-save-the-stock-as-an-STL-from-simulation-in-Autodesk-HSM-and-Fusion-360.html)
|
||||
where no supported automated stock export exists. Do not fabricate missing artifacts or mark
|
||||
incomplete captures complete. Additional fixtures must cover concavity, multiple islands,
|
||||
reversed winding, narrow channels, round profiles, offsets, through holes and multiple tools.
|
||||
|
||||
All Fusion-produced files and derived reports belong in ignored `plan/` or outside the repository.
|
||||
The oracle refuses an unignored in-repository destination. Commit only original recipes, harness
|
||||
code and independently authored expectations. No vendor post source, templates or assets are
|
||||
part of SolidCraft. Local references for facing, contouring, pocketing and drilling now pass
|
||||
input reconciliation, setup values, both programs' clearance and dimensional checks, and all
|
||||
three NC/stock comparisons (4/4). Together with the [acceptance audit](cam-acceptance.md),
|
||||
this closes the planned first milling milestone. The contour, pocket and drill exports use the maximum
|
||||
Stock Accuracy setting after replay to completion; the original coarser exports and their
|
||||
failed/inconclusive comparisons remain in ignored local storage. Numeric Fusion resolution is
|
||||
recorded as not reported, without substituting the independent verifier's resolution. Acceptance
|
||||
remains 0.01 mm with the original post and verifier error budgets.
|
||||
|
||||
## Manufacture display and playback
|
||||
|
||||
The workspace shows the selected program's model, initial stock or simulated final stock, with
|
||||
separate fixture coloring and visibility controls. Stock uses the setup coordinate frame; hidden
|
||||
model and fixture bodies cannot be selected in the viewport. Editing a setup reveals the bodies
|
||||
for reference selection. Missing or stale stock falls back to the model with an explicit message.
|
||||
The remaining-stock display is the final conservative upper surface, not stock removal animated
|
||||
at each playback step. Its mesh is cached by the simulation job and shares the bounded, conforming
|
||||
boundary extraction used by STL export. Display extraction errors do not replace simulation status.
|
||||
|
||||
Playback advances typed motion/event blocks at an adjustable rate, independent of frame rate.
|
||||
Zero means the initial clearance pose. The panel shows operation, tool, spindle and tool-tip
|
||||
coordinates; paths distinguish rapid and cutting motion, including full-circle arcs. `cam.inspect`
|
||||
exposes the same machine state, and `ui.inspect.manufacturing` exposes the current display choices.
|
||||
Stock extraction runs on the native worker and cooperatively on WebAssembly. Cell sorting,
|
||||
boundary stitching, triangulation, manifold validation and large topology-map cleanup yield and
|
||||
check cancellation. Cancellation returns no partial mesh; synchronous STL export uses the same
|
||||
implementation. Native UI tests cover stock-frame
|
||||
placement, visibility, stale results and playback boundaries. The four-strategy headless UI
|
||||
walkthrough exercises background generation/simulation, posting, stock selection and playback zero,
|
||||
with CPU-rendered stock views. A separate native desktop-window walkthrough exercises facing,
|
||||
internal contouring, pocketing and peck drilling on original CAD plates. Contour and pocket
|
||||
operations retain associated circular sketch boundaries and ramp entry; drilling retains a
|
||||
cylindrical face selected in the viewport. Closing and reopening the saved designs clears derived
|
||||
jobs while retaining those references. Editing coolant in the operation dialog and regenerating
|
||||
passes clearance and finished-dimension checks for each case. Native-posted contour, pocket and
|
||||
drill files match their command exports byte for byte. Playback, final-stock display and stale-post
|
||||
rejection were also checked. Local artifacts and screenshots are in ignored
|
||||
`target/cam-native-acceptance/`; this is SolidCraft evidence, not a Fusion comparison.
|
||||
|
||||
A second disposable native-window walkthrough checks recovery. A missing profile produces a
|
||||
reselection error; selecting the original profile and using the operation editor's **Use selected
|
||||
sketch profile** and **Save** restores generation and passing simulation. A clamp intersecting
|
||||
the pocket produces a cutter/fixture error attributed to motion 7 and NC line 20; **Locate issue**
|
||||
seeks that motion. Moving the same associated clamp clear restores passing clearance and dimensions.
|
||||
Cancelling active simulation through **Cancel job** leaves the job cancelled and blocks posting,
|
||||
including after later jobs finish. Editing feed in the operation dialog marks the result stale;
|
||||
posting rejects it, and regeneration/simulation passes. Geometry, deliberately broken references,
|
||||
profile selection and fixture correction were arranged through registered commands; editor actions,
|
||||
generation, simulation, cancellation and issue location used native UI input. Evidence is local in
|
||||
`target/cam-native-recovery/`. Preparation cancellation is covered by engine regressions, not this
|
||||
native walkthrough.
|
||||
|
||||
Interactive Save, Save As and Open use the same picker/background-loading flows as the toolbar;
|
||||
JSON commands remain dialog-free. Keyboard shortcuts use the modifier state on each key event,
|
||||
so a quick Command/Ctrl+S still saves if the modifier is released in the same frame. Regression
|
||||
tests cover these flows, cancelled pickers and persistence of manufacturing definitions.
|
||||
|
||||
Verification findings include a one-based interpreted NC `record` when a physical line is
|
||||
known. SolidCraft's independent post round trip also attaches `source` with physical line,
|
||||
operation ID and one-based IR block (the completed-block count used by playback). Attribution
|
||||
is added after verification and never influences clearance or dimensional decisions. Raw NC
|
||||
comments and deserialized data cannot supply this trusted mapping; imported programs retain
|
||||
line/record attribution without a guessed SolidCraft operation. Arc subdivisions share their
|
||||
original source block. Program-wide and missing-cut findings may have no responsible line.
|
||||
|
||||
`cam.inspect {job, finding: index}` uses a zero-based finding index and returns the reported
|
||||
world-space point, operation definition, associated CAD source, exact NC line and playback state
|
||||
where mapped. It rejects stale jobs and invalid indices; failed verification still blocks posting.
|
||||
The Manufacture panel's **Locate issue** action uses that command to center the reported witness
|
||||
and seek the completed source block. The marker remains visible when paths are hidden, can be
|
||||
cleared, and disappears when inputs change. The marked witness is not a claim of the exact first
|
||||
collision contact, and the stock view remains the final conservative stock surface. Validation
|
||||
JSON and HTML NC diagnostics retain the operation/block/line attribution.
|
||||
|
||||
Findings have explicit information, unresolved or error severity. The bounded list keeps one
|
||||
representative witness per kind/NC line/severity, prioritizes definite errors when full, and
|
||||
shows errors first. This list is diagnostic sampling, not an exhaustive inventory of affected
|
||||
points; verification status and stock intervals are computed independently of finding retention.
|
||||
|
||||
## Browser responsiveness measurements
|
||||
|
||||
A local release-mode WebAssembly probe on Chrome 155 (macOS, 2026-10-15) measured the original
|
||||
four analytic fixtures, using the actual generator, verifier and stock extractor. Before cooperative
|
||||
stock extraction, its longest single call was 433.1 ms for contour, 275.8 ms for pocket and
|
||||
383.1 ms for drill. After the change, the longest stock-extraction poll across those fixtures was
|
||||
2.5 ms. Triangle counts and passing clearance/dimension results were unchanged.
|
||||
|
||||
A second probe reused the UI scheduler with a four-ms target and one batch per animation frame.
|
||||
The largest observed batch was 4.9 ms; no batch exceeded 16 ms. These are local observations,
|
||||
not performance guarantees or complete browser acceptance: the probe excludes CAD snapshot
|
||||
preparation, the rendered application, export serialization, concurrent jobs and hostile-size
|
||||
inputs. Later primitive/export probes below cover representative accepted-size inputs; their
|
||||
remaining atomic latencies are explicit limits in the acceptance audit. Unit
|
||||
regressions verify exact synchronous/cooperative mesh agreement, early/mid/late cancellation,
|
||||
round-robin fairness, completed-job termination and a poll cap if the host clock stalls.
|
||||
|
||||
The clamped through-hole and external-contour recipes also pass the same local release Wasm
|
||||
probe. Their largest observed scheduler batches were 5.2 ms and 7.4 ms, with no batch over 16 ms;
|
||||
stock extraction peaked at 4.0 ms and 4.1 ms. The external contour produced 243,154 cells and
|
||||
111,102 triangles. These measurements have the same limited scope described above.
|
||||
|
||||
## Associated drilling selections
|
||||
|
||||
In a drilling operation, select inward cylindrical faces or circular sketch profiles in drilling
|
||||
order, then choose **Use selected holes**. The engine command accepts `selections` containing
|
||||
`{kind:"face",body,index,occurrence?}` or `{kind:"profile",sketch,index,occurrence?}`. A face pick
|
||||
without `occurrence` uses the displayed world body name; an explicit occurrence path uses the
|
||||
body definition name. Profile picks use the sketch feature ID and evaluated profile index.
|
||||
The returned `sources` belong in `Operation.hole_sources`, with the returned `holes` as the
|
||||
preview coordinates in `geometry.holes`. The command also reports selected diameters.
|
||||
|
||||
Face sources store a body/occurrence identity and persistent face name. Profile sources store
|
||||
sketch curve identities. Immutable job preparation resolves these again in setup coordinates,
|
||||
including uncaptured occurrence moves. Stored preview centers are never used as a fallback.
|
||||
Matching cylindrical seam faces on the same body occurrence become one hole, retaining the first
|
||||
pick’s source. Duplicate identical references and conflicting coincident axes are rejected.
|
||||
|
||||
Missing, split-to-new-name or ambiguous faces/profiles require reselection. Noncircular profiles,
|
||||
external cylindrical faces and axes not parallel to setup Z are rejected. A linked hole's diameter
|
||||
must match the drill within
|
||||
the operation tolerance; choose a matching tool or explicitly unlink before pilot drilling.
|
||||
|
||||
Linked coordinates are read-only in the operation dialog. **Unlink holes** retains the displayed
|
||||
coordinates as explicit input. Feeds, spindle, top/bottom heights, peck depth and tip/full-diameter
|
||||
depth remain user-controlled. The complete operation settings, resolved centers and source
|
||||
identities are included in setup sheets and canonical toolpath JSON; inspection exposes the
|
||||
operation's hole sources. Selection establishes an axis only: independent machining and clearance
|
||||
verification still decides whether the program can be posted.
|
||||
|
||||
### Snapshot hashing responsiveness
|
||||
|
||||
A local Chrome 155 release-Wasm stress probe found synchronous snapshot hashing calls of
|
||||
54.6 ms for 32 operations with 10,000 boundary vertices each, 172.6 ms for 1,000 operations
|
||||
with 1,000 vertices each, and 92.2 ms for 200,000 target triangles. Background snapshot
|
||||
preparation now hashes incrementally, yielding before each operation/tool and every 256
|
||||
triangles. It preserves the exact existing serialized fingerprint, including field order and
|
||||
numeric/string encoding; no algorithm-version or cache-key change is needed. Cancellation
|
||||
checks surround every yield and cannot return a partial digest. Regression tests compare the
|
||||
old and incremental encoders across the original corpus and a maximum-size triangle snapshot.
|
||||
On the same local probe, maximum scheduler batches for those three large cases were 5.1,
|
||||
4.2 and 4.2 ms respectively; none exceeded 16 ms. These are measured observations, not hard
|
||||
deadlines.
|
||||
|
||||
One setup or operation is still encoded atomically. This hashing probe alone does not measure
|
||||
large reference lists, CAD tessellation, a single offset query or direct synchronous exports.
|
||||
The subsequent primitive/export probes cover those cases and record remaining atomic limits.
|
||||
These measurements do not establish whole-application latency guarantees.
|
||||
|
||||
### NC round-trip responsiveness and limits
|
||||
|
||||
Background simulation now yields during reference posting, independent modal interpretation
|
||||
and IR correspondence checking. Posting and correspondence yield every 256 blocks; the reader
|
||||
yields every 256 physical lines, including comment/blank lines. Cancellation is checked before
|
||||
and after each yield and returns no partial G-code, parsed program or trusted line mapping.
|
||||
The synchronous APIs use the same processing code with immediately ready checkpoints.
|
||||
|
||||
A local Chrome 155 release-Wasm probe measured a 228.9 ms synchronous round trip for 199,990
|
||||
blocks. The cooperative path's largest scheduler batch was 4.2 ms. A 200,000-block path also
|
||||
passes, with 200,003 interpreted records including the three post startup events; its largest
|
||||
batch was 4.1 ms. Neither case had a batch over 16 ms. The former reader incorrectly counted
|
||||
startup against the generated-path limit and rejected the maximum-size path. Both posted blocks
|
||||
and external interpreted records now have explicit, independently checked bounds.
|
||||
|
||||
Regression tests exercise the exact path limit and excess input, synchronous/cooperative bytes
|
||||
and machine-state equality, operation/block/line provenance, unchanged unknown-command errors,
|
||||
and cancellation at every checkpoint across all three stages. Measurements exclude direct
|
||||
synchronous export commands, CAD preparation, offset queries and the rendered application;
|
||||
these observations do not establish a universal latency guarantee.
|
||||
|
||||
### Dense boundary validation and offsetting
|
||||
|
||||
The original 10,000-vertex seven-lobe boundary exceeded the all-pairs validation budget before
|
||||
reaching offset generation. Indexed candidate checks now admit that simple boundary without
|
||||
relaxing intersection tests or the candidate-work limit. A separate dense-circle regression
|
||||
exposed a library assertion on short segments; power-of-two coordinate normalization resolves
|
||||
the reproduced case without simplifying geometry. Independent regular-polygon distance checks
|
||||
cover every output vertex at two scales and shifted coordinates; concave checks sample output
|
||||
vertices against the original input segments. These checks are not whole-stock certification.
|
||||
|
||||
A local Chrome 155 release-Wasm generation probe on 2026-10-16 produced 6,674 blocks from the
|
||||
10,000-vertex seven-lobe input. Its longest scheduler batch was 21.2 ms (one batch above 16 ms),
|
||||
compared with 6.4 ms for the 1,400-vertex case. Validation is cooperative, but the library offset
|
||||
query remains atomic. This records an unresolved responsiveness limit; it is not a guarantee of
|
||||
frame-rate responsiveness. The probe excludes CAD preparation and stock verification.
|
||||
|
||||
|
||||
A 2026-10-16 primitive probe measures the remaining atomic work separately from machining
|
||||
acceptance. A 100-island pocket with 9,904 vertices emits 80,307 blocks with a maximum 9.7 ms
|
||||
scheduler batch. Hashing 1,000 setup references or 10,000 profile curve IDs (256-byte names and
|
||||
64-element occurrence paths) takes batches up to 3.2 ms and 8.0 ms respectively. These original
|
||||
synthetic probes test computation; they do not supply matching intended geometry for dimensional
|
||||
acceptance. Fixed-tolerance CAD cylinder tessellation takes about 12 ms at radius 10 mm,
|
||||
102 ms at radius 500 mm and 1,087 ms at radius 5000 mm, producing 3,560, 8,188 and 28,382
|
||||
triangles. The largest case now respects the requested 0.00125 mm chord tolerance instead of
|
||||
silently coarsening it. Native preparation runs on its worker, but a Wasm shell tessellation is
|
||||
still atomic and the measured large-body stall remains a browser responsiveness gap. Local
|
||||
before/after evidence is in `target/cam-web-probe/primitive-baseline.json` and
|
||||
`primitive-fixed.json`; output budgets and tolerances were not relaxed.
|
||||
|
||||
|
||||
The follow-up mesher optimization uses Spade's bulk point insertion and an original conservative
|
||||
line/AABB index for trim-boundary candidates. It retains every boundary segment and the existing
|
||||
winding predicate; uncertain arithmetic visits candidates rather than pruning them. Rounded
|
||||
positions are mapped back to vertex handles so duplicate points do not change constraint indices.
|
||||
Differential tests compare indexed and complete winding scans across concavity, holes, reversed
|
||||
winding, translated/scaled coordinates, boundary points and nearly parallel rays. Kernel checks
|
||||
independently assert concave two-hole prism volume/containment and large-cylinder chord/volume
|
||||
bounds. The algorithm fingerprint advances to `cam/18` because tessellation can change triangle
|
||||
ordering. A local instrumented prototype reduced the radius-5000 case from about 1089.8 ms to
|
||||
96.5 ms with the same 28,382 triangles and 0.00100715 mm maximum measured radial chord error.
|
||||
Its segment visits fell from 352,784,748 to 1,462,907. This optimization does not make shell
|
||||
meshing incremental; its remaining atomic latency is recorded below. Incremental exports are
|
||||
covered by the subsequent acceptance checks.
|
||||
|
||||
The uninstrumented production release-Wasm follow-up measured 10.3 / 27.2 / 90.8 ms for radii
|
||||
10 / 500 / 5000 mm, with the same triangle counts and radial errors as the fixed-tolerance
|
||||
baseline. The largest case remains an approximately 91 ms atomic step on this machine; no
|
||||
hard scheduling deadline or full browser responsiveness claim follows from this measurement.
|
||||
Evidence: `target/cam-web-probe/tessellation-production-index.json`.
|
||||
|
||||
|
||||
## Incremental export acceptance
|
||||
|
||||
A quiet Chrome155 release-Wasm probe with an original 200,000-block path measured synchronous
|
||||
toolpath JSON up to296.7ms and posting/roundtrip342.5–360.8ms. An original tiled height field
|
||||
with40,000cells exported34,051,171bytes of STL in540.5ms; validation JSON took35.5ms. These are
|
||||
serialization/resource measurements, not claims that a synthetic report passed machining checks.
|
||||
The incremental path avoids a full intermediate JSON Value for large arrays, yields between
|
||||
motion/cell/triangle batches and each operation/tool, and reuses cooperative stock extraction
|
||||
through ASCII serialization. Focused tests compare all JSON fields, HTML values/escaping and
|
||||
STL/NC bytes, inject cancellation at every serialization checkpoint, and check stale/cancelled
|
||||
background results cannot write output. The UI regression now exercises background posting and collection through an injected save-picker
|
||||
service. A disposable native command walkthrough additionally exports all five formats, including
|
||||
a33.9MB stock mesh, and verifies no destination file exists before explicit result collection.
|
||||
A fresh system save-dialog attempt was not completed: native accessibility timed out and window
|
||||
capture reported no presented frame. That manual check is not counted as a new passing walkthrough.
|
||||
|
||||
The incremental follow-up measured at most4.3ms per scheduler batch for the same original export
|
||||
cases (no batch above16ms). The40,000-cell STL is still34,051,171bytes, and the200,000-block NC
|
||||
program is still11,999,980bytes. Toolpath JSON shrinks from41,002,015 to15,201,072bytes through
|
||||
whitespace removal; semantic equivalence is asserted against the original serializer. Evidence:
|
||||
`target/cam-web-probe/exports-baseline.json` and `exports-incremental.json`. These timings exclude
|
||||
file-system publication and are machine-specific; command freshness checks still govern publication.
|
||||
|
||||
|
||||
The final native save retry used a regular disposable app bundle. The actual system Save dialog
|
||||
created `posted.nc` (146,348 bytes), identical to the registered-command NC export. Job status
|
||||
confirmed a fresh verified job, passing clearance/dimensions and idle export after UI collection.
|
||||
Post-save screenshot capture remained unavailable; the result is established by the output file
|
||||
and job state. Evidence: `target/cam-native-audit/save-acceptance.json`.
|
||||
@@ -160,7 +160,7 @@ labels; `prefs:measure_axis_distances` identifies the checkbox.
|
||||
| `ui.resize` | `width`, `height` | |
|
||||
| `app.quit` | `force?` (quit without asking about unsaved designs) | `quitting` (the window closes), `asking` (a "save changes?" prompt is open) |
|
||||
|
||||
`ui.workspace {workspace?: "design" | "render"}` reads or changes the active workspace.
|
||||
`ui.workspace {workspace?: "design" | "render" | "manufacture"}` reads or changes the active workspace.
|
||||
Entering Render requires finishing the current modelling operation; returning restores
|
||||
the Design camera. See [the integrated Render workspace](render-workspace.md).
|
||||
|
||||
|
||||
Reference in new issue
Block a user