Thin extrude caps are certified by the curves the wall follows, so a sketch attached to a cap survives switching between solid and thin (#1519).
Co-Authored-By: Philipp Bischoff <PhilippBischoff0@users.noreply.github.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A sketch text's height, place (x and y) and angle can each be an expression over the design's parameters, and the text follows parameter changes, undo and reopening. Closes#1362.
Co-authored-by: NOWN-DEV <NOWN-DEV@users.noreply.github.com>
The continuity core (kernel bridge: Hermite control rows reproducing a support surface's position, tangent, curvature and change of curvature, G0 to G3), surface.blend between two edge chains (#764), and a crown for fitted patches. Existing patches and fillets are unchanged by default (crown 0 is the plain patch bit for bit). SurfaceBlend and Patch.crown are noted under format 22.
* Imports become components: a STEP assembly's tree as nested components (#1386)
Every imported file (STEP, IGES, 3MF, STL, OBJ: inserted, dropped, opened as a
design, or file.insert_step / file.insert_mesh / doc.open from scripts, the CLI
and MCP) now comes in as a new component named after the file, with its Import
feature inside it. A STEP assembly's products become nested components; a part
placed more than once is one component with an occurrence per placement, and
the Import feature skips the file's later copies (`skip`, format 21 note). The
contents are held as one rigid group (rigid joints, glyphs hidden); moving an
inner part is refused until component.unlock ("Unlock Contents") releases it.
Y up turns the import's component. Replies report component, component_name
and occurrence. Undo is one step; designs with loose imports are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Keep an import's rigid group hidden when the window loads the file in the background
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Import instances' skip list is format 22: format 21 ships in 0.12.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Catalog entries for Unlock Contents
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* View-dependent display refinement: bodies seen up close are drawn from finer display plans (#1320)
Each frame the viewport works out every shown body's screen-space error (the display
quality's chord tolerance in pixels where the body is nearest the eye) and picks a
refinement step past the chosen display quality, each halving the chord, with hysteresis.
Steps are planned off the UI thread and swapped in when ready, within a triangle budget
and a cache size. Faces (GPU plan or CPU mesh), edges, silhouettes and highlights of a
refined body all come from the refined plan, so a highlight stays on the drawn triangles.
Planned bodies are chunked by content on the GPU, so a refinement re-evaluates only its
own chunk. Display only: the reference mesh, the B-rep and exports never change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Display refinement: only collect finished plans while the view stands still, time the choice, keep the web planning one step a frame
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Format
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Keep the Display quality note as it was (the longer one pushed the Colour vision list off the Graphics page)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Part of #771 and #772. solid.sweep and surface.sweep take orientation (perpendicular, parallel or a direction), twist (up to 4 turns) and end scale (0.01 to 100), applied about the profile's normal through the path's start; default options run the old sweep, so existing sweeps are unchanged. New fields are optional, left out when unset and noted under format 21; twist and scale are model parameters. Both sweep dialogs get Orientation, Twist and End Scale rows; labels in every catalog. Checked on main + this branch: cargo check --workspace, kernel/engine/UI sweep tests, the doc suite and the robustness goldens.
* Preferences ▸ Graphics ▸ Display quality: Coarse, Normal, Fine, Ultra (#1287)
A viewing preference that sets how finely the viewport tessellates curved faces and edges:
chord tolerance relative to each body's size (3e-3, 1e-3, 3e-4, 1e-4) and the most a facet may
turn (30, 20, 12, 7 degrees). Normal is the tolerance the viewport has always used.
Bodies keep a display plan per level, so switching is a re-plan the first time and instant
after; the reference mesh the model reads (picks, holes, measuring) and exports are unchanged.
Away from Normal the model scene builds edges, and faces on the CPU path, from the plan at that
level, so silhouettes and edges get finer with the faces and a highlight still lies on the
displayed triangles.
The preference is saved with the others, set over the control channel (`ui.prefs`
`display_quality`), labelled in en/de/ja/ko/zh. `solidcraft-cli bench-open --display LEVEL
[--edit NAME EXPR]` times the plans at a level and after a parameter edit.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Highlighted edges follow the display quality too
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
A symmetric solid extrude of 10 mm is now 10 mm thick, 5 mm each side of the sketch plane, and switching from One Side to Symmetric keeps the thickness entered. Under format 21 the extent records its convention; designs saved without it keep the per-side reading, so their geometry and parameters don't change. Fixes#1236.
Co-authored-by: Karl-VonRichter <Karl-VonRichter@users.noreply.github.com>
A loft section with a hole is refused with a clear message instead of being lofted as if filled, in both section-to-section and section-to-point lofts. Fixes#1184.
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.
A large design showed nothing but a progress bar until it had rebuilt completely. While
it rebuilds, the evaluation now offers the model built so far (placed as the design
places it) every 1.5 s to a window that asks, and the open card draws it as a small
picture on a thread of its own, the way it shows a saved preview. The bodies' meshes
made for it are the ones the finished model shows, so little is done twice. A design
that opens within the first interval shows none.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
A design built over MCP is many small commands, and each one did work over the
whole design, so building or showing a 1,300-body design took minutes:
- moved components were transformed and meshed again after every change; world_state
now reuses each placed body whose definition and placement are unchanged
- next_d_name searched the design once per candidate number
- Document::eval evaluated every parameter for every expression; now only when the
expression names one
- param_rows' used_by was quadratic; the desktop no longer gathers completions on every
change while no text box has focus
solidcraft-cli bench-agent builds a generated ~1,300-body bicycle command by command
and times it (241 s -> 16 s here). Eval output is unchanged apart from timings.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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.
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.
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.
Since the model's mesh went back to the reference mesher (#940), the GPU viewport drew
opaque bodies from their display plans while hover and selection lit faces with the
reference mesh's triangles. Two triangulations of the same face at equal depth fought, so
a hovered face shimmered in wedges instead of lighting whole.
Faces lit over a body drawn from its plan now use the plan's own triangles
(ModelBody::plan_mesh, evaluated once on the CPU), and the highlight pass gets a small
depth bias toward the eye so f32 rounding between the GPU and CPU evaluations of the same
triangles cannot speckle it either.
Test: every face of a box with a pocket and a round boss, hovered and rendered offscreen
through the viewport's real pipelines on the GPU path, lights the same pixels as on the
CPU path (skipped without a GPU adapter).
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* fix: a modelled thread that would cut nothing is refused (#995)
An M5 modelled thread in a 5 mm hole cut nothing into the nut: the
internal groove runs from the minor diameter out to the major one, so
with the hole as wide as the thread it lay entirely in the hole, and the
faceted cut only left the wall faceted with slivers ("the thread goes the
wrong way"). The fit check takes a 5 mm hole as an M5 hole.
- thread_groove measures how deep the groove cuts into the material
(hole wall out to the major radius, or shaft surface in to the root);
under a quarter of the basic depth 5H/8 the modelled thread is refused
with the measured depth, the tap drill (as solid.hole drills it) or
shaft size to use, and the size that fits the face, e.g. "this 5.00 mm
hole is too wide for a modelled M5 thread: it would cut 0.00 mm of the
thread's 0.43 mm depth; drill 4.2 mm for M5, or thread this hole M6".
- Cosmetic threads and their fit check are unchanged.
* test: pin the cut-nothing limit for coarse and fine pitch; show the hole size with show_mm
---------
Co-authored-by: MateuszSychXpl <151755914+MateuszSychXpl@users.noreply.github.com>
Co-authored-by: bherbruck <brennen.herbruck@gmail.com>
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 <SychPL@users.noreply.github.com>
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 <midasdf@users.noreply.github.com>
A hole drilled along a panel, into its rim, has no place in the flat pattern
as a cut-out, so every such hole was refused. It is now kept as a bore of that
panel, in flat coordinates, and cut only from that panel's material when the
folded part and its flat pattern are built, so the sheet still unfolds and
folds back with it. A hole that would run into a bend, or cross a panel at an
angle, is still refused. The flat pattern lists the bores.
The action matrix worker takes ACTION_MATRIX_ONLY (just these actions) and
ACTION_MATRIX_UNFOLD (unfold and refold every sheet after each action) for
rechecking one group by hand.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* 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 <noreply@anthropic.com>
* Holes at sketch points show their arrow: into the part, or away with Flip (#967)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* 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 <noreply@anthropic.com>
* 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 <noreply@anthropic.com>
* 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 <noreply@anthropic.com>
* 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 <noreply@anthropic.com>
* Goldens: seeds 7, 21 and 85 drill their holes straight in (#950)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Offsets picked faces along their normals into a new surface body: planes and cylinders move exactly, other faces get a fitted B-spline within tolerance, and offsets that would fold over are refused. Adds the SurfaceOffset feature (noted under format 18), the surface.offset engine command and an Offset Surface dialog.
Closes#758.
Co-authored-by: jyviko <2501648+jyviko@users.noreply.github.com>