mirror of
https://github.com/bherbruck/solidcraft.git
synced 2026-11-06 20:02:16 +00:00
e4844753cb9a836cda170d2a416412b3ca875ff1
59 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
9a79588575 |
doc, engine, ui: placing the model returns its error; placements are checked where they are set
doc: world_state, world_state_reusing, state_in_frame_at, state_in_frame, face_point_state, face_point_names and construction_state return Result. A body that could not be placed, a frame that could not be inverted, a sketch plane or thread axis that did not survive the placement, or a failed placing worker used to leave things where they were without a word; now the call fails with what could not be placed. is_placement is the one test of an occurrence's placement (finite, a rotation that does not mirror, a translation within 1e9 mm). Opening a design names every occurrence that fails it; add_occurrence refuses one; a joint solution that would place an occurrence outside one is not applied and the joints placing it report it. engine: Session::world_state returns Result and keeps a failure in its cache as it keeps a placed model. bounds, home_camera, open_sketch_plane, the scene builders, the world previews, frames::to_local and auto_operation pass the error on; helpers answering "not found" take the placed model from their caller. Commands setting a placement check it (valid_position, exploded view, fastener at a point, STEP insert matrix). ui: panels, picks and hovers read the session's placed model through open_meshing::session_world; a model that cannot be placed shows no placed bodies, and the viewport says why across its bottom. Pictures and the control channel report the error. cli, mcp: snapshots, renders, benches and the oracle report the error; the kernel-case rig records it as the case's failure. Tests read the new Results with unwrap. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017itGh5fpMEousnZ91cYcVt |
||
|
|
712caf8bf4 |
engine: no boolean retries to report; overlaps are SMLib's exact intersection
The kernel has no boolean retries now, nor their diagnostics (capture_boolean_diagnostics, BooleanDiagnostics, BooleanStrategy), nor the near-coaxial crescent (coaxial_overlap, coaxial_candidate, with_attempt_budget). What read them goes: - doc: FeatureResult and the evaluation cache carry no boolean diagnostics, and no "Boolean retry" warning; the saved model no longer writes them (an older file's are ignored); - engine: timeline.inspect / feature inspection drop `boolean_diagnostics`; fuzz runs and the CLI fuzz summary drop their retry counts; - inspect.interference: each pair is the bodies' Intersect, measured; the near-coaxial crescent, the by-piece intersection of bodies in several pieces and the unverified notes go (the command's doc no longer lists near_coaxial); - inspect.clearance: an overlap is the bodies' Intersect, measured near its region; the pin tries, the cut-down copies of large bodies (clipped, narrowed), the union cross-check (union_disagrees, contradicted) and the malformed-part check (plausible) go, and the measure near the origin passes its move's error on. Tests: the retry test and the unit tests of the deleted checks are removed; the barrel join test (tests/boolean_diagnostics.rs, now tests/barrel_join.rs) keeps its geometry checks; the pin-in-bushing test expects the filleted case measured; assertions on empty diagnostics and on near_coaxial are dropped; the corpus fixtures lose the diagnostics key and the one retry warning. (not built: base in progress) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017itGh5fpMEousnZ91cYcVt |
||
|
|
1ecf00b5ac |
engine: feature replies carry no boolean diagnostics
doc's FeatureResult has no boolean_diagnostics any more (truck's Boolean
retry reports, gone with truck; SMLib's boolean has no retries). The
timeline.inspect and doc.inspect replies drop the key.
Tests of the removed reports: tests/boolean_diagnostics.rs is deleted (it
checked truck's retry events and their survival through the cache, undo and
reopen); the assertions that a feature's report had no events go from
features_more_tests, patterns_tests, hole_face_tests and tests/rim_cut (the
rest of each test stays). The CLI corpus's expected replies
(move-bodies, issue-489-stacked-join, issue-616-lid-ribs) drop the key; the
issue-616 one listed a planar_fallback event. docs/robustness.md: its
section on retries becomes one on SMLib's booleans, which have none.
Left to the blends work: engine fuzz.rs (its retry-event counts) and
clearance/interference (capture_boolean_diagnostics, coaxial_overlap,
with_attempt_budget).
Not built: base in progress (kernel-smlib/no-truck
|
||
|
|
42997a62ed |
WIP kernel: Body::mesh(&MeshTolerance) as the one mesher (does not build yet)
Body::mesh / mesh_plan / mesh_of and MeshTolerance (chord, display, display_of, export_of) replace tessellate, tessellate_with, display_mesh*, display_plan*, reference_display_mesh_angular; every caller in kernel, doc, engine, io, ui-egui, gpu and the CLI renamed mechanically; the truck-mesher fallback, mesh_shells*, refined* removed; Body::new orients from the planner; truck-meshalgo dropped from Cargo.toml with the tests of its hooks. Still to fix: trait imports in tess/*, splitface/lumps/preview/step_in/boolean_record meshalgo uses, measure. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017itGh5fpMEousnZ91cYcVt |
||
|
|
a8c8f88323 |
naming: list removed lines before added ones in the corpus diff
A failure now reads as a diff does: the recorded line (-) and then the line the rebuild gives (+), and the message says which is which. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QWhMwdqJYQKQq8RCLSL1LT |
||
|
|
a55196e7ad |
naming: the corpus rebuilds with the same names and references
A test over every design the repository keeps (the action matrix's corpus: old design files, examples, regressions, demo and typical designs, the oracle recipes; plus the sample designs, the engine's design fixtures and the older designs of the hole matrix, taper and projection tests: 154 designs). Each is rebuilt and recorded in tests/naming/<group>/<design>.txt: per body the names of its faces and edges with whether each follows exact history, and every stored name (feature face picks, fillet/chamfer/bend edges, sheet metal edges, the face a sketch is attached to) with the face or edge it finds now. A difference fails with the design and the changed lines; record an intended change with NAMING_CORPUS_BLESS=1, as FEATURE_WALK_BLESS does. Face and edge indices are left out on purpose. They are the kernel's order: truck already gives a fillet's or a boolean's faces in another order from one process to the next (oracle 07 and 37 changed on every run), and SMLib will order them differently again, while what must not change is the names and what references find. Names are listed sorted. One design's names themselves change between runs on truck (closed_sweep_torus_cut: level wall halves numbered #1/#2 in kernel face order); it is listed in UNSTABLE with the reason and its difference printed instead of failed on. Records made on this branch (truck), macOS. The whole corpus builds in about 20 s on 14 cores (designs run side by side). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QWhMwdqJYQKQq8RCLSL1LT |
||
|
|
a7c1909766 |
CLI: evaluate scripts on the input design (#6861) (#6872)
* claim: #6861 eval scripts on input designs * fix(cli): evaluate scripts on the input design (#6861) * fix(cli): validate eval options before opening inputs Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
189b47c750 | Chamfer and Fillet refuse a point where several edges meet (#5173) (#5177) | ||
|
|
b3cbbe7bd5 |
CLI: reject incomplete and unsupported run/eval options (#6918) (#6919)
* claim: #6918 validate run and eval options * fix(cli): reject invalid run and eval options (#6918) |
||
|
|
dfde1e032d |
mcp setup: add SolidCraft to the AI clients on this computer; plain mcp finds a late app (#6379)
solidcraft-cli mcp setup (alias install) and Help > Connect AI assistants edit each installed client's own configuration in place, with this program's absolute path: OpenCode, Claude Desktop, Claude Code, Cursor, Codex, Gemini CLI, Copilot CLI, Windsurf, Zed and VS Code. Only the solidcraft entries change; a stale path is refreshed and an entry the user changed is left alone. Plain mcp keeps looking for the app while its headless session has no work, and says on every tool result that it is headless when the app was not found. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
9e6e0b8df1 |
Render workspace: complete experimental ribbon, resources and effects integration (#5493) (#5494)
* wip(render): reconcile completed material and image pipeline source with 0.20 (#5493) Source-only integration reference for staged review, not a merge-ready aggregate. Donor: 0xlillith/solidcraft@aea20b0115. Upstream: |
||
|
|
b7b25f9e2b |
Render workspace: first basic delivery to main (#6050)
* Normalize UI container violation paths across platforms (#5599) Report repository-relative paths with forward slashes so diagnostics and the existing nested-package regression assertions agree on Windows and Unix. Keep the container detection rules unchanged. Validation: official ui-containers gate and all seven focused xtask tests passed; rustfmt and diff checks passed. Only xtask/dependencies were compiled; no application build or heavy tests. (cherry picked from commit |
||
|
|
5e0e7a4c6a |
CLI: --help on each subcommand prints its usage and exits 0 (#4538) (#4545)
* claim: #4538 * CLI: --help on each subcommand prints its usage and exits 0 (#4538) Every command now answers `--help` and `-h` with its own usage on stdout and exit 0, the way the top level has since #1828. Before, each subcommand answered differently: `fuzz --help` started a fuzz run with the default seeds and ran until it was stopped, `recipe --help` took the flag for a file name, and `snapshot`, `render`, `oracle`, `run`, `eval`, `script` and `crashes` answered with an error on stderr and exit 1. The help is read before the command runs, so `--help` never starts work: no fuzz run, no MCP server, no file read. `fuzz` also refuses an argument it doesn't take, as `snapshot` already did: a flag it doesn't know and a stray word are errors, not arguments to ignore while a hundred seeds run. The usage lives in one place now: each command's lines are a constant, and the top-level usage is composed from them, so the two cannot drift apart. The top-level usage is unchanged, byte for byte. # Conflicts: # apps/solidcraft-cli/src/main.rs |
||
|
|
0dffb206b1 |
Assembly: ground the first part; drag free joint chains (#2804) (#2805)
* assembly(feat): ground first parts and drag free joint chains Ground the first top-level part when it is created and let face dragging reposition free occurrences or any member of a floating joint chain in one undo step. Preserve exact repeated-placement frames, joint values, modifier selection and Escape cancellation. Keep the accumulated fixture, viewport layout and documentation integration fixes from the existing PR. Signed-off-by: Karl Von Richter<karl@embeint.com> * assembly(fix): update movable fixtures for first-part grounding Accept the documented grounded override in component creation, explicitly free movement fixtures, and keep linked clipboard pastes movable even in an empty document. Cover first and reused linked pastes, default insertion grounding, and single-step undo in the existing link tests. Signed-off-by: Karl Von Richter<karl@embeint.com> * assembly(test): keep the motion-cost crank free Unground the first component in the document-level joint-face measurement fixture so its motion samples can rotate after first-part grounding. Preserve the rotation and shared-measurement assertions that caught the Linux CI failure. Signed-off-by: Karl Von Richter<karl@embeint.com> * assembly(test): free the frame placement fixture Create the frame-member placement fixture ungrounded before moving it above its root sketch. Keep its world-space member assertions while respecting first-part grounding in the frame tests added on main. Signed-off-by: Karl Von Richter<karl@embeint.com> --------- Signed-off-by: Karl Von Richter<karl@embeint.com> |
||
|
|
98c4f335e8 |
Control channel and MCP on by default, with a setting to turn it off (#5561)
The app opens its localhost control channel on port 27878 (or the next free one) unless Preferences > Assistant turns it off; --control and SOLIDCRAFT_CONTROL_PORT still win. A current.port discovery file lets solidcraft-cli mcp find the running app with no arguments. Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com> |
||
|
|
e33c371e99 |
Model cache: thin the checkpoints of a design too big for its file instead of leaving the cache out (#3220) (#4882)
* claim: #3220 * Model cache: keep fewer states of a design too big for its file instead of none (#3220) A model cache over the container's budget keeps the final state, then the slowest features' states while the bodies they add fit (a body several states hold counts once), and is left out only when not even the final state fits. Opening evaluates just the features whose state the file left out, each from the state before it, so the model is whole afterwards. * Model cache: keep each encoded body apart, copy only what a cache stores Encoding a model too big for its file no longer copies every distinct body into one buffer before thinning: the payload is copied from the encodings once its size fits, so saving holds no more than before. * Model cache tests: canonical runs in the timeline fixture; rustfmt * Model cache: count the records a thinned cache keeps; always try the final state Thinning counted only the bodies, so a model of many copies of one part (records, not bodies, filling the room) shrank its budget to nothing and saved no cache although its final state fitted. The choice now counts the records of what it keeps, always keeps the final state, and says what it counted, so each retry keeps less and the final state alone is always tried. * docs: a thinned model cache counts its records and always tries the final state * Model cache test: the slowest feature's state holds bodies 16 to 23 * Model cache: thinned opens with fingerprints that read the state before a feature Since #3397 a feature's fingerprint reads where the bodies before it lie. After a state the file left out, adopt takes the saved fingerprint and the evaluation that works the state out checks it. A result evaluated ahead is never taken as one the file left out. The thinned round trips include the placed components' design, whose cut reads those placements. --------- Co-authored-by: MateuszSychXpl <151755914+MateuszSychXpl@users.noreply.github.com> |
||
|
|
c54b711345 |
CLI: --help prints usage to stdout and exits 0 (#1818) (#1828)
* claim: #1818 * claim: #1818 * fix(cli): --help, -h and help print usage to stdout and exit 0 (#1818) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: bherbruck <brennen.herbruck@gmail.com> |
||
|
|
e98e065584 |
Open saved designs from the model they were saved with (#3053) (#3102)
* WIP: adopt the saved model on open (#3053) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * WIP: tests * WIP: bench-open opens as Open does * docs: opening from the saved model * Tests: an edit after opening evaluates from the feature it changes * clippy * Read SOLIDCRAFT_NO_MODEL_CACHE through the env helper * Open: no picture from the model when the model itself opens; cancel test evaluates * Saved model: bodies passed through found without writing their record; states list runs of bodies * Adopted results go into the evaluation cache: an undone edit, or the marker rolled forward, takes them again * Model cache size guard: the saved model's writer --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
953fd7d5f8 |
Typed parameter contracts and JSON Schemas for solid.box and solid.extrude (#2829) (#2611)
* Spike: typed parameter contracts and JSON Schemas for solid.box and solid.extrude The schema RFC's spike (plan/schema-spike.md). solid.box and solid.extrude get typed contracts with generated JSON Schemas (2020-12), checked in front of the unchanged handlers by a per-session level: off (the default, which changes nothing), warn (the call runs and gains param_warnings) or strict (the call is refused and the design left alone). Also engine.describe and the MCP tool describe_command, `solidcraft-cli mcp --param-check off|warn|strict`, a FeatureResult type for feature replies, and an env-var audit recorder (SOLIDCRAFT_PARAM_AUDIT) used to check the contracts against every test. Local spike branch; not for upstream as is (see the results report). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Parameter contracts: put the audit recorder behind a feature; drop two ignored test keys The audit recorder is now on only in a build with the engine's `param-audit` feature and `SOLIDCRAFT_PARAM_AUDIT` set. Its code is still compiled, linted and tested without the feature. `scripts/param_audit.py` summarises a test run's audit logs, and the schema module's docs give the steps for converting a further command. Two tests passed keys their command ignores, which the audit found: `position` on `solid.box` (`hole_face_tests.rs`) and `symmetric` on `solid.extrude` (`face_tests.rs`). Both are removed, so the tests build what they always did. Comments no longer call the contracts a spike. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: bherbruck <brennen.herbruck@gmail.com> |
||
|
|
803ae6d5be |
Script replay keeps a feature name another feature has (#1990) (#1997)
A sketch and the feature built from it may share a name, and the sample and oracle designs do. `timeline.add` refused such a recorded name, so a design's own exported script failed to replay. `Document::insert_feature` now keeps the name, as `add_feature` does; a blank name still gets a fresh one. Co-authored-by: bherbruck <brennen.herbruck@gmail.com> |
||
|
|
31b41978fc |
Construction geometry on model vertices follows them when a parameter moves them (#568) (#2409)
Thanks @rlartot. |
||
|
|
26f42ae09b |
Snapshot: draw a see-through appearance see-through, and show a tool body inside its target (#2329) (#2330)
* Snapshot: draw a see-through appearance see-through, and give the CLI --body, --tool and --section A headless picture dropped a body's opacity: the scene carried only a colour, so a design with a translucent appearance was drawn opaque by `solidcraft-cli snapshot`, by MCP screenshots and in a design's thumbnail, although the window has always drawn it as glass. There was then no way to look at the body a cut would remove inside the material it meets: only a volume to measure and reason about, which hides exactly the errors a picture makes obvious (a tool that stops short, or lands in the wrong place). - `SceneMesh` carries the body's opacity; `view::build_scene` takes it from the design (`model_body_opacity`), and a selected body stays solid so the selection colour reads. - The GPU capture routes a see-through body into the scene's glass at its own alpha, as the viewport does; the CPU rasterizer draws the solid bodies first (they own the depth buffer), then the see-through ones blended over them, far sides before near sides and without writing depth, so what lies inside shows and a line between the two is not hidden. - `snapshot --body NAME:opacity=0.3,color=#rrggbb`, `--tool NAME` (that body solid in the tool colour, the rest see-through) and `--section z=27` run the commands the app itself runs (`appearance.assign`, `inspect.section`): the options are shortcuts, not a second renderer. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Tests: measure the tool colour as it is drawn through a see-through target The tool-colour filter was derived on paper and demanded a red more than twice either other channel, which the target in front of it tints away (measured: (200, 108, 85) through opacity 0.3); and the colour check painted the tool, which a solid target hides. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fmt * Snapshot options: strip the colour's # rather than slicing it; README Slicing `value[1..]` on an input-derived string is what the house rules ask us not to write, even where a length check has already made it safe. The error a failed assignment reports now names the body rather than claiming it came from --body, since --tool reaches it too. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * --tool: assign the bodies around the tool in groups, not one command at a time Each appearance.assign is an undo step with a document snapshot behind it, so one per body made --tool cost grow with the size of the design for no reason: the bodies around the tool all get the same opacity, and the ones that share a colour can be named in one call. A design whose bodies all wear the default grey now costs two commands whatever its size. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Rasterizer: say where its glass and the GPU's differ Splitting each see-through body by facing orders its own two layers; it does not sort across bodies, which the GPU does. Worth stating rather than leaving a reader to find it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: bherbruck <brennen.herbruck@gmail.com> |
||
|
|
6f93e7a851 |
fix(examples): cut both mounting holes in the bracket (#1515)
Co-authored-by: bherbruck <brennen.herbruck@gmail.com> |
||
|
|
7ad5130cd2 |
refactor: geom::UnitVec3 for unit axes and normals (#2603)
* geom: UnitVec3; a face's analytic axes and normals are unit by type Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * geom: UnitVec3 adds to and subtracts from a Vec3 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * kernel, doc, engine: cylinder axes and measured normals held as UnitVec3 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * kernel, engine: functions that take a unit axis or direction say so by type Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * doc: a face's normal goes to Plane::from_normal as is Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * kernel, doc: main's new cylinder helpers take the face's axis as a UnitVec3 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
9eb1540a34 |
Docs: describe SolidCraft as independent CAD (#2768)
Reword comments, docs and package descriptions so they describe SolidCraft's own behaviour instead of comparing it to another product. The trademark notice, the commercial-CAD rule and the navigation preset name stay as they were. Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com> |
||
|
|
bc68e14c3e |
Mutation testing: judge kernel mutants by the black-box suites (#2660)
The kernel will move from truck to solidcore (#1597). The tests that must catch regressions across that switch are the ones that don't depend on the kernel: the reference tests and the robustness goldens. cargo-mutants checks whether they would notice a change in the kernel's behaviour. - apps/solidcraft-cli/tests/oracle_cases.rs: the reference tests as a cargo test (ignored; CI keeps replaying them through cargo xtask oracle), run over one process per core. - .cargo/mutants.toml: mutants are judged by that test and the pull-request sample of the robustness goldens, not by the kernel's own unit tests. - A mutants profile (ci with incremental builds): about 15 s to rebuild after a kernel change instead of about 3 minutes. - docs/mutation-testing.md: how to run it, its cost, two cargo-mutants 27.1 problems and the pilot's results (15% of sampled kernel mutants caught). Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> |
||
|
|
b04e0801d6 |
Per-command timings for script runs and batches (#1868)
Thanks @DuBearte. |
||
|
|
64966bab88 |
Implement the reviewed UI icon system and durable review workflow (#853)
Thanks @Nathan-Dane. |
||
|
|
bf4551159e |
Split Body and Combine Intersect keep their faces' sources, so sketches attach (#565) (#1732)
Thanks @SychPL. |
||
|
|
3087363c44 |
test: three ignored tests pass again and run in CI (#679, #562) (#1663)
Thanks @PhilippBischoff0. |
||
|
|
1a0b33fcf3 |
Headless pictures draw on the GPU, with the viewport's pipelines (CPU rasterizer as last tier) (#1555)
Thanks @jyviko. |
||
|
|
b3df2c382b |
snapshot --camera and saved views; grid: false / axes: false for headless renders (#1313)
solidcraft-cli snapshot takes --camera JSON and --view with a saved view name (through view.apply, as the MCP screenshot does), plus --no-grid and --no-axes; the MCP screenshot and ui.render take grid/axes, the headless render skips a hidden origin axis, and the app's ui.render follows the Grid and Origin switches. Closes #1245. |
||
|
|
1473893b08 |
MCP: a bridged server starts without the app and connects once it runs (#1298)
The bridged MCP server starts when no app is listening, says so in its instructions and in each tool error, and connects on the first call after the app starts. A batch that could not be sent says the app is not running. docs/mcp.md describes it. |
||
|
|
96356dc544 |
CLI snapshot takes --in; an unknown command suggests close ids (#1301)
snapshot starts from --in (a design or STEP file) with the script on top, as run does, and refuses options it doesn't take; an unknown command id names the closest registered ids. |
||
|
|
5c2fa3e9ca |
Action matrix regressions of #1255: knuckle rounds, thin holes, a 45° flange hole, an axis after an edit (#1280)
* Action matrix regressions of #1255: knuckle rounds, thin holes, a 45° flange hole, an axis after an edit - Curve blends: past the end of a curved edge the run of sections along the end tangent wrapped round the ring of centres; it is shortened while it still crosses the end face (the hinge knuckle's cap rounds at 0.728 mm). - Boolean retry guard: each body's volume is measured finer than its smallest radius, and a volume out of bounds is measured again ten times finer before it refuses (a 0.133 mm drill measured -30272 mm³; a plastic part's coarse mesh was off by more than the slack). - Sheet metal: a drill cap's certificate allows the evaluation noise its fitted tilt shows (a hole square to a 45° flange). - Construction geometry on a named face uses the face found by name, not a second pick at its nearest point (an axis through a corner round after a parameter moved it). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Retry guard: measure the target, tool and result at one tolerance Measured at different tolerances, the chords' error on the faces they share didn't cancel: a blind hole in a long D-profile bar measured 20 mm³ more than the bar. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Action matrix baseline from this branch's full run: 37 actions pass again, none fewer Blessed with cargo xtask action-matrix --from DIR --bless from the 16 shards of run 38673859774. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
c159a3e277 |
Action matrix: nightly shards cut by measured cost, a fresh baseline, and a determinism check (#1256)
* Action matrix: nightly shards cut by measured cost, heavy designs in slices, and a determinism check
The full matrix ran as four fixed quarters of the corpus and two of them hit the 60-minute
job limit. Now action_matrix_shard runs shard k of n (ACTION_MATRIX_SHARD=k/n), planned from
tests/action_matrix/costs.json: designs that take more than five minutes are split into slices,
and the pieces go largest first to the least loaded shard. The nightly runs 12 shards and uploads
each one's outcomes and timings; cargo xtask action-matrix --from DIR --bless records them in the
baseline and costs.json without running the matrix again. action_matrix_determinism runs a sample
twice and lists any action whose outcome changed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Action matrix: costs measured on runners, 10 shards, determinism on the lighter designs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Action matrix: baseline and costs from a full run on main, 16 shards, timeouts listed
The baseline is regenerated from the 10 shards' results of a full run on
|
||
|
|
2e7f41710b | run and eval can write their JSON to a file (--json-out) (#1242) | ||
|
|
d019f2d5bf |
Straight edges stay one edge after cuts (#1049) (#1101)
* Straight edges stay one edge after cuts (#1049) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Robustness goldens: cuts join straight edges along untouched walls (#1049) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fmt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Robustness goldens note: what each changed seed shows when replayed on both builds Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
ec8e739aad |
Export a design's timeline as a replayable command script (#1045)
timeline.export_script (and solidcraft-cli script) writes a design's history as a command script that solidcraft-cli eval replays into the same design, so a bug that only shows on one design becomes a one-file repro. timeline.add restores one stored feature with its id, names and references, through the same checks a design file gets when it opens. Closes #886. SychPL's #1078 approached the same issue independently; thanks to both. Co-authored-by: SychPL <SychPL@users.noreply.github.com> |
||
|
|
d506382aca |
ci: run the action-matrix sample on its own; name a hang in an edit round (#1037)
The sampled pi-case hole on Body1/F13:side:l7@F14.1 became a real hole with #952 (7.5 s instead of 170 ms); beside the heavy tests on main's push runs it passed the matrix's 90 s action limit in its edit round, reported as the design not loading. The sample now takes every CPU in nextest so nothing runs beside it, and the edit round writes a start line so a hang there is reported as <action>+edit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
6cb3025b72 |
Sheet metal: a hole drilled into a rim is a bore its panel keeps (#560) (#955)
A hole drilled along a panel, into its rim, has no place in the flat pattern as a cut-out, so every such hole was refused. It is now kept as a bore of that panel, in flat coordinates, and cut only from that panel's material when the folded part and its flat pattern are built, so the sheet still unfolds and folds back with it. A hole that would run into a bend, or cross a panel at an angle, is still refused. The flat pattern lists the bores. The action matrix worker takes ACTION_MATRIX_ONLY (just these actions) and ACTION_MATRIX_UNFOLD (unfold and refold every sheet after each action) for rechecking one group by hand. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
ce902be66c |
Fillets and chamfers ending on a boss's pieced wall or beside it, on a face that runs along its seam twice, and loops the loop blend refuses (#926)
Fillets and chamfers ending on a boss's pieced wall or beside it, on a face that runs along its seam twice, and loops the loop blend refuses - A straight edge whose end meets one curved surface in several faces (a cylinder a join left in pieces) ends on that surface: the section is cut where it crosses each seam, which is shortened there; where no seam is crossed (the wall missing inside the other body) the section lies on the bared surface and the rest of the side edge becomes a seam. - Two end faces that aren't both planes meeting in lines: each face takes the section's points on it, cut where it crosses the edge between them. Not where an end face runs on smoothly from a side (an earlier round): the corner build takes those. - Face boundaries close over several connector edges. - A face on a periodic surface running along its seam twice (as a STEP file gives it) is rebuilt the same way (#691). - A curved chain ending square on a face that runs on past its side extends that face's seam. - A smooth chain stops before an edge between faces that meet smoothly. - A loop the loop blend refuses for its shape is blended edge by edge; refusals about its size stand. - Action matrix: ACTION_MATRIX_ACTIONS and ACTION_MATRIX_VALIDITY for quick local runs; the fillets and chamfers that pass now recorded. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
78d9aa0153 |
Booleans: small tools in large bodies are traced at their own scale (#559) (#946)
A through-all hole's tool is twice the largest body long, and the boolean's tolerances followed that length: a 6 mm hole through a 920 mm part was traced at nearly 1 mm, wider than the hole, and the cut came out empty or failed. When every other strategy has failed, the boolean is now asked again (unshifted, then once shifted) at tolerances scaled to where the bodies meet: the overlap of their boxes and the thinner operand's thickness. Its result is checked as the others are and held to the retry guard. It runs last, so whatever an earlier strategy answered is kept as it was, and only for single-shell operands (bodies in several pieces are retried a piece at a time, each with this pass of its own). The sampled shortcut also gave up on a slender tool lying across its box (a long hole drilled at an angle fills little of it): it now samples past the first 2000 points until enough land inside, so a tool that misses a body leaves that body as it is. Bodies that had enough samples in the first 2000 are sampled exactly as before. Baseline: the 90 actions that newly pass, rechecked one by one with the final build. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
6a6a7e2865 |
test: give an action-matrix design 300 s to load (#812)
Loading a design (from a worker's start or restart to its first output) gets 300 s; each action keeps 90 s. oracle/41-tube-radial-holes (about 23 s here) timed out loading on a loaded CI runner, and reloads after a hung action were charged to the next action. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
a3dfbaa0b0 |
Booleans build the same body every time: face order no longer follows heap addresses (#748)
truck's face and edge IDs are their addresses, so walking maps keyed by them followed heap layout, and the ribbed lid's side-wall hole passed or failed by chance. The planar boolean's rebuild and glue now take truck's connected components in the shell's order, and the planar boolean's own maps are ordered. Healing's union-find keeps the lesser root and takes a run's ends in order of use. The face classification after an intersection orders each component's faces by the shell first. The lid now builds the same body on every run, with a test that builds it six times in one process. Its 0.5 mm side-wall holes, and one sensor enclosure hole of the same kind, now fail every time and are marked failing in the baseline. Fixes #707. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
cb071bb93b |
fix: axis or tangent plane on a drill tip no longer fails with "no face at NaN" (#567) (#655)
The nearest point on a triangle with a zero-length edge (a cone's tip) is no longer NaN, so an axis or tangent plane on a drill tip works again (#567). |
||
|
|
1e4387f3ea |
fix: cuts no longer split walls they don't touch (#670)
A cut built slab by slab (the exact prism boolean) sewed the result from horizontal slabs and only joins merged the coplanar pieces back. So a floor vent cut through the Raspberry Pi case split the long wall into strips at the ports' tops and bottoms (87 faces instead of 79 at 32 mm), and at 24 mm the end opening split the end wall. - Prism booleans merge coplanar neighbours for every operation (faces only: edges, curves and surfaces stay exact), keeping each face's construction source where all its pieces share it, Split Face lines and regularization protection. Painted or protected operands keep their authored pieces as before. - The prism history now tells apart a wall's several edges with its caps (a wall with openings meets each opening's floor), so cuts beside existing openings keep exact history and faces keep their names. - Tests: the Pi case's faces pinned after every feature at 24, at 24 changed to 32, and built at 32 (each outer side one face); random openings and bosses on a shelled case never split another side; every corpus design rebuilds a parameter edit like a fresh build and reverts exactly. - Action matrix baseline: demo/pi-case re-blessed (fewer, merged faces; no regressions), demo/pi-case-0.8 recorded, and 88 new passes on regressions/lid_ribs_flush_with_window. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
5ef1dcba8e |
Sheet metal rims and holes, plastic features, lofts, raised pieces and merged walls take face attachments (#677)
Sheet metal rims and bend ends attach by name (<panel>:rim.<edge>, <flange>:rim.bend0/1), as do face profiles from sheet faces. A plain or counterbored Hole square to a panel is machined into the flat pattern. Boss, Lip, Rest and Snap Fit keep the body's history and name their own faces. Hole tools name their faces by the part they cut, and pattern copies as copies. A pattern's repeated fillets keep the body's history. Loft sides are named by their section curves. A piece Offset Face moved off its face's plane attaches by its own qualified name. Sides of a profile grown to overlap a flush body keep their sketch line's name, so walls a Join merged take a sketch (#681). Face sketch 75% -> 90%, offset plane 75% -> 90%, press-pull/extrude 64% -> 85% in the action matrix; baseline blessed. Fixes #494, fixes #495, fixes #560, fixes #561, fixes #563, fixes #564, fixes #681. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
29258767ce |
fix: refuse Boolean retries that change the part away from the tool (#616) (#644)
Joining ribs flush with a lid's window left a zero-thickness slit far from the rib (the planar fallback glued back only one of the faces its pieces shared) and displaced the tool on the other joins. Gluing now joins every shared face pair, coincident-face separation checks there is material behind a pushed face for every join, and any join or cut that needed a retry must be closed, keep volume monotonic and leave the part unchanged outside the tool's box, or it is refused with an error. Feature command replies carry the feature's warning. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
8be0f64f5a |
Fillet and chamfer of one edge ending on curved, slanted or several faces (#646)
A single edge's blend no longer needs a plane square to the edge at each end. Straight edges: each rail ends where it reaches the end face's surface, the side edges there are shortened or continued along their line or circle, and the blend ends where its cylinder or chamfer plane meets that surface (a fitted curve checked against both). A chamfer may end across two faces. Curved edges: at a slanted or curved end the rolling ball runs on past the end and the strip is cut back where it meets that face. A straight edge running smoothly into a bend or rounded corner is blended along its whole smooth chain. Rolling-ball fixes: smooth chains follow edges stored against their curve, the ball touches only the faces of the edges it rolls along, the seam normal at a joint comes from the face there, and each strip is fitted with neighbouring sections at its own spacing. Action matrix: edge.fillet 83.6% -> 93.0%, edge.chamfer 82.6% -> 93.3% (697 new passes, no regressions); reference tests 76/76. Fixes #556 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |