mirror of
https://github.com/bherbruck/solidcraft.git
synced 2026-11-07 12:31:56 +00:00
65b02ff7ab28eb60055ecd5e501ced94de8b1765
141 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
335278e3c7 |
Wave 266/509: Profiler: commands, feature evaluation, io; diagnostics.profile; CLI --profile (and 3 more)
4 commits, squashed; the originals stay reachable from tag archive/merge-main-develop. - |
||
|
|
3dc5d6d475 |
Wave 265/509: Profiler crate: nested per-thread spans, an aggregate table and a Chrome trace
1 commits, squashed; the originals stay reachable from tag archive/merge-main-develop.
-
|
||
|
|
5a4e482e9c |
Wave 260/509: Formatting: rustfmt over the rebased branch (and 3 more)
4 commits, squashed; the originals stay reachable from tag archive/merge-main-develop. - |
||
|
|
d6dacbd6d8 |
Wave 258/509: Cargo.lock: resolved for the merged manifests (and 3 more)
4 commits, squashed; the originals stay reachable from tag archive/merge-main-develop. - |
||
|
|
0de308b21d |
Wave 213/509: kernel: a tangent chain stops at a smooth edge (and 3 more)
4 commits, squashed; the originals stay reachable from tag archive/merge-main-develop. - |
||
|
|
0bd4531c7c |
Wave 110/509: WIP kernel: Body::mesh(&MeshTolerance) as the one mesher (does not build yet)
1 commits, squashed; the originals stay reachable from tag archive/merge-main-develop.
-
|
||
|
|
47c5f081d4 |
Wave 78/509: smlib tests: SSI corpus scorer and its parity with score.py
1 commits, squashed; the originals stay reachable from tag archive/merge-main-develop.
-
|
||
|
|
b1315a3de9 |
Wave 23/509: solidcraft-step: STEP topology into schema 4 B-rep records
1 commits, squashed; the originals stay reachable from tag archive/merge-main-develop.
-
|
||
|
|
61f8fbcbfe |
Wave 18/509: solidcraft-smlib: exact mass properties, Brep::mass_properties and Brep::area
1 commits, squashed; the originals stay reachable from tag archive/merge-main-develop.
-
|
||
|
|
af6528b420 |
Wave 15/509: kernel: a side-by-side runner for truck and SMLib booleans (and 1 more)
2 commits, squashed; the originals stay reachable from tag archive/merge-main-develop. - |
||
|
|
7f7358f918 |
Wave 13/509: STEP geometry as plain data: read and write ISO 10303-42 curves and surfaces without truck
1 commits, squashed; the originals stay reachable from tag archive/merge-main-develop.
-
|
||
|
|
709191218c |
Wave 11/509: solidcraft-smlib: SMLib statically linked behind its C API, with a safe wrapper (and 1 more)
2 commits, squashed; the originals stay reachable from tag archive/merge-main-develop. - |
||
|
|
af07f4e0e5 |
Arabic interface language with right-to-left text (#3762) (#3768)
* claim: #3457 * Hebrew interface language with right-to-left text (#3457) Adds a complete Hebrew catalog (assets/locales/he.json, original translations) and registers `he`. egui 0.36 shapes each font run with harfrust, so a run of Hebrew letters is drawn right to left, but it places the runs of a line left to right in stored order. The new `bidi` module runs the Unicode Bidirectional Algorithm (unicode-bidi, MIT OR Apache-2.0) over each message of a right-to-left catalog once, giving egui the runs in display order with brackets mirrored and placeholders kept whole, while leaving each Hebrew run's letters in reading order for the shaper. A test lays messages out with a real Hebrew font and checks where the glyphs land. Desktop builds append a system Hebrew font (Arial Hebrew / SF Hebrew, Segoe UI / Arial, Noto Sans Hebrew / DejaVu Sans). Layout mirroring, wrapped multi-line RTL paragraphs and a web Hebrew font are follow-ups. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Hebrew: translate the new Describe Command label; list he in the control protocol Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Hebrew: catch up with main's catalog and the new ribbon (#3457) - Translate the 258 messages main added since the branch was cut, drop the 38 it removed (10 renamed ones keep their translation) and retranslate the two whose English changed (toolbar → application bar). - The timeline title is ציר הזמן, matching the glossary. - Ribbon buttons split their labels into two lines from the start of the string; Hebrew labels come in display order, so the first line showed the end of the phrase ("חדשה / סקיצה"). For right-to-left labels the first line now takes the words at the end of the string, and a shortened line loses characters, and shows its ellipsis, on the left. The word-boundary sweep checks Hebrew from the lines the galley is built from, since epaint's right-to-left rows carry zero-width glyphs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Hebrew: after rebasing onto main, load the Hebrew face with the cached system fonts main now searches the system fallback faces once (SystemFonts, on a thread); the Hebrew face joins that search with its coverage check. Drop the three camera-animation messages main removed (#4296) from the Hebrew catalog. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Hebrew: translate the messages main added after the catch-up (#3457) Translates the messages main added since the last catch-up: the history bar's buttons and name toggles, the 3D mouse driver and axis mapping, the thread size columns, the File view (home page), the redesigned Preferences, the new issue report dialog, free orbit and the assistant's setup card. Drops the one message main removed. The catalog has every English message again, so the complete-catalog checks pass for he. * Arabic interface language (right-to-left, on the Hebrew bidi path) Adds an original Arabic translation of the whole English catalog (assets/locales/ar.json, every message) and registers it. `ar` joins the complete catalogs, so a message added to en.json later fails the build until it is translated. It goes through the right-to-left path of #3458 unchanged: crate::bidi puts each message in display order and leaves every Arabic word's letters in reading order for harfrust, which joins them with the font's own tables. Ribbon labels use the right-to-left line split from the same stack. fonts.rs adds a system Arabic fallback after the Latin interface font, which keeps spaces, digits and Latin text so each Arabic word stays one shaped run: Segoe UI/Tahoma/Arial on Windows, SF Arabic/Geeza Pro/ Damascus/Tahoma on macOS, Noto Sans or Naskh Arabic/KACST One/DejaVu Sans on Linux, or NotoSansArabic-Regular.ttf in CRAFT_FONTS_DIR. It is the first fallback for an Arabic UI (Arial Unicode, a CJK candidate, has Arabic letters without joining data) and the last otherwise; like Thai and Hebrew it is never promoted for a CJK interface. Tests: the catalog comes back in display order with no directional controls, and Arabic laid out with a real font lands on screen word by word in reading order. * Hebrew: review the catch-up translations; restore the camera-animation messages (#3457) - Review of the 533 messages translated in the previous commit: 21 corrected. Keys in the motion dialog are keyframes (נקודות מפתח, as in Add Key), the Design workspace is תכן as in its label, a dropped "(Direct Driver)" is restored, terms aligned with the rest of the catalog (פורמט, סוכן קוד, רצועת הכלים), and a few calques reworded. - Translate ui.animate_view_changes, ui.animation_speed and ui.look_at_anim_desc, which main has again, so he stays complete. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Arabic and Hebrew: translate the messages main added since (#3457, #3762) Both catalogs again carry every English message. The 760 messages main added since the last rebase (render workspace, material editor, standard views, sheet metal Path Flange, AI app connections, document-on-disk notices and more) come from A-AL-ANAZI's translations on #3768; the five Perforate dialog messages are new here. The earlier Hebrew review is kept on top of them, and 33 of the new Hebrew messages are corrected: "completed" was "perfect" (מושלם → גמור), Regrade read as ranking (now תיקון צבע מחדש), shaders, guarantee, the Mirror reflection mode, simulations and displacement. Co-authored-by: Abdullah <alksa2025@gmail.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Arabic and Hebrew: attribution rows as a pending file main now takes new ATTRIBUTION.md rows as one file per change (attribution/pending/), so the he.json and ar.json rows move there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Arabic and Hebrew: translate the 23 messages main added since (#3457, #3762) Both catalogs again carry every English message; the two theme-page messages main removed are dropped. Twelve of the new messages (link updates while loading, the agent chat's model choice, plugin search, render quality) come from A-AL-ANAZI's translations on #3768; the sketch plane descriptions, the rigid group and empty-boolean messages, free sketch points and the web update note are new here. Co-authored-by: Abdullah <alksa2025@gmail.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Arabic and Hebrew: translate the 12 messages main added since (#3457, #3762) Eleven come from A-AL-ANAZI's #3768; "Turn Up Axis" in Hebrew follows the catalog's existing up-axis wording, and the agent chat's no-tool-call message is new in both. Co-authored-by: Abdullah <alksa2025@gmail.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Arabic and Hebrew: translate the 22 messages main added since (#3457, #3762) * Arabic and Hebrew: a label found by its English text comes back in display order too (#3457, #3762) * Arabic and Hebrew: translate the 32 messages main added since (#3457, #3762) * Arabic and Hebrew: translate the 34 messages main added since (#3457, #3762) * Arabic and Hebrew: translate the 30 messages main added since (#3457, #3762) * Arabic and Hebrew: translate the 7 messages main added since (#3457, #3762) --------- Co-authored-by: rootarchitect <7781866+rootarchitect@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Abdullah alanazi <x1700@MacBook-Air-Abdullah-2.local> |
||
|
|
3726959d82 |
Control channel: check the token before parsing the whole request (#6643)
Until a connection had shown the token, its first line (up to 16 MiB) was parsed whole into a JSON value. A line of [0,0,...] that size is hundreds of MB once parsed, so 16 connections without a token could make the app run out of memory and lose unsaved work. The token is now read from the request object without building the rest of it: other fields are only skipped, and anything but an object with a string token is refused as before. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
af1d15b5ea |
Canvas to Sketch: trace a canvas image into a sketch on it (#3931) (#4263)
* Canvas to Sketch: trace a canvas image into a sketch on it (#3931) New command canvas.to_sketch, offered as Canvas to Sketch in the canvas context menu. It traces the canvas image (automatic Otsu threshold, light drawings on dark backgrounds inverted) with interpolated marching squares and Douglas-Peucker, and adds lines and cubic Bezier splines through Insert SVG's add_geometry to a new sketch on the canvas plane, with the canvas' width, centre, rotation and flip. Holes stay holes; one undo step. The image's declared width x height is checked before decoding (at most 40 megapixels) and the decoder runs under image::Limits, since canvases are capped by file size, not pixel count. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Move the new message to a pending locale file 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> |
||
|
|
ebb6cc53ab |
Crash reports: capture native crashes on macOS (#2113) (#6593)
* claim: #2113 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Crash reports: capture native crashes on macOS (#2113) A signal handler for SIGSEGV, SIGBUS, SIGILL, SIGFPE, SIGTRAP and SIGABRT writes the same <journal>.native.json as the Windows exception filter: the signal, the faulting module and offset, the thread and a frame-pointer walk. The next start reports it instead of "an unclean exit". The signal then goes on to the previous handler or the default action, so macOS still writes its own crash report. native_crash_macos.rs joins the crash-safety skill's list of files that may use unsafe (no safe API can catch these signals). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
0b2d3ecd44 |
Release 0.24.0: version bump, design format 39 (#7394)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
8630a3f0e5 |
External STEP corpus: nightly import checks (#1397) (#6407)
* claim: #1397 * External STEP corpus: nightly import checks on real-world files (#1397) tests/external-corpus.toml pins 20 real-world NIST PMI STEP files (AP203 geometry-only and AP242 editions from several vendor exporters, public domain) by archive and per-file SHA-256 with the licence recorded. cargo xtask external-corpus downloads each source once into the gitignored corpus/external/, verifies every hash, imports each file headless (file.insert_step + inspect.measure) and checks body count, total volume (0.1 %) and area (0.5 %) within tolerances and time and memory budgets. A file whose upstream hash changed is reported as 'source changed', never as our failure. --bless "why" re-records expectations in the manifest with a dated reason. The External corpus workflow runs it nightly. assets: skip corpus/ when scanning for attribution (downloaded case data is never committed). --------- Co-authored-by: Dahak Builds <dahakbuilds@users.noreply.github.com> |
||
|
|
66b872a749 |
Web app: open a design from a same-origin path (#6670)
?open= now also accepts an absolute path on the page's own origin, fetched with the page's scheme, so a self-hosted setup that serves SolidCraft and other tools under one origin can link a design on a LAN without a public HTTPS address. Absolute URLs keep the HTTPS-only rule (a URL on the page's own origin is also accepted), redirects must end on HTTPS or the same origin, and protocol-relative, dot-segment, backslash and control-character values are refused. |
||
|
|
4d61100534 |
Release 0.23.1: version bump, design format 38 (#7035)
The component colour tests no longer assume a design always carries a list of pending format changes; once the release folds them, there is none. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
8e61eb7d6f |
Release 0.23.0: version bump, design format 37 (#6868)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
4cd9a4f4d4 |
Web app: open a design from a link, and an embed mode (#6252) (#6253)
* claim: #6252 * Open hosted designs in the web app and add an embed layout Fixes #6252. Fetch HTTPS design links with bounded reads and open them as unsaved copies. Keep model panels and joint controls in embeds without browser persistence, application chrome, or unload prompts. Add a full-app link and iframe docs. Cover query parsing, hostile URLs, size limits, and the compact layout. * Translate the linked-design messages into Japanese and Chinese |
||
|
|
2cf05388f1 |
Release 0.22.1: version bump, design format 36 (#6628)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
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> |
||
|
|
cc1e654690 |
Warn when a design is open elsewhere or changed on disk (#5467) (#5468)
* claim: #5467 * Warn when a design is open elsewhere or changed on disk (#5467) The desktop app keeps a lock file next to each open design (.~<file>.lock: computer, user, version, opened and refreshed times), refreshes it every minute and removes it on close; a lock not refreshed for three minutes is stale and ignored. Opening a design that another SolidCraft has open asks: Open Read-Only, Open Anyway or Cancel. A read-only design saves only to another file. A design remembers its file's size and modification time when it is opened or saved. Save over a file another program or computer changed since asks: Save a Copy (the default), Overwrite or Cancel. Programmatic calls never ask: doc.open reports open_elsewhere and takes read_only, and file.save over a changed file returns an error until it is given overwrite: true. ui.documents answers both questions. |
||
|
|
2a0096fe4a |
Release 0.22.0 (#6344)
* Release 0.22.0: version bump, design format 35 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Release 0.22.0: tests no longer expect the folded render and material changes to be pending Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- 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 |
||
|
|
612d9d08dd |
cadmpeg 0.6.3: FreeCAD and Rhino import in the browser too (#4482)
cadmpeg 0.6.3 is pure Rust (ruzstd instead of the zstd C library, zip 9), so solidcraft-io depends on it on every target and the wasm build reads .FCStd and .3dm files like the desktop app. The browser's file pickers offer them. 0.6.3 replaces DecodeOptions::container_only with a decode depth; ask for Geometry, what its STEP writer reads. zip 8 leaves the tree, and with it the three cargo-deny advisory exceptions kept for it. Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> |
||
|
|
01220d3eb5 |
Version 0.21.0 on main (released from rc.2's code) (#5774)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
d5a046c3d3 |
Agent chat: end the agent's process group where kill is busybox' (#4587) (#4588)
* claim: #4587 * Agent chat: end the agent's process group with the system call (#4587) The group was signalled with a `kill` program: `kill -s TERM -- -<pgid>`. That works with procps' `kill` and with BSD's, but busybox' `kill` takes no `--`: it prints its usage, exits 1 and signals nothing. The agent's helpers (the CLI an adapter wraps, the MCP servers it starts) then stay alive after the agent is ended. The group is signalled with the system call instead, so no `kill` program and no shell are needed and the behaviour is the same everywhere. `nix` (MIT) is already in the tree through zip, and only on Unix: the browser build does not take it. The two tests that cover this now pass where they failed before: `agent_chat::process::tests::dropping_the_process_ends_its_group` and `agent_chat::process::tests::stopping_the_agent_leaves_no_helpers_running`. |
||
|
|
a51dfc9e1f |
Release 0.21.0-rc.2 (#5691)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
fdde3f9da9 |
Add macOS native menu bar (#2361) (#4531)
* claim: #2361 Co-Authored-By: GitHub Copilot <noreply@github.com> * feat: add native macOS menu bar (#2361) Reuse document actions and unsaved quit handling in native application, File, Edit, Window and Help menus. Replace duplicate header controls only when native installation succeeds, preserving other platforms and the fallback UI. Co-Authored-By: GitHub Copilot <noreply@github.com> --------- Co-authored-by: GitHub Copilot <noreply@github.com> |
||
|
|
2bf3d4e11f |
Release 0.21.0-rc.1 (#5566)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
030187452a |
Release 0.20.0 (#5118)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
198fbeb814 |
i18n: every UI label reaches the catalog, on the UI kit (#2483)
On main, 120 label literals (95 distinct) can't be translated in any locale: the English catalog doesn't reach them. Catalogue them in en, ja, zh and de, translate indented row labels once for display and measuring, look up the thread profile by its id, and give each navigation preset's help, shown by the mouse mapping picker, a catalog message. A guard tokenizes the UI sources and checks every label literal of a kit call, of context_menu::button and of tr_label/tr/SelInput against the English catalog, resolving kit calls by their imports. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
5899e5b6c5 |
Release 0.19.0 (#4603)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
4b23bb3a03 |
Implement compact workspace layout (#2029) (#4533)
* Vertical history strip: left of the browser, compact rows, hollow-circle marker, collapsed rail hover * Vertical history strip: seam handle to expand and collapse names, drag to resize with snap * Vertical history strip: no empty gap below the transport * Show the history seam arrow only on hover (#2028) * claim: #2021 * Redesign the Assistant chat panel with shared UI components * Show Assistant in the shared floating panel shell * Extend floating Assistant to viewport height and shift navigation * Dock Assistant before history and match docking preview bounds * Align Assistant top margin with floating shell cards * Extract a shared panel drag grip * Rebuild responsive history sizing and three-way docking * Share browser and History collapse hover styling * Show the History title as soon as its text fits * Animate stacked browser and History expansion and collapse * Make panel folding responsive and independent of frame delays * Let folding panel contents shrink continuously to header height * Use four explicit History transport actions in every layout * Resize the shared Browser and History column from either card * claim: shared compact-mode containers (#2029) * Centralize layout-aware UI containers and enforce their use * Keep docked Assistant at the outer edge beside tool sheets * Use shared surface policy for Assistant tool space * Let tool sheets drag over shell panels while avoiding Assistant * Update Parameters drag bounds assertion for shell overlap * Keep dragged tool sheets below ribbon and workspace selector * Enforce universal UI containers in mandatory repository checks * Remove legacy report windows and require shared window composition * Remove retired UI styling and require shared controls * claim: compact layout preference (#2029) --------- Co-authored-by: bherbruck <brennen.herbruck@gmail.com> |
||
|
|
728f753b80 |
Release 0.18.4 (#4362)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
034aa60d47 |
Release 0.18.3 (#4270)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
93a2922c5e |
Display plans and the model cache for large STEP assemblies (#2814) (#4021)
* STEP import: mesh band faces that wrap around a closed surface correctly Fixes two related bugs that caused SolidCraft to fail to mesh a face wrapping all the way around a closed, non-periodic surface (a revolved ridge band, or a tube-shaped B-spline surface): a missing face, a folded/self-overlapping triangulation, or a hole in the rendered body. 1. Ring edges that run slightly off their surface. STEP files write a surface and the curves bounding it to the file's own declared uncertainty, so a ring edge can legitimately sit a few micrometres off the surface it bounds. The code finding where a ring edge crosses the planned split line compared against the edge's raw (off-surface) point using a hardcoded tolerance far stricter than the file's own precision, rejecting a valid cut. Now matches against the point on the surface directly below the ring crossing, respecting the file's declared tolerance. 2. Closed B-spline surfaces, their slits and their slivers. truck only treats the rotation of a revolved surface as periodic; a face on a B-spline surface whose control net closes on itself (a tube) wasn't recognized as wrapping around at all. This produced a folded face, a hole (a boundary loop landing a full period away from where it should cut), and one near-zero-width sliver face costing the entire body its tessellation plan. Adds periodicity detection for closed B-spline surfaces, period- aware hole-loop alignment, dropping of zero-width slit boundaries, and isolating a too-thin-to-triangulate face so it no longer takes the rest of the body down with it. The GPU shader's periodic wrap mirrors the CPU math so the two don't drift apart. Regression tests: band_faces_split_when_ring_edges_run_off_their_surface, band_face_with_a_zero_width_slit_is_still_meshed, a_sliver_face_too_thin_to_triangulate_does_not_cost_the_body_its_plan. Ablation-tested: disabling either mechanism in (2) reproduces its target test's original failure message while leaving the other test unaffected. * STEP import: mesh the band's split faces, not just split them jyviko asked whether a band wall missing from the interactive app's render was a shading issue or a genuinely missing face. It was missing: the ring- edge split fix made the band's topology correct, but plan_face still produced zero triangles for the two new sub-faces. Two causes, both in plan_face (crates/kernel/src/tess/mod.rs): 1. The tolerance for how far an imported boundary may lie off its surface was tied to the requested mesh's chord tolerance instead of to the body's own size. A finer display tolerance could then reject a boundary a coarser one had just accepted, so the face would drop out exactly when zooming in on it. 2. Near a sharp corner of this flat-panelled band, several boundary points that are legitimately a few micrometres apart (within the STEP file's own declared precision) all projected onto the same surface point. The boundary loop then repeated a point in (u, v), which a triangulator can't follow, so the face's plan failed outright. One face without a plan costs the whole body its plan, and the fallback mesher can't handle a closed B-spline surface either, leaving both halves of the split band with no triangles at all: present in the topology, invisible in every renderer, and absent from the body's volume. Fix: scale the off-surface tolerance to the body's own extent (new Rules::extent), and collapse a run of boundary nodes that land on the same surface point to one (drop_collapsed) before triangulating. Regression test additions to band_faces_split_when_ring_edges_run_off_their_surface: the body's volume now matches the analytic pentagon prism (was a third of it - only the top cap - before this fix); display_plan leaves no face without triangles from coarse to fine tolerance; and the actual tolerance and facet angle the viewport draws with gives the split band its full lateral area on both halves. Confirmed on review_band_big.step, the fixture behind the review screenshots: volume's relative error against the analytic pentagon prism drops from 1.4e-4 to 4.1e-6, and the band wall now occludes the floor grid behind it in a snapshot the same way the top and bottom caps always did. Full kernel suite: 739 tests, 0 failed. * STEP import: hold an imported boundary to the file's own tolerance, not the part's size jyviko: the off-surface acceptance added in the last commit (rules.extent * OFF_SURFACE) scaled with the part, so a 2 m part silently accepted a boundary 2 mm off its surface while a 20 mm copy of the same part accepted only 0.02 mm. A STEP file's own declared uncertainty does not grow with the part, so the bound shouldn't either. Body gains boundary_tol: Option<f64>, Some(file's declared tolerance) for a body read from STEP (crate::step_in::Units::tol, already used by the ring-split fix in split.rs), None for anything this kernel built. It's set before the import's own unmeshed-face check runs, and carried over by the two face-split operations that re-cut an imported surface (splitface.rs, outline.rs), since the file's uncertainty still describes those boundaries afterward. plan_face's accept now reads: the file's own tolerance when the body declares one, or the old chord-tolerance/extent bound otherwise. The old bound's tol * 10.0 term had to go too, not just the extent term: at a 2 m part's typical display tolerance that term alone is ~20 mm, nearly ten times the extent bound jyviko objected to, so keeping it would have left the exact 2 m/2 mm example still silently accepted. Two new tests in step_in/tests.rs: - band_faces_split_when_a_scaled_copy_runs_off_its_surface: the same band fixture at a realistic 2 m scale with the same absolute slop and declared uncertainty as the small one, meshes the same way at every chord tolerance from coarse to fine. - off_surface_budget_follows_the_file_not_the_part_size: the actual regression. The same off-surface error is accepted or refused the same way whether the part is 20 mm or 2 m; a 2 mm error against a 1 µm declared uncertainty is refused at both sizes now (accepted at 2 m under the old bound, refused at 20 mm - that asymmetry was the bug). Checked at both a coarse and a fine display tolerance. Known gap, not fixed here: a STEP-imported body saved into a .solidcraft design and reopened loses boundary_tol (native.rs's decoder has no field to read it from) and falls back to the old extent-based bound on reload. Today's design format has no concept of this value at all; persisting it is a real format change, out of scope for this fix. Full kernel suite: 776 tests, 0 failed. clippy -D warnings clean. * Display plans for STEP threads and pointed ends (#3847) Three faces cost a threaded or pointed STEP part its whole display plan, so it was drawn from the reference mesh: cracked, faceted, and never refined up close. - A loop through a pole (a cone's apex on the boundary) seemed to wind around the surface: the jump at the apex, unwrapped to the nearest copy, was arbitrary. The loop is turned to end where it leaves the pole, so the step that closes it is an ordinary one (`seam::close_through_pole`). - Projection onto a spline with hundreds of spans (a helical flank) restarted from a 16 x 16 grid and settled on another turn; it now starts from two points per span, capped. - Sag refinement no longer inserts a point exactly on a boundary side, which split the side and failed the face. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * tess: a refused face's edges are divided finer and it is planned again (#2814) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LGeCa5jWWdroMWvXxN3LLM * tess: sliver faces plan empty; a face no method plans is filled flat from its nodes (#2814) A face whose boundary runs out and back along itself (two edges between the same vertices, a rounding apart, as STEP files write slivers) encloses nothing and is planned with no triangles. A face still refused after its edges are divided finer (a cusp, a sliver whose sides sag across each other, a small cap at a pole) is filled flat from its shared boundary nodes, so the rest of the body keeps its display plan instead of falling back to the reference mesh. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LGeCa5jWWdroMWvXxN3LLM * display mesh tests: a rim the chord tolerance leaves a line is divided again (#2814) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LGeCa5jWWdroMWvXxN3LLM * portable B-rep: up to 8192 control points along a spline direction (#2814) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LGeCa5jWWdroMWvXxN3LLM * solidcraft-cli: --debug logs what the engine reports to stderr Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LGeCa5jWWdroMWvXxN3LLM * STEP import: a spline written over a tiny parameter range is read over one (#2814) Some writers parameterize splines over a few millionths (a humanoid robot's edges span 5.4e-6). The kernel tells parameters apart only to 1e-6, so over such a range it evaluated the curve's end wrongly, and trimming an edge to its vertices dropped a control point: the bodies could not be stored exactly and the whole model cache was left out of the design. The knots are now stretched to span one; the curve is the same and edges are trimmed by their vertices, so nothing read from the file refers to the old parameters. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LGeCa5jWWdroMWvXxN3LLM * model cache: a body keeps its file's declared accuracy (#2814) A body restored from the cache dropped the accuracy the file it was read from declares, so the planner held its boundaries to the kernel's own bound and a reopened design drew differently from the import. It is stored with the body's runtime values, and only when there is one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LGeCa5jWWdroMWvXxN3LLM * tess: a boundary within a hundredth of its body lies on its surface, at every quality (#2814) #1721 held a body read from a file to the accuracy the file declares. A writer declares what it aims for, not a bound its edges keep: a 251-body robot assembly declaring 0.01 µm has boundaries 10 to 30 µm off their surfaces, and 95 of its bodies lost their display plans. The bound is a hundredth of the body again, what Normal quality always allowed, and now the same at every quality, so zooming in still never drops a face (#1721's point). A file declaring more raises it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LGeCa5jWWdroMWvXxN3LLM * STEP import: keep faces whose edge vertices sit slightly off their curves Some exporters write an edge's vertex beside the end of its curve, further off than the accuracy the file declares (a surface export declares 0.01 mm and puts a vertex 0.19 mm off two spline ends). The reader refused such edges and left the face, and with single-face bodies the body, out. A vertex may now sit up to the file's tolerance or 1/1000 of the model's size (the diagonal around its VERTEX_POINTs), whichever is larger, never more than the existing 1 mm ceiling. Spline and open-conic edges have the end control point moved onto the vertex, so every such edge meets its vertices exactly. The file's declared accuracy still governs closed-curve, seam and circle checks. * tess, io: review clean-ups (#2814) - A sliver face is one whose loops are all slit: drop_slits finds it in the retry after a failed plan, so the pre-check on every face (folded) is gone. - The flat fill uses cdt::triangulate (a lenient fill that leaves out sides crossing one already kept) and its flood-fill inside test, and the plane from geom::Plane. - Refinement only builds its indexes when a face was refused, takes the faces to plan again from edge_faces, and re-samples edges on the pool; Rules::finer for the finer rules. - One PackageWriter::fits for the model cache, the preview and the thumbnail. - The band split's ring tolerance lives in split.rs; comments say what the off-surface bound is now. - The CLI logger prints Level::as_str(). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LGeCa5jWWdroMWvXxN3LLM --------- Co-authored-by: David Lackovic <lackovicdavid1234@gmail.com> Co-authored-by: bherbruck <brennen.herbruck@gmail.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: jyviko <2501648+jyviko@users.noreply.github.com> Co-authored-by: Ray <raykholo@users.noreply.github.com> |
||
|
|
57bcc40838 |
Release 0.18.2 (#3970)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
522ae77556 |
Release 0.18.1 (#3851)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
c3151fb7fe |
Release 0.18.0 (#3792)
Version 0.18.0; no pending design format changes, so it writes format 28 like 0.17. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
1122cd44b8 | UI library, tokens, fonts and icons (step 5 of #2016, after #2287) | ||
|
|
c5129a45d7 |
Release 0.17.0 (#3629)
Version 0.17.0; design format 28 fixed (13 pending changes folded). 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> |
||
|
|
46a0b25280 |
STEP import: CJK names read back whole (#2344) (#2347)
Adjacent \X2\...\X0\ runs, as step_out writes one per character, now decode: the backslash opening the next run was pushed as a literal, so a name exported as 圆角 came back as 圆\X2\89D2\X0\ (also every linked component insert, which round-trips through STEP). STEP and IGES bytes that are not UTF-8 are decoded in their detected legacy encoding (chardetng + encoding_rs) instead of from_utf8_lossy, so GBK or Shift_JIS names from vendor files no longer turn into U+FFFD. Co-authored-by: bherbruck <brennen.herbruck@gmail.com> |
||
|
|
d0afc31632 |
Save the evaluated model with every design: exact, stored once, scaled caps (#3053) (#3093)
* Model cache written by default: exact bodies, stored once, scaled caps (#3053) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * bench-open: say why bodies were not kept * Exact planes and revolutions; budgets for large bodies (#3053) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Native B-rep: rebuild shells as the kernel made them (closed and seam edges) (#3053) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs: the model cache and the exact native B-rep (#3053) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * bench-open: time a save without the cache too * Model cache entries are Deflate-compressed (#3053) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Model cache: one that does not fit the design file is left out, never a failed save (#3053) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
d3fa22e987 |
3D mouse calibration in Preferences (#2326)
Adds a 3D mouse calibration section to Preferences (#1463). |