Commit Graph
383 Commits
Author SHA1 Message Date
Irakli Kourtis 2a4907884b Ruled Surface: strips off an edge chain, exact where possible (#762) (#1151)
Ruled Surface: strips off an edge chain in normal, tangent, angle or direction mode, exact planes/cylinders/cones where possible, mitred or round corners, stitched into one surface body. SurfaceRuled is noted under format 21. Closes #762.
2026-10-14 21:44:56 -04:00
bherbruckandClaude Opus 5.5 ed22d663e4 Smart Extrude: direction from the picked side, and a Cut stays a Cut (#1257) (#1261)
* Smart Extrude: direction from the picked side, Cut into a body stays a Cut (#1257)

- A sketch profile (or a thin extrude's curve) extrudes toward the side it was
  picked from: from the bottom view it goes down. Body faces still go outward.
- The automatic operation is latched per side of the profile: a drag that starts
  into a body is a Cut and stays one past the far side; a Join does not become a
  Cut when it reaches another body. Passing through zero decides afresh for the
  new side.
- An explicit operation, Direction or Reverse ends the automatic choices.
- auto_operation also looks just past the profile, so a long cut through a body
  reads as a Cut from the start (the engine's operation: "auto" too).

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* Scenario s07: the XZ profile seen from behind now extrudes toward the camera

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-14 21:31:10 -04:00
Irakli Kourtis 16c49c3e86 Untrim: holes removed and a face restored to its natural bounds (#1150)
Adds surface.untrim (#761); the SurfaceUntrim feature is first saved in format 21.
2026-10-14 20:29:25 -04:00
NOWN-DEV 5c6f70cc00 Faces by name in the face commands; model.faces gives a point on each face (#1243) 2026-10-14 20:18:13 -04:00
selune a261aaa841 Render: integrated workspace, preview image jobs and opaque PBR (#1046)
Lands the Render workspace (R3), bounded preview-image jobs with cancellation and atomic PNG export (R4a), and opaque PBR looks as one change.

- Render workspace: an overlay-free product preview on the installed GPU device. Returning to Design restores its camera. render.scene and render.settings.apply are added.
- Image jobs: render.preflight/start/status/cancel/export run bounded CPU preview jobs. Export captures the job, overwrite choice and document, and checks the caller's file scope before writing.
- Opaque PBR: looks can carry metal fraction, roughness and dielectric IOR. The product viewport and preview PNG use them; geometry and mass are unchanged. The v1 catalog export refuses PBR rather than dropping it.
- Render setups and PBR looks are saved under design format 21. Labels are in en/de/ja/ko/zh/ru.

Supersedes #706 and #800. Refs #620, #673, #756, #1004.

Contributed by @0xlillith.

Co-authored-by: lillith <[email protected]>
2026-10-14 19:24:36 -04:00
Mateusz Sych 099d7e298a Degrees of freedom count closed loops (#1206)
Degrees of freedom count closed loops.
2026-10-14 18:46:46 -04:00
Lasse Lian a4a8b48567 Design properties: project, author and licence in the design, its exports and inspect_design (#1015) (#1189)
A design carries metadata (format 21): project, part number, revision, author, organization, description and license, plus other tools' data under reverse-DNS keys, kept as written. Edited in the Design Properties window (Document Settings), set by document.metadata.set, reported by inspect_design, and written into STEP, IGES and 3MF where the format has a place for them. Translated, with tests.
2026-10-14 18:25:35 -04:00
Erikas 5744b1f327 Test: a pattern of touching cuts builds without fallback (#400) (#1144)
Test: a pattern of touching cuts builds without fallback (#400).
2026-10-14 17:56:17 -04:00
HiroKenEz 1a67390a53 body.rename: renaming a counted body keeps later counted names (#1109) (#1199)
body.rename: renaming a counted body keeps later counted names (#1109).
2026-10-14 17:56:12 -04:00
HiroKenEz 1337404c06 Sketch fillet and chamfer: a construction line at the corner is not a side (#1026) (#1176)
Sketch fillet and chamfer: a construction line at the corner is not a side (#1026).
2026-10-14 17:56:07 -04:00
phanoob beb3ea01e7 Taper: the review of #1014 (spline sides follow their offset, no silent limits, face names kept) (#1204)
Taper: the review of #1014 (spline sides follow their offset, no silent limits, face names kept).
2026-10-14 17:55:58 -04:00
Mateusz Sych c715986a2a Motion links carry a value through a chain stored in any order (#1203)
Motion links carry a value through a chain stored in any order.
2026-10-14 17:55:54 -04:00
CamWight b6e87f0c44 Two tests pass on a Windows checkout: a CRLF parse and an 8.3 TEMP path (#1186) (#1211)
Make two tests pass on a Windows checkout: a CRLF parse and an 8.3 TEMP path.
2026-10-14 17:36:07 -04:00
selune 289b521a65 Render R2: persist named render setups without re-evaluating geometry (#667)
render.settings.set saves validated named render setups (camera, output size, exposure, environment) as one undo step, and render.settings.get reads them back without applying a camera. When validated render settings are the only change, the engine keeps the evaluated model instead of rebuilding it. Setups are saved under design format 21; format-20 designs read as having none. Fixes #658; refs #620.

Contributed by @0xlillith.

Co-authored-by: lillith <[email protected]>
2026-10-14 17:11:39 -04:00
bherbruck 229de1484c Hide and show joints in the browser, like other items (#1168)
Fixes #1160.
2026-10-14 15:04:57 -04:00
HiroKenEz fd12325d90 body.rename: follow the body in later features' participants (a primitive's targets) (#1108) (#1159)
A primitive's `targets` live in the feature's participants beside its kind; renaming a body now renames them too, so a box or cylinder cutting the renamed body no longer fails with unknown body.
2026-10-14 14:43:15 -04:00
NOWN-DEV 764fcaa5a8 Sheet metal: the flat-pattern DXF writes ellipses and splines exactly (#1096)
sheet.export_dxf writes an AutoCAD 2000 drawing with ELLIPSE and SPLINE entities for ellipses, splines and text outlines instead of chords, with curves: arcs for machines that read only lines and arcs. Perforation circles go through the same writer. Closes #1089.
2026-10-14 14:09:46 -04:00
Karl Von Richter 9a4e8fbd19 Sketch: associative, editable sketch patterns (#1103)
Rectangular and circular sketch patterns stay linked to their source: editing the pattern's count, spacing or the source geometry updates the copies, and the copies keep their point and radius relations. Patterns are saved under format 20; older designs keep their independent copies.
2026-10-14 14:09:37 -04:00
NOWN-DEV c3aae64a63 Sheet metal: a cut-out with a corner a hair beside a bend line refolds (#1095)
Edges shorter than the model tolerance are dropped from the flat cells, and the refold sews touching corners, so a cut-out across a bend line no longer fails with a degenerate edge.
2026-10-14 13:59:07 -04:00
Mateusz Sych c469adf456 MCP: an agent's folders hold for file loads through the app and for a design's font files (#1112)
doc.open and the STEP/mesh imports run on the file loader's worker with the request's path scope, and a font named by file path in a design is checked against the scope before it is read.
2026-10-14 13:58:56 -04:00
Mateusz Sych 94faf9ce1b Close kinematic loops: driven joints move four-bars and sliders (#1141)
Driven joints now solve closed kinematic loops, so a four-bar or slider-crank moves as a whole when one joint is driven.
2026-10-14 13:40:16 -04:00
JIJINBEI 1a456d2d1f One walk over the geometry a feature holds (3/3, #876) (#1028)
Moves the per-feature geometry handling (transforms, face points, profile selections, point expressions) into one geometry walk in feature_geometry.rs, with a golden record of what each feature kind moves. sheet.perforate holds no world geometry and joins the no-op arm.
2026-10-14 13:29:31 -04:00
NOWN-DEV f79dfe41b6 Paste New copies an import's bodies under the names its features use when the names are numbered (#1117)
Where an Import's stored labels pair one for one with its numbered built bodies (X, X (2), X (3)), component.paste_new stores the copy under the bodies' names, so the copied features after it find their bodies. No format change.
2026-10-14 13:24:27 -04:00
phanoob 6ebfcd16b6 A text's path becomes construction (#1119)
sketch.text and sketch.edit_text make the curve a text follows construction in the same undo step, so it no longer cuts the letters into pieces; the reply names the curve as guide.
2026-10-14 13:24:23 -04:00
JIJINBEI c26da73f5f A pasted cylinder Emboss keeps its face and badges the pasted cylinder (#1132)
timeline.paste keeps a cylinder Emboss's persistent face name, remapped onto the pasted features and bodies, so the copy embosses the pasted cylinder instead of failing (#1035).
2026-10-14 13:24:01 -04:00
Jonas Wrede 54a8c807bf Sheet metal: sheet.perforate, a perforation field exported to the flat pattern and DXF (#732) (#1041)
Adds sheet.perforate: round holes on a staggered or square grid over the flat sheet, kept clear of edges, cut-outs and bend zones. The holes go to the flat pattern, the DXF and the measured volume rather than the B-rep, so a panel can carry many thousands of them.
2026-10-14 12:43:31 -04:00
selune d399effbf7 Local appearance and material libraries (#863)
Adds local scalar appearance and material libraries: a catalog in the io crate with safe writes, engine commands to list and apply library entries, and a library dialog in the UI, with docs.
2026-10-14 12:21:35 -04:00
Lasse Lian 6df69e9def Thin Extrude: walls of a set thickness along sketch curves (#721) (#991)
Thin Extrude builds walls of a set thickness along sketch curves, open chains and closed loops, with the wall centred, inside, outside or on both sides at two thicknesses. Saved under format 20 (thin on an Extrude); an extrude without thin saves as before. Closes #721.
2026-10-14 11:46:16 -04:00
JIJINBEI 86ea018d05 One walk over a feature's references (2/3, #876) (#988)
Part 2 of #876: one walk over the references a feature holds (the sketches it's built from, the features it names, the bodies it works on) replaces three hand-written matches, with a golden record covering every variant.
2026-10-14 11:14:25 -04:00
NOWN-DEV dde6d48dd0 fix: renaming a body keeps the names of its duplicates (#1056)
Bodies imported with the same label come in as X, X (2), X (3). Renaming one of them no longer renumbers the others: body.rename now pins the current names of the feature's other bodies when it stores the new one, so later renames, materials, appearances and features still find them.
2026-10-14 09:51:12 -04:00
phanoob 4dbc0efff9 Taper any profile, sketch text included (#1014)
A tapered extrude now offsets spline and conic curves as well as lines and arcs, so sketch text and any other profile can take a taper, and the join of tapered letters onto a face finds its boolean result.
2026-10-14 09:47:44 -04:00
NOWN-DEV 37113c0c13 fix: sketch.text refuses inputs it doesn't understand (#1057)
sketch.text and sketch.edit_text took at, height, angle and text with a silent default when a value had the wrong kind, so a height of "H" made 5 mm text and at: ["H", 25] put it at the origin. An input that is given (not null) now has to be what it names, or the command is refused with the input's name, and a null at no longer passes as the origin.
2026-10-14 09:24:30 -04:00
NOWN-DEV 435ad0fd8c fix: a planar union leaves no sliver where an edge crosses its neighbour by their shared corner (#1058)
A planar union no longer leaves a sliver where an edge crosses its neighbour, so a sheet whose outline runs on past a flange's edge with a slight bend unfolds again.
2026-10-14 09:14:41 -04:00
Lasse LianandSychPL 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 <[email protected]>
2026-10-14 09:06:24 -04:00
NOWN-DEV 08b6a8fe0f fix: the server's own folders under a short-named temp path are expanded, not refused (#1055)
On Windows the temporary folder often has an 8.3 short name, which the path scope refuses. vfs::long_names spells folders SolidCraft derives from the environment with long names, and the MCP scratch folder and the recovery folder use it, so screenshot without a path and the recovery commands work there again.
2026-10-14 09:05:43 -04:00
NOWN-DEV cf93869c4d fix: pasted features act on the copies of an import's bodies when their names are numbered (#1059)
Pasting an Import together with later features that name its bodies now points those features at the pasted copies, including bodies whose names carry a number such as X (2).
2026-10-14 09:03:09 -04:00
seluneandbherbruck 52fb5ac0e6 feat: query directional elastic modulus from validated material cards (#998)
* feat: validate physical material cards with sources and conditions

* feat: query directional elastic modulus from physical material cards

* fix: register physical material validation labels in complete locales

* fix: register directional elasticity labels in complete locales

* Add German and Korean labels for the material property commands

---------

Co-authored-by: bherbruck <[email protected]>
2026-10-14 08:17:00 -04:00
NOWN-DEV 0f4cda0510 Convert to Sheet Metal takes a long thin plate (#1040)
Convert to Sheet Metal without bend edges refused every plate whose bounding-box diagonal reached a thousand times its thickness ("no outline on that face"), and just under that limit a hole smaller than the mesh's sag fell out of the outline and the DXF. The outline's tolerance is now at most a tenth of the thickness: a thin plate is meshed again at that tolerance. Nothing new is stored. Tests: long thin strips, sheets thousands of times longer than thick, and a strip keeping holes down to 1 mm.
2026-10-14 08:12:41 -04:00
32d3cf6877 Fillets and chamfers meeting at corners on curved faces: what #935 leaves (#854)
* Fillets and chamfers meeting at corners on curved faces, on top of #935

What #935 and #926 leave of #851 and the matrix:

- Corner build for blends meeting on faces of any surface (curvecorner.rs):
  the knife-edge tip's round with the arc's or the back edge's, edges
  picked in any order, a round ending in an earlier round of its radius
  (as a feature of its own), and chamfers meeting at the arc's corner.
  Its end curves are fitted by chord length: a uniform parameter
  through points clustered at the ends doubled back on itself there,
  and the display planner refused the face.
- A straight edge ending at a curved face (the back edge into the
  knife-edge tip): rolled, or cut by the face in the planar corner
  build (blend_corner.rs).
- A rolling ball turning about a rounded corner of its own radius
  (a pivot: a piece of sphere or cone).
- Seams that are an earlier blend's straight contact (fitted curves)
  count as straight.
- No spline across a joint where the strip's curvature jumps (a line
  into a small round): each strip ends on the joint's section.
- Sections at a chain's vertices on the faces of the edge from it
  alone.
- Every new fillet path passes #949's check for openings.

Tests measure volumes through the display plan, as #935's do.
Action matrix: 51 more fillets and chamfers pass (sweep, tangent arc
chain, sheet-metal hem, bracket holes), none fewer. Robustness seed 33
recorded (its last fillet builds differently; display and measured
volumes now agree).

Co-Authored-By: bherbruck <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015bV2ntwLfUHV4JnCMPSyRi

* Corner blend tests: scale, seed 33's volumes, tighter engine bounds

From the review of #854:

- seed_33_display_plan_and_measure_agree: seed 33's bodies measure
  the same through the display plan and the measure (2e-5), which the
  golden's re-record rests on.
- the_arc_rounded_after_the_back_edge_matches_both_together: the order
  that still leaves 0.05 mm³ at the tip, as an ignored test.
- corner_blends_hold_at_any_scale: the cases this branch adds on the
  #851 part, at 0.01x and 100x, take off what they take at full size
  times k³ (within 5e-6, checked to 1e-4).
- The engine tests on the part as drawn measure through the display
  plan; bounds are about twice what each reads (2e-4 to 3e-3), and the
  front corner's sets are checked against the kernel's CSG grid.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015bV2ntwLfUHV4JnCMPSyRi

---------

Co-authored-by: bherbruck <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-14 07:40:23 -04:00
selune 01f2c78cd1 Validate sourced physical material property cards and elastic stability (#934)
Adds the read-only material.properties.validate command: schema_version 1 engineering material cards in SI units are checked for numerical consistency and elastic stability, with derived isotropic moduli, missing conditions and sources needing review. Nothing is assigned or saved.

Thanks @0xlillith.
2026-10-14 05:28:18 -04:00
Karl Von Richter 9ca7d307a4 Offset of an irregular closed spline no longer fails its error certificate; offset fit nodes stay private (#1009)
Fixes #971. At the node limit the offset certificate splits the fitted curve where it meets the exact offset midpoint, so curves with different parameter speeds certify within the same 0.002 mm tolerance. Associated offset fit nodes are hidden from display, picking, box selection and snapping until Break Association.

Thanks @Karl-VonRichter.
2026-10-14 05:27:39 -04:00
bherbruck 2f91338d3d Large STEP imports: no more multi-minute hang, shared STEP text, cancel and progress (#925) 2026-10-14 05:01:12 -04:00
Mateusz SychandSychPL cf9d7772f1 To / From Object finds a target in another, moved component (#993)
Fixes #928. Extrude To / From Object and Revolve To Object now resolve their target in the feature's own component frame, so a face in another component whose occurrence is moved is found where it is shown instead of the extrude stopping at a flat plane through the picked point. The point is named after the nearest face, a named point keeps its named face when another component touches it there, and such features re-evaluate when a placement changes, so they follow the target when it moves later.

Co-authored-by: SychPL <[email protected]>
2026-10-14 04:41:59 -04:00
midasdfandmidasdf 6e84c03946 Curvature-continuous (G2) fillets for straight planar edges (#862)
Fillet gets a Curvature (G2) radius type (type: "curvature", alias "g2"): a quintic blend whose size is the equivalent circular setback, for convex and concave straight edges between planar faces with a perpendicular planar end face at each end. Unsupported cases are refused rather than falling back to a circular fillet, and a blend that would cross a loop in its end face is refused. Persisted as a fillet style under format 19; labels in en/de/ja/ko/zh.

Co-authored-by: midasdf <[email protected]>
2026-10-14 04:26:53 -04:00
NOWN-DEV 6a67cc8f1e An edge flange folds beside a ledge as tall as its setback (#978)
Trimming the base at an edge flange's setback snaps corners within tolerance onto the trim line and merges away the zero-width run a ledge as tall as the setback left along it, so the ledge goes with the strip as a lower one does. Splitting outline edges at other cells' corners now skips points within the model's tolerance of an end, so a ledge a little taller keeps its sliver and the bend runs under it, also off the axes. Both used to fail with "sew: a degenerate edge". Nothing new is stored.
2026-10-14 02:51:29 -04:00
bherbruckandClaude Opus 5.5 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 <[email protected]>
2026-10-14 02:31:19 -04:00
bherbruckandClaude Opus 5.5 b34d45233d Holes on round faces from the app, and Flip for holes at sketch points (#980)
* Holes on round faces from the app, one hole per pick, and Flip for holes at sketch points (#967)

The Hole dialog takes any face: a hole on a round face drills against the face's normal where it
was picked, and its arrow shows that. A round face split at its seam is picked whole, but makes
one hole where it was clicked. Holes at sketch points get Flip (saved as flip in the hole's points,
under format 18), in the command and in the dialog.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* Holes at sketch points show their arrow: into the part, or away with Flip (#967)

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-14 02:10:09 -04:00
Karl Von Richter 47a7f29485 Guide sketch patterns with live previews and editable offsets (#966)
Sketch Mirror, rectangular and circular Pattern, and Offset now show a green live preview that follows the selection and settings; OK commits, Cancel leaves the sketch unchanged. The shared dialogs show the current selection step and source counts, sources can be toggled with Ctrl/Cmd-click, cleared and reselected.

Offsets keep editable driving distance dimensions (One Side, Two Sides, Symmetric) that update the derived curves without moving the source, with undo/redo and save/reopen. Format 19: older files keep their fixed offsets.

New dialog labels in en, zh, ja, de and ko.

Fixes #696. Fixes #517.
2026-10-14 01:58:01 -04:00
NOWN-DEV 4687e3b073 Convert to Sheet Metal keeps a plate's round holes round (#977)
The plate check compared the face outline's area (from the tessellation, so each hole was a polygon of chords) with the exact volume, and refused plates with a few small holes. Where the outline runs along a cylinder about the plate's normal it is now an arc of that circle; coaxial pieces of one radius are one wall, so a hole split into two, three or four faces is one circle. The check passes with its tolerance unchanged, and the flat pattern and its DXF carry one CIRCLE per hole (ARC for rounded corners and slot ends).

A round blank now converts too, so unfold_cut_refold_and_convert checks the refusal with a block thicker at one end instead of a rod.
2026-10-14 01:47:40 -04:00
bherbruckandClaude Opus 5.5 1ff16cc72b A hole on a face drills into the material, also in older designs (#950) (#952)
* Hole matrix: placement, types, extents, edits and 0.9.0 designs, with today's failures listed

Each case checks the drill goes into the material, the bore sits on its axis, a blind hole stops
where it should, the removed volume against its analytic value, the face count and that every
body is still one closed valid solid. Failing cases are listed in tests/hole_matrix/known_failures.txt
as a ratchet.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* A hole on a face drills into the material, also in older designs (#950)

Without a direction, solid.hole took the direction from any face whose infinite plane passed
within ten tolerances of the point, the last one found winning: the far side of a thin plate or a
face of another body at the same height could set it, and the wrong direction was saved. It now
uses the face nearest the point, against its outward normal (exact for planes, cylinders and
spheres, so holes on curved faces work without a direction). When a design is evaluated, a face
hole whose saved direction leaves the face it starts on is mirrored into it, so designs saved
with the wrong direction drill into the part.

Fixes #950.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* Hole at a point on no face (a planar face's centroid outside it) keeps the plane it lies in

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* Record the hole direction fix in the goldens and the action matrix baseline (#950)

Seeds 7, 21, 81 and 85 drill their holes straight into their faces now. In the action matrix,
holes on four faces that used to go the wrong way now build, and two whose correct direction
meets a cut the kernel refuses are marked failing.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* Goldens: seeds 7, 21 and 85 drill their holes straight in (#950)

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-14 01:45:11 -04:00