Commit Graph

501 Commits

Author SHA1 Message Date
github-actions[bot] 80dcf9de7f Regenerate THIRD-PARTY-LICENSES.txt and docs/features.md [skip ci] 2026-10-19 20:16:40 +00:00
rlartot 31b41978fc Construction geometry on model vertices follows them when a parameter moves them (#568) (#2409)
Thanks @rlartot.
2026-10-19 16:11:38 -04:00
Brazz 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>
2026-10-19 16:10:45 -04:00
NOWN-DEV b0b59480eb Joints: relations that tie part of a placement (#2497)
Joints can tie part of a placement: parallel, angle, point on plane and more (#2496).
2026-10-19 16:08:23 -04:00
NOWN-DEV 473f1e6516 Sheet metal: readable face names from the sheet itself (#2275)
Sheet metal faces get readable names (#2272).
2026-10-19 16:08:01 -04:00
NOWN-DEV 539c17b425 Joint sweep: drive a joint until parts touch, and report where (#1981)
Joint sweeps can stop where parts touch and report the contact and remaining room.
2026-10-19 16:07:44 -04:00
DuBearte b3f205a638 Agent chat: the design bridge gets its own MCP name, so a user's solidcraft entry can't shadow it (#2592) (#2596)
* claim: #2592

* fix(agent-chat): the design bridge is named solidcraft-app (#2592)

A user's own MCP entry named `solidcraft` (as docs/mcp.md suggests) took the
bridge's place in agents that keep their own entry on a name clash, so the chat
worked on a headless session instead of the open design.

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>
2026-10-19 16:05:17 -04:00
cronos bd4eb42c2d Pin analytic robustness and edge-contact scale regressions (#1950)
* test: pin analytic robustness and edge-contact scale regressions

* test: freeze patterned-bore reference after body grouping change
2026-10-19 16:05:00 -04:00
NOWN-DEV 99d8d382b9 Bill of materials: part properties on components and assembly.bom (#1888) (#1899)
* Bill of materials: part properties on components and assembly.bom

A component definition now carries part properties (part number,
description, revision, other tools' keys) and free text properties,
saved with the component and shared by its occurrences.
component.metadata and component.metadata.set read and change them in
one undo step; Paste New copies them; parts.insert numbers standard
parts from their standard and size, and parts.resize renumbers them.

assembly.bom counts the placed components (flat: parts at any depth
through their subassemblies; top: direct children), grouped by part
number or by definition, sorted by part number, and writes CSV (fixed,
quoted columns) or JSON. The app gets a Bill of Materials window on the
INSPECT panel that lists, edits and exports the rows.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Bill of materials: name a merged row's equal definitions once

Two standard parts with the same size are separate definitions with the
same name; their row now reads "SHCS M6x20" instead of repeating it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Window widths test: close the Bill of Materials window between commands

The test closes the floating windows a command opens before starting
the next one; the Bill of Materials window was left open and measured
against the next dialogs' limits.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Bill of materials: sub-parts in their part's row, and part properties without re-evaluating

assembly.bom takes group_children: true. A part with a part number keeps
what is placed inside it (a bolt's washer and nut) in its own row, listed
under it as children (items 1.1, 1.2, with each and count) instead of rows
of their own; bolts with different contents stay different rows, and
total_occurrences is the same either way. The window has a switch for it
and shows the children under their part; the CSV lists them after their row.

Changing part properties re-evaluated the model, re-seated every joint and
rebuilt the placed model: 361 ms per change with 30 jointed bolts. A change
that only touches components' metadata and properties now takes the same
path as a render-only change (proved on the whole Document), also for its
undo and redo: 0.6 ms.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Bill of materials: look the structure up once, not per subassembly

Deciding whether a subassembly is a part (it has bodies of its own) scanned
every body of the model for each subassembly, and each body looked up its
feature by a linear search of the timeline: subassemblies × bodies × features.
assembly.bom now indexes the placements, the body owners
(Document::body_owners: one pass over the bodies with the timeline in a map,
the same rule as model_body_component) and the numbered components once per
call. 600 bodies and features with 60 subassemblies: 8.1 ms → 1.3 ms; the
old cost grows with the cube of the design's size.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: bherbruck <brennen.herbruck@gmail.com>
2026-10-19 16:04:39 -04:00
William Dunn d8d04c9009 Tool modifiers: shared resolve, classic defaults, preview-safe Ctrl (#1616)
* Centralise tool modifiers with classic defaults and preview-safe Ctrl.

Route sketch/selection chords through a shared resolver. Keep Alt snap
suppress and dual toggle as defaults; optional Shift add-only and Ctrl
snap mapping. Skip preview rollback while a manipulator drag is active.

* Address #1616 review: classic snap suppress, single viewport owner, docs.

Default suppress to Ctrl/Cmd or Alt; drop navigation set_suppressed; remove unused label_key; add preview rollback gate test; document sketch modifiers.

* fix(#1616): correct Modifiers primary in tests; simplify rollback fixture.

* Treat Ctrl as primary off macOS, and rustfmt the modifier files.
2026-10-19 16:04:28 -04:00
SS-EN fb82ccb273 Timeline/MCP API: suppress lists, dotted edit keys, set_parameter expression (#2899)
Timeline and MCP edits take suppress lists, dotted edit keys and parameter expressions.
2026-10-19 10:14:23 -04:00
SS-EN 771f62be71 Interference: clear apart pairs from their meshes, intersect the rest in parallel, time budget (#2895)
Thanks @SS-EN.
2026-10-19 09:14:52 -04:00
fugazister aee47fca00 Messages window: keep status messages to read and copy again (#2763) (#2764)
Status messages are kept for the session in a Messages window (Help menu, or click the status chip), newest first, with Copy all.
2026-10-19 09:09:35 -04:00
github-actions[bot] f1a5f4ab30 Regenerate THIRD-PARTY-LICENSES.txt and docs/features.md [skip ci] 2026-10-19 11:38:55 +00:00
amolinari-autotex aaa35a94d8 Relink a linked assembly source from the Browser (#2772) (#2773)
Thanks @amolinari-autotex.
2026-10-19 07:14:33 -04:00
NOWN-DEV 768e69c4c7 Joints: a new joint between faces that already meet leaves the part as it is (#2709) (#2710)
Thanks @NOWN-DEV.
2026-10-19 05:54:21 -04:00
NOWN-DEV c66e33284b Joints: offsets, angles and values typed as expressions follow their parameters (#2385) (#2386)
Thanks @NOWN-DEV.
2026-10-18 22:13:13 -04:00
github-actions[bot] 38f6ed76c9 Regenerate THIRD-PARTY-LICENSES.txt and docs/features.md [skip ci] 2026-10-19 01:41:22 +00:00
A.Hakim Noor 66108a6b99 Add Malay language support and update localization doc (#2188)
Thanks @a-hakim.
2026-10-18 21:34:54 -04:00
CypherNaugh_0x 8e762fee57 Add optional ambient occlusion and graphics quality presets (#1135)
Thanks @CypherNaught-0x.
2026-10-18 21:29:03 -04:00
leValdemar19 86b2b97d6f Sketch Offset: constrain to the ends of an offset spline (#2424) (#2615)
* claim: #2424

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SBN24y2TcqRcm2zn8Gkj27

* Sketch Offset: constrain to the ends of an offset spline (#2424)

An associated offset spline hid all of its generated fit nodes, its two
end points included, so nothing snapped to them, and a curve drawn from
one shared the node and was refused ("invalid offset output point roles").

- An open offset's end points are shown and snapped to again; its
  interior fit nodes stay private.
- After every sketch edit, a curve that took an offset node gets its own
  point there, coincident with the node: the offset keeps sole ownership
  and the curve follows the offset when its source moves.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SBN24y2TcqRcm2zn8Gkj27

* Scenario: lines snap to and close onto an offset spline's ends (#2424)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SBN24y2TcqRcm2zn8Gkj27

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 21:16:43 -04:00
bherbruck 46bc44b706 Merge pull request #2821 from tangency-labs/ci-faster-shards
CI: faster test shards
2026-10-18 21:16:14 -04:00
bherbruck 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>
2026-10-18 21:16:11 -04:00
bherbruck 2452513b65 CI: faster test shards
- Pull requests that can change a robustness golden check every seed but the 17 slowest, in the
  same nextest run as the other tests instead of a second step after it (16-30 minutes on its own).
  The slow seeds (about four fifths of the goldens' time) still run in the merge queue, on main and
  nightly. A failed golden still prints how to re-record it, and junit.xml now holds the whole run.
- The slowest tests start first (nextest priority), so a shard no longer ends with one of them
  running alone.
- tspline::tests::hostile_tsplines_never_panic joins the heavy tests pull requests skip (up to
  12 minutes on a GitHub runner; the same kind of check as hostile_params_never_panic).
- The ci profile builds dependencies without line tables: the test archive pull requests' shards
  download goes from 3.4 GB to 2.2 GB.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 00:36:14 +00:00
Tyler Chiriboga 4a4eb59788 3MF import: read objects in other model parts (production extension) (#2089) (#2127)
* claim: #2089

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* 3MF import: read objects in other model parts (production extension) (#2089)

Slicers save multi-part projects with the 3MF Production extension: the
root model's objects are components with `p:path` naming another model
part of the package, which holds the meshes. The reader skipped those
components and build items, so such files did not open at all.

Components and build items now keep the part they name, and the parts
objects name are read once each (looked up through an index of the zip
entries), with the number of part names and their total size capped.
Each part's unit is applied as it is read, so parts in different units
fit together. Cycle detection keys on (part, object), so parts that
place each other in a loop are refused.

Tests: components and build items in another part, part names in any
case, a part in centimetres under a root in millimetres, and hostile
packages (missing part, a path out of the package, an empty path, an
unknown object, a part that is no model, a loop between parts, more
part names than a package can hold). The 3MF mutation fuzz also runs
on a production-extension package.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* 3MF import: count every placement toward the budget (#2089)

An object that only places other objects added nothing to the triangle
budget, so a few objects each placing hundreds of components multiplied
at every level up to the depth cap (300 components, 3 levels: about 1 s;
deeper never finished). That was already true for one model part and now
reaches across parts. Every placement now costs at least one unit, so
such a file stops at the budget.

Test: six levels of 300 components over an empty object (300^6
placements) stop with a budget error in well under a second; without
the change the test does not finish.

Suggested in review by @jyviko.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Tyler Chiriboga <18270301+Tyler-Chiriboga@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: bherbruck <brennen.herbruck@gmail.com>
2026-10-18 18:10:56 -04:00
Jackson Oursland 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>
2026-10-18 18:10:36 -04:00
NOWN-DEV 6d410c342c Joints: origins on an edge of a face, at its middle or a corner (#2403) (#2404)
* Joints: a face or circle origin keeps its turn as the face tilts

A face- or circle-centre joint origin worked out its frame's x from the normal alone
(`Vec3::any_perp`), which switches axis where the normal crosses 0.9 along X: a part on a face
tilted past about 64° by a parameter spun a right angle about the face. New origins keep the x
they have when picked (`x`, component coordinates) and each solve lays it onto the face as it is
now, so the part tilts with the face without spinning. Origins saved without it are placed as
before.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Joints: origins on an edge of a face, at its middle or a corner

`joint.origin` and `joint.create` take `edge: [x,y,z]` (a point on an edge of a planar face),
with `on` (which face; default the larger planar face beside it) and `corner` (the end near that
point). The origin sits at the edge's middle (z out of the face, y into it) or at the corner (x
and y along its two edges into the face, right-handed whichever way the edges run). The edge, the
face and the corner's other edge are kept by name and found again on every solve, so a part set
40 mm in from a panel's corner stays there when the panel changes size; a name that finds nothing
leaves the joint out with the reason.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: bherbruck <brennen.herbruck@gmail.com>
2026-10-18 18:10:28 -04:00
Rec0iL deb28dd721 Agent chat: attached pictures use the shared viewer, in any format, decoded in the background (#2554)
Thanks @Rec0iL.
2026-10-18 13:07:55 -04:00
N3MI-DG 3eeb20d2bd Browser: hidden items grey out, and folders keep their own visibility (#2308)
Thanks @N3MI-DG.
2026-10-18 11:34:55 -04:00
Rec0iL f498d23a79 Agent chat: keep Send in view for a long message, open "View attached" (#2224) (#2225)
Thanks @Rec0iL.
2026-10-18 10:53:31 -04:00
Cyryl Sochacki 8025966a35 i18n: add Polish (pl) UI translation (#2032)
Thanks @cyryllo.
2026-10-18 10:24:13 -04:00
fugazister 535a43ab3c Custom colour themes: theme files, Gruvbox built in (#2255) (#2405)
Thanks @fugazister.
2026-10-18 10:01:39 -04:00
CamWight b7a6c68702 Docs: a glossary of SolidCraft's terms (#1569) (#2484)
Thanks @CamWight.
2026-10-18 09:19:22 -04:00
franco michetti a4edea9ad2 Agent chat: attach files and pictures to a message (#1744)
Thanks @onembyte.
2026-10-18 08:18:29 -04:00
Brazz 07708a4e2a Extrude: a taper composes with a start offset (#2312) (#2313)
Thanks @acbrazzl.
2026-10-18 06:18:43 -04:00
franco michetti 5eb7640b54 Agent chat: pop out into its own window, dock back (#1745)
Thanks @onembyte.
2026-10-18 05:59:30 -04:00
Lasse Lian b685b7301f Preferences: reverse horizontal pan direction (#2007) (#2047)
Thanks @lasselian.
2026-10-18 03:12:23 -04:00
cronos a8e8d82f90 Add regression coverage for mouse picking during 3D mouse navigation (#1786)
Thanks @crono2250.
2026-10-18 01:33:09 -04:00
selune 7c9f8a5895 Drawing: validate section geometry contracts (#2053) (#2085)
Thanks @0xlillith.
2026-10-18 00:29:12 -04:00
amolinari-autotex 48986041ed Add complete Italian UI localization (#1941)
* Add complete Italian UI localization

Translate all 1509 English catalog entries originally, register Italiano, guard complete coverage and exercise Italian labels and UI rendering.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* i18n: Italian is a partial catalog

it.json lacks 19 messages main has gained since this branch began, so as a
complete catalog it would fail every_complete_catalog_carries_every_english_message.
Like the other community languages, Italian is now partial: its gaps fall
back to English and new labels don't require an Italian string. The docs
line goes back to main's wording, with Italian among the partial catalogs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LGeCa5jWWdroMWvXxN3LLM

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Ben Herbruck <bherbruck@herbrucks.com>
Co-authored-by: bherbruck <brennen.herbruck@gmail.com>
Co-authored-by: jyviko <2501648+jyviko@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 22:28:04 -04:00
Irakli Kourtis 83c31d77c4 surface.boundary: surfaces through boundary curves and curve networks (#763) (#2129)
* feat(geom): surfaces through curve networks, and spline spaces to build them

Adds spline_space (clamped B-spline spaces, Hermite interpolation, exact
embedding by Bézier degree elevation and knot insertion, a monotone cubic
for reparameterising) and network (loft, Coons and Gordon surfaces through
curves in one or two directions, with G1/G2 cross-boundary conditions
against a neighbouring face). Part of #763.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(kernel): boundary surfaces from sketch curves, 3D curves and edges

kernel::boundary_network turns sketch chains, 3D sketch polylines and edge chains
into network curves, gives G1 frames of the faces along open edges
(EdgeFaces), builds the B-spline face (sides split at chain vertices so a
join shares the body's edges) and joins it into a surface body by stitching.
G2 is refused for now (not supported yet). Part of #763.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(kernel): second derivatives of B-spline surfaces in the vendored truck-geometry

BSplineSurface::uuder and vvder multiplied the second differences by p
instead of p·(p − 1), as BSplineCurve::der2 does, so every surface of
degree p ≥ 3 (NURBS too, through its homogeneous surface) reported
1/(p − 1) of its second derivative: a cubic surface's curvature read as
half. This is why a G2 boundary surface on a cylinder measured half the
curvature it carries (#763). New tests hold both to finite differences
for degrees 2 to 5.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LGeCa5jWWdroMWvXxN3LLM

* feat(kernel): G2 boundary surfaces against a body's face

The network always carried the face's curvature across a G2 edge; the
refusal came from measuring it with truck's halved surface second
derivatives (fixed in the previous commit). EdgeFaces now reads the
face's second fundamental form from the exact second derivatives
instead of differencing the normal. A new test holds the curvature
across a cylinder's edge to the cylinder's within 0.1%, also with a
sheared far curve; G3 is refused (a network holds up to G2).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LGeCa5jWWdroMWvXxN3LLM

* test(kernel): a boundary patch with straight corners measures its own area

A stadium's arcs meet its lines at 180°, so the Coons patch is singular
at its corners. From such a corner the reference mesher's boundary walk
ran onto the B-spline's extrapolation past its domain (a planar spline
passes through every point of its plane there), and the face measured
289 mm² for its 158.5 (#763). The vendored mesher's bounded projection
(nearest_projection, #2043) keeps the walk on the domain; this holds it
there, by the faces, the measuring mesh and the display mesh. The
display path (#1653) was never affected.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LGeCa5jWWdroMWvXxN3LLM

* feat(geom,kernel): three-sided boundary surfaces (one side collapsed to a point)

A network curve may be a PointCurve: the apex where the two sides beside
it meet. The curves through it cross it at the point itself, its row of
the net collapses there, and the kernel's face leaves that side out of
its loop (three edges, one vertex at the apex). One point per patch, as
a side; refused elsewhere, when it moves, or with a continuity
condition. Tests: a triangle and a quarter disc filled flat with their
analytic areas (40 mm², 25π), by geom and by the kernel's faces and
meshes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LGeCa5jWWdroMWvXxN3LLM

* feat(doc): boundary surfaces through curve networks and loops of three or four

FeatureKind::SurfaceNetwork saves a network as `u` and `v` curves, each
a sketch chain (planar or 3D), a chain of a body's edges with an
optional G1/G2 continuity, or a point (the apex of a three-sided
patch), and an `operation` that can join the surface into the body of
its edges. A SurfaceBoundary of three or four sketch curves, refused
until now, builds as the flat Coons patch of its loop (three collapse
the side opposite the first curve). The format change is one pending
file; feature-walk goldens record the new variant's sketches, bodies
and points.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LGeCa5jWWdroMWvXxN3LLM

* feat(engine): surface.boundary through loops of three or four and curve networks

The command keeps its loop form (two to four curves of one sketch; three
and four now build the flat patch of the loop, crown refused there) and
gains a network form: `u` and `v`, each curve a sketch curve id, a
{sketch?, curves} chain (planar or 3D), a {body, edges, continuity?}
edge chain (g1/g2 with the face beside it) or a {point} for a
three-sided patch, with `operation` new or join. Edits may move between
the two forms (timeline.redefine accepts the command now that it has a
dialog).

Tests: analytic areas of loop patches and of a hyperbolic paraboloid
bounded by four 3D lines (every mesh vertex on z = xy/10), a loft
across two sketches, G1 and G2 measured across a cylinder's edge with
inspect.continuity (angle < 0.1°; curvature jump 1e-16 with G2 against
0.027 with G1), 26 hostile networks refused without panicking, and u/v
added to hostile_params_never_panic.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LGeCa5jWWdroMWvXxN3LLM

* feat(ui): Boundary Surface dialog

Curves and Cross curves take sketch curves and edges (picks that meet
end to end in one sketch or body are one chain); Continuity and
Operation (New Body or Join). Two to four sketch curves of one sketch
with nothing across are the loop patch; anything else is a network.
Edit Feature brings either back (per-side orders, crown and stations
the dialog does not show are kept). Strings in en, ja and zh.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LGeCa5jWWdroMWvXxN3LLM

* docs: ROADMAP M8 and the bridge patch's notes for boundary networks (#763)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LGeCa5jWWdroMWvXxN3LLM

* test(oracle): a boundary surface through a loop, thickened (#763)

Case 83: four sketch curves (a square's three sides and a half circle
for its top) make one boundary surface, thickened 2 mm; analytic values
from tools/oracle-analytic/cases_surfaces.py (V = 2A, area 2A + 2P,
centroid by moments). Recipes gain boundary_surface, thicken and remove.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LGeCa5jWWdroMWvXxN3LLM

* refactor: boundary surfaces, review cleanups

Project onto the face once per derivative evaluation (the frame is
passed to natural() and reused by scale()), keep each track's
finite-difference step instead of rescanning its table, export the
kernel's edge-pick and chain caps and the default station count for
the engine, doc and dialog to share, map TooLarge spline errors to
KernelError::TooLarge, reuse the engine's operation parser, and skip
the dialog's sketch lookup when the picks are no loop.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LGeCa5jWWdroMWvXxN3LLM

---------

Co-authored-by: jyviko <2501648+jyviko@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: bherbruck <brennen.herbruck@gmail.com>
2026-10-17 21:47:38 -04:00
github-actions[bot] dc8edead22 Regenerate THIRD-PARTY-LICENSES.txt and docs/features.md [skip ci] 2026-10-17 23:22:01 +00:00
Koschtetnix 487aa64e10 Multi profile extrusion performance (#2064)
Thanks @Koschtetnix.
2026-10-17 18:30:52 -04:00
Karl Von Richter 11a196e6f8 sketch(feat): add dimension references and parameter tools (#1548)
Show each dimension's parameter name while creating or editing it, and let
users insert another driving dimension at the expression cursor or selection.
Use the available editor width and keep Apply aligned with the right edge.

Add a tools dropdown with Measure, named user parameter expressions, and
access to the existing parameter table for adding and editing parameters.
Preserve the unfinished dimension expression while either window is open.

Cover reference insertion, dependent updates, parameter selection, dialog
round trips, applying and cancellation with UI integration tests. Update the
parameter guide.

Signed-off-by: Karl Von Richter<karl@embeint.com>
2026-10-18 00:00:35 +02:00
DuBearte 7a3221d2dd Updates: 0.11–0.14 must install 0.15 by hand once (#2136) (#2141)
Thanks @DuBearte.
2026-10-17 17:28:04 -04:00
rpromas 6597ffe072 Self-host the web app with Docker; publish the image to ghcr.io (#2033)
Thanks @rpromas.
2026-10-17 13:49:07 -04:00
Nathan Dane 8a31738fe5 docs: ribbon redesign proposal (#1439)
* docs: ribbon UX redesign proposal (mockups and notes)

Seven mockup images and a short description of the proposed ribbon shell, with floating and
compact layout options. Pictures only; no app changes. The sketch variant with tab locks is
left out.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* docs: update the UX mockups to the current command set

Adds the Sketch Pattern panel, Perforate, new joints and motion commands, Fair and Match Surface,
and the Render workspace; the workspace switcher now matches the app (Design and Render available,
Animation, Simulation, Manufacture and Drawing later). Command map covers all 389 commands.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* docs: draw the UX mockups with the reviewed icon SVGs and accents

Ribbon, browser, history and navigation icons now come from the icon system in #853, with the
Sketch tab in the Sketch green and constraints in red.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* docs: address review on the UX proposal README

Describe the current toolbar in our own terms, and list only Design and Render as the workspaces in
scope.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-17 11:36:43 -04:00
CamWight b6f9b1deac Pages links point at docs.solidcraft.io: Flatpak repository, help and troubleshooting (#1922)
Thanks @CamWight.
2026-10-17 07:26:28 -04:00
DuBearte b04e0801d6 Per-command timings for script runs and batches (#1868)
Thanks @DuBearte.
2026-10-17 07:26:20 -04:00
github-actions[bot] b64edf15d3 Regenerate THIRD-PARTY-LICENSES.txt and docs/features.md [skip ci] 2026-10-17 11:12:34 +00:00