mirror of
https://github.com/bherbruck/solidcraft.git
synced 2026-11-06 20:02:16 +00:00
stack/render-11087
460 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
1b55174743 |
Render: isolate lens saves and retain bounded previews
Save only lens parameters on existing CPU/GPU jobs while keeping unrelated draft settings dirty. Retain pinned checkpoints through preview and status, and release host-only snapshots outside the status lock. Use the admitted PNG bound for registered-executor checkpoint slots. Preserve executor work credits, final publication and regrade ownership. Add regression coverage and align help, translations and capability documentation. |
||
|
|
8829c1c3c5 | Render: restore saved shots, progressive images and exports | ||
|
|
af5644aee6 |
Ribbon: switch panel menus on hover after the first click (#11447) (#11713)
* claim: #11447 * Add an option to switch ribbon panel menus on hover * Update profile membership count for ribbon hover setting |
||
|
|
c4a63a1d43 |
GPU path tracer: don't rerun a setup that crashed in the driver (#9236) (#9666)
* claim: #9236 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * GPU path tracer: don't rerun a setup that crashed in the driver (#9236) A driver that takes the process down while it compiles the path tracer (RADV on an RX 7600) is beyond error scopes and unwind guards. A running setup now keeps gpu-path-setup.json (its adapter key) in the settings folder, removed when the setup answers or the app closes normally. A launch that finds it for the same adapter leaves the setup failed with an explanation and a Try again button; CPU ray tracing stays available, and a driver update changes the key and so tries again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
d9421bf2ca |
Browser: an option to start folders closed and open rows only on request (#8768) (#8771)
* claim: #8768 * feat: Browser folders start closed and find a body only when asked, behind a preference Preferences › Layout › Browser rows start closed (`browser_rows_start_closed`, off by default) starts the Browser's folders closed, and placements too whatever "Components start open" (#9274) says. Rows then open with their arrow, Expand All or Find in Browser, which opens just the rows down to its body and closes again the ones the last find opened. A body picked in the 3D view leaves the Browser as it is, and only the body Find in Browser found has the rows above it marked, so a large assembly's placements are not named again after each edit. With the preference off, folders start open, placements start as "Components start open" says, and a pick in the 3D view opens the Browser down to its body, as on main. Find in Browser looks the body's placement up once and opens its rows before drawing, instead of each row testing the revealed path while it is drawn. * Browser tests: read the row order from the Browser's content frame Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: bherbruck <brennen.herbruck@gmail.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
3aee35fe01 |
Web app: keep unsaved work in the browser instead of the leave-page box (#10220) (#10221)
* claim: #10220 * Web app: keep unsaved work in the browser instead of the leave-page box (#10220) A new preference, off by default, on Preferences > General > Saving (web app only): "Keep unsaved work in this browser instead of asking when the tab closes". With it on, each open design with unsaved changes keeps a copy in the browser's private storage (keep-<page>-<design>.sc/.json), written once the design has been still for 0.8 s (at most 4 s after the first change it lacks) and again on pagehide or when the page is hidden. While every copy is current, beforeunload doesn't ask. A copy goes when its design is saved, closed, or the preference is turned off. The next visit offers the copies newer than their design's last save in SolidCraft's own window, "Restore unsaved design: <name>, changed <time>?", one window for several, with Restore, Open saved version, and Discard. A page holds a Web Lock while it runs, so another open tab's copies are never offered or removed. With the preference off, the single autosave and the browser's prompt work exactly as before. * Web app: the restore window comes from the UI kit's recovery module (#10220) The kit's text and divider helpers are private to the UI crate, so the "Restore unsaved design?" window moves to recovery_ui (browser_copies_window), beside the desktop recovery window, and the web shell only maps its answer. Also keeps the window handle for the page listeners instead of using the one moved into the app. * Web app: restore window buttons sit in one row (#10220) * Web app: keep unsaved work and still ask, unless told not to (#10220) Keeping a copy in the browser no longer replaces the browser's leave-page box by itself. A second option, shown once work is kept and on by default, leaves the box in place; off, the box appears only while a copy isn't current. * Web app: kept-copy review fixes (#10220) A failed write of a kept copy waits 30 s before the next try, a recovery copy is dropped only after the remembered saved file has opened, the preference is documented under its current label, and the ui.prefs list is sorted again. |
||
|
|
5562d9c6c8 |
Quick-access bar: pin ribbon commands to the application bar (#10223) (#10224)
* claim: #10223 * Quick-access bar: pin ribbon commands to the application bar (#10223) A command's menu (a ribbon button, a section drop-down row or a command search result) has Add to Quick Access: the command's own icon joins the application bar after Save, Undo and Redo. A click starts it as its ribbon button does, a drag along the bar reorders the buttons, and the button's menu has Remove from Quick Access. Empty, and so not drawn, by default; it holds up to 24 commands. The list is kept with the toolbar's customisations (`quick_access` in the toolbar's saved document), so it is saved, exported with the keyboard shortcuts and carried by settings profiles. * Quick access: a pinned family variant no longer replaces the ribbon choice A quick-access click now starts the pinned command with start_pinned, so it starts exactly that command and leaves the sketch family remembered choice (the main ribbon button) unchanged. |
||
|
|
0690ee5875 |
Web app: run as a modelling editor inside another page that keeps the design files (#8517) (#11273)
* claim: #8517 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * web: editing embed for host pages (?embed=editor, #8517) A host page that keeps the files itself and frames SolidCraft for modelling needs the modelling UI without the application chrome. `?embed=editor` runs the web app as such an embed: - no application bar (logo, File menu, document tabs, update, help, report a bug) and no start page; the layout is docked; - the ribbon, browser, timeline and properties stay; Ctrl+Z and Ctrl+Y still undo and redo; - Ctrl+N, Ctrl+O, Ctrl+S, Ctrl+W and Ctrl+, are left to the host; - nothing is kept in the browser (no stored designs, autosave, recovery prompt, preferences or leave-page prompt), as with the existing viewer embed. The existing `?embed&open=` viewer embed is unchanged. SolveApp gets one flag, `embed_editor`, for desktop and test hosts too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * control: document.export / document.import / document.saved for a host (#8517) An editing embed's host keeps the design itself. Three control methods (window.solidcraft.request in the browser; the desktop control channel too; not the agent chat's, whose method list is unchanged): - `document.export` -> {name, revision, dirty, format: "json", text}: the active design as a `.json` design file holds it. `revision` is the one `document.revision` answers, so a host that follows the design compares one number. - `document.import {text, name?}`: replaces the active design with that text, timeline and parameters as saved, opened saved with a new `document_id`. It runs as a design opened in a tab of its own, with the old tab closed without asking, so whatever was open in the old design leaves with it. A text that does not read leaves the design as it was. Waits behind a file loading or a design change, as commands do, and evaluates on the window thread. - `document.saved {revision}`: the host saved that revision; refused when the design has changed since. They are control methods, not commands: they act on the app's open design. The browser API test gets a round trip through all three. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: aduijs <7501203+aduijs@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
1432131e95 |
English: command labels in title case, other labels in sentence case (#9085) (#10734)
* English: command labels in title case, other labels in sentence case (#9085) The rest of #9085 after #9194 (the plural and the spelling) and #9907 (the Preferences page names). Command labels are in title case (422 of 430 were already); the seven in sentence case follow, and Fix/UnFix reads Fix/Unfix. The UI text skill states the rule. The user docs name the Preferences footer's button by its current label, Restore page defaults (#10295). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Navigation bar menu test: the echo names the command by its own label Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * UI text skill: state the case rule in one short sentence, under the 3600 limit Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Localization doc: the case rule in full, with examples Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Localization doc: the example button is Restore page defaults now Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
fb80454368 |
User guide: window tour gets a numbered screenshot and a navigation clip (#10323)
* Book: a numbered window screenshot and a navigation clip, from a capture script The window tour now opens with a screenshot of the real window, its parts numbered in the order the page describes them, and a short looping clip of orbit, pan, zoom and Home. examples/demo/doc_shots.py makes both, and any later figure: each shot is a function that starts a fresh app (its own settings) under Xvfb, drives it over the control channel with the demo's Demo driver, and writes a still (numbered callouts, palette-optimised PNG) or an H.264 clip (the drawn pointer of overlay.py, short button labels, idle cut by trim_idle.py) into docs/book/src/media/. CONTRIBUTING.md says how to redo a figure when the UI changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * doc_shots: clips keep a moment on each result; the window tour again on 0.29.0 trim_idle.py takes --hold S, the seconds of each idle stretch to keep (default 0.1, as before, so the README demo is unchanged). The guide's clips keep 0.8 s, so a reader can see what each step did before the next begins. The window screenshot and the navigation clip are made again with it, on SolidCraft 0.29.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
dcbedbd805 |
Don't blindly reopen a design that stopped the last session (#5064) (#10443)
A design that crashes or hangs the app while it is being reopened was reopened blindly every launch, bricking the app each time. A launch that reopens designs now marks them in the recovery folder; the marker is cleared as each design finishes opening. A launch that finds the marker left behind skips those designs once and says which one the last session stopped on, so the app starts usable and the loop breaks. Co-authored-by: Dahak Builds <dahakbuilds@users.noreply.github.com> |
||
|
|
4d738cd210 |
Sketch: an ellipse is drawn with its axes, and D measures its half-axes (#9291) (#9292)
* Sketch: an ellipse comes with its axes, and D measures its half-axes An ellipse could only be sized by its minor radius, drawn like a circle's radius, and there was no way to give its full axes. sketch.ellipse now also adds the major and minor axes as construction lines through the centre. The major axis runs from the major end to the point opposite it; the minor one is perpendicular to it, ends on the ellipse, and both are bisected by the centre. That adds six coordinates and six equations, so the ellipse keeps its five degrees of freedom, and it needs no new constraint kind and no format change. With the axes in place every ellipse size is an ordinary dimension. D on an axis line gives its length, the whole axis. D on the outline gives a half- axis, the distance from the centre to an axis end, chosen the way a line chooses horizontal or vertical but in the ellipse's own frame: text pulled across the major axis measures along it (the major half-axis), text pulled out past an end of it measures across it (the minor one). The end on the text's side is used. Near the boundary between the two, a dimension being placed keeps the half-axis it had (sketch.dimension's previous_axis, which the Dimension tool sends), so the preview does not flip. A half-axis and its whole axis determine each other, so the second becomes a driven dimension through the existing redundancy path. Deleting the ellipse leaves its axes, as deleting a Center Rectangle's edges leaves its construction diagonals. Ellipses without axes, from existing designs, keep the minor radius as before, and type radius still gives it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Guide: an ellipse's axes and half-axis dimensions Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: test that an ellipse's half-axis preview keeps its axis near the boundary The Dimension tool sends the half-axis its last preview chose, so near the boundary between the major and the minor half-axis the preview keeps it. This covers that path from the tool, from both sides of the boundary. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: an ellipse's axes select and drag with it, as a rectangle's diagonals do A double-click on a Center Rectangle's edge or diagonal selects its edges and both diagonals, and dragging a diagonal moves the rectangle without changing it, because its lines share corner points. An ellipse's axes are held by constraints instead, so a double-click selected only the ellipse (and Delete then left the axes behind), and dragging the major axis moved the ellipse but stretched its minor half-axis. Sketch::ellipse_axes now finds an ellipse's construction axes (the detection sketch.dimension already used, moved into the sketch crate). Sketch::chain treats an ellipse and its two axes as joined, so a double-click on any of them selects all three. Dragging either axis moves the ellipse and both axes as one, keeping both half-axes. Dragging the outline still sets the minor half-axis. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: a corner test reads its line's id instead of assuming l1 sketch.ellipse now adds two axis lines, which take the first line ids, so the extend test reads the id of the line it draws from the reply. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: an ellipse's axes cut a trim, as a Center Rectangle's diagonals do Trim, extend and break take every other curve as a cutter, construction lines included, so an ellipse's construction axes stop them as a Center Rectangle's diagonals do. A test now states it for both shapes, and the guide says it. The freeform cutter test keeps the axes it used to delete and asserts the piece a trim removes: from where the major axis crosses the circle to where the ellipse does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: test dragging an ellipse's outline with its axes present Dragging the outline sets the minor half-axis, and the minor axis line, held on the ellipse at one end, follows it; the centre and the major half-axis stay. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: other dimension types on an ellipse with axes keep the minor radius Only auto, major and minor give a half-axis on an ellipse drawn with its axes. Any other type (radius, diameter, horizontal and the rest) gives what it gives on an ellipse without axes, as the parameter doc says, instead of quietly becoming a half-axis chosen by the text. The arm for a missing text_at is dropped: with no text the rule already picks the minor half-axis. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: test an ellipse's half-axis dead zone from the major side too The tests only showed a previous minor half-axis being kept near the boundary; the point they used on the major side is major by geometry alone. A point inside the band where geometry says minor now shows a previous major half-axis kept, in the engine and in the Dimension tool's preview. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: a placed ellipse half-axis is the one its preview showed On an ellipse already sized, a half-axis is added as a driven dimension on the click, and that command left out the half-axis the preview kept near the boundary, so the click could place the other one. It now passes it as the preview does. The remembered half-axis also comes only from a draft whose text was placed (one without text is the minor half-axis by default and biased the first placement), is kept per sketch as well as per picks, and is forgotten once a dimension is placed or the picks are cleared. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: say how an ellipse's axes are recognised and what that costs The axes are read from the constraints, with no mark in the design, so the doc comment says which lines count, that deleting the midpoint or point-on-curve constraint leaves an ellipse without axes, and that each lookup scans curves times constraints. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: an ellipse with one axis deleted still picks its half-axis by the text With one construction axis deleted, D on the ellipse fell back to the minor radius wherever the text was pulled, because the half-axis choice needed both axes. It now reads what is left of them and chooses as before: the major half-axis goes to the major end (also from the far side, when the point opposite is gone with its line), the minor one to its axis end, or as the minor radius when the minor axis is the one deleted. An ellipse with neither axis keeps the minor radius. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: the one-axis half-axis test checks what is measured to The test for an ellipse with one axis deleted checked only the reply's axis and value, which both ends of an axis give alike. It now checks the dimension's kind and end: the axis end on the text's side, the major end from either side once the point opposite is gone, a radius once the minor axis is. With the major axis deleted and no text the reply names the minor axis and measures to its end, where it used to be a radius with no axis named. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: an ellipse's minor radius is drawn as its half-axis, without R A radius on an ellipse is the minor half-axis, and it was drawn as a circle's radius: one leader from the centre towards the text, marked R, which measures nothing a reader can see. It is now drawn as the distance from the centre to the minor axis end on the text's side, the way the half-axis is drawn while the ellipse has its axes, and labelled with the length alone. This is what D gives once the minor axis line is deleted, and on an ellipse with no axes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: an ellipse's half-axis keeps a radius's stored text The half-axis frame read the stored text from the middle of the half-axis, so a radius placed on an ellipse in an existing design would show its text somewhere else. The text is stored from the centre again, as a radius's always was, and the side drawn to follows it. An unplaced one sits where a linear dimension to the minor axis end puts its text, and stacked texts step out from the centre as a radius's do. A view test reads the painted label, so the drawing cannot go back to R unnoticed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: an ellipse moved, turned or scaled takes its axes along Move, Sketch Transform and Scale moved only the curves picked, so an ellipse moved without its axes left them where they were: its centre no longer halved them, the minor end left the ellipse, and the sketch stayed unsolved. A Center Rectangle's diagonals share its corners and always go along; an ellipse's axes share only the major end. The axes now go with the ellipse, as they do when it is dragged. Copy is unchanged: it copies no constraints, for a rectangle either. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: a preference draws ellipses without their axes, as before Drawing an ellipse with its construction axes changes what the Ellipse tool makes out of the box, so the old ellipse stays one setting away: Preferences › Sketch › Draw ellipses with their axes, on by default. Off, the tool draws the ellipse alone. sketch.ellipse takes axes: false for the same, and keeps drawing the axes when it is not given. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: sketch.ellipse refuses an axes value that is not true or false A string such as "false" was read as not given, so the axes were drawn; it is now refused as the text commands refuse a non-boolean bold or italic. The move test also covers an ellipse whose minor axis was deleted: the major axis left goes along. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: D picks a half-axis on an ellipse without axes too An ellipse with no axis lines (both deleted, a mirrored copy, one from an older design) gave the minor radius wherever the text was pulled, so its major half-axis could not be dimensioned on it. The half-axis is now chosen by where the text is on every ellipse: the major one to the ellipse's own major end, the minor one as its minor radius. With no text it is the minor radius, as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: with one half-axis dimensioned, D on the ellipse gives the other D on an ellipse chose the half-axis by where the text was pulled even when that half-axis was already held by a dimension, so the second D usually guessed the one already there and was refused as over-constrained. With a driving dimension already on one half-axis (to an axis end, the minor radius, or the whole axis along its line or between its ends), D with no type now gives the other, in either order and with or without the axis lines. With both held it chooses as before; an explicit major or minor is kept. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: the held half-axis rule is documented and its cases tested The Dimension command's parameters and the guide now say that with one half-axis held, D on the ellipse gives the other. Tests cover the whole axis held as a distance between its ends and as its line's length with the other axis deleted, and check that a mirrored ellipse has no axes. The placement test undoes its first dimension, so its second half still tests where the text is rather than the held half-axis. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: Transform previews an ellipse with its axes OK in Sketch Transform moves, turns and scales an ellipse's axes with it, but the window drew where OK would leave only the picked curves, so the axes stayed put in the preview until OK. An ellipse picked alone is now drawn with the axis lines it has. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: the typed-radius ellipse test counts the ellipse's axes Main's #10282 test drew an ellipse with typed radii and expected one curve; with the ellipse_axes preference on by default the tool also draws the two axes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: an ellipse's remaining axis still drags and selects it With one axis deleted, dragging the other axis did not hold the ellipse (with the minor axis left, the drag squashed it), and a double-click on the ellipse or that axis selected only the one curve. The drag and Sketch::chain now read whichever axes are left through ellipse_axis_lines, as Transform and Move already do. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: drop the unreachable third arm of the held half-axis check A distance from the centre to the major end or the point opposite it is already matched by the first arm, so the third arm and its major_end closure never ran. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: D on an ellipse's axis line is the whole axis wherever the value is pulled An axis line took the free line's rule, so on a turned ellipse a value pulled beside or above the box the axis spans gave its horizontal or vertical distance. An ellipse's axis is a construction axis, so auto now always gives its length, which the held half-axis check already counts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: an ellipse's axis is never a side of a Fillet or Chamfer corner A line drawn from an ellipse's major end shares that point with the major axis, so Fillet or Chamfer there took the two as a corner (two lines skip the construction filter) and rounded the line into the axis. The axes are left out of a corner, picked by its point or as a and b. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: test the move reply, extend and the one-axis Transform preview for ellipse axes The reply of sketch.move, sketch.transform and sketch.scale lists the axis lines, Extend stops at an axis, and Sketch Transform previews an ellipse with the one axis left after the other was deleted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: with Draw ellipses with their axes off, D on an ellipse is its minor radius as before The preference brought back the old drawing only; D on an ellipse had changed with no way back. sketch.dimension takes half_axes (default true, refused when not true or false); false makes auto on an ellipse the minor radius wherever the text is. The Dimension tool and the context menu's Sketch Dimension pass it from the preference, and with it off a radius on an ellipse is drawn and labelled R as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: read an ellipse's axes in one pass over the constraints ellipse_axis_lines scanned every constraint for every curve, so 500 ellipses with their axes (1500 curves, 2000 constraints) took 1.6 s to read and Move on all of them 2.0 s. It now collects the lines the centre bisects first: 3 ms and 0.36 s. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: the dimension and corner parameters say how an ellipse's axis lines take part Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Preferences: Draw ellipses with their axes says D gives the minor radius when off Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: ask only the ellipses centred on a line's midpoint whether it is their axis is_ellipse_axis read every ellipse's axes to answer for one line. An axis is bisected by its ellipse's centre, so it now asks only the ellipses centred on a point that bisects the line. The answer is the same. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: a horizontal or vertical dimension across a level major axis holds it for D on the ellipse half_axes_held counted a distance, a length and a radius, but not a horizontal or vertical dimension across the major axis, which is its length when the axis lies that way. D on the outline could then take the held major half-axis and be refused as determined; it now gives the minor one. Across a slanted axis such a dimension is only a projection and does not count. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Dimension: a draft on an ellipse is drawn with the axes preference it was made with The frame read the preference as it is now, while the dimension added is the draft's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: a horizontal or vertical dimension across an upright minor axis holds it too Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: drop the unused Sketch::ellipse_axes; ellipse_axis_lines says how the axes are read Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: an ellipse's own axes do not cut it, so Trim takes a lone ellipse whole and stops at real crossings Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: Fillet and Chamfer offer no corner at an ellipse's axis end, as the engine takes none Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: a deleted ellipse leaves its centre on its axes, as a Center Rectangle's centre stays Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: ellipse axis docs say what they do, and the corner picker tests a curve's ends before its axis role Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: the trim-at-a-crossing test checks that part of the ellipse is left Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: an ellipse axis moved, turned or scaled on its own takes its ellipse along, as a drag does Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: a selection dragged by an ellipse axis takes the ellipse along, as the axis alone does Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Docs: the Sketch preferences page lists Draw ellipses with their axes Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: the ellipse axes help text says D gives the minor radius, drawn and labelled R as before, wherever the value is pulled Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
e3f99de8af |
Onyx: a tactile stone-grey theme with broad subtle blur (#10338)
* Onyx: add the finished stone-grey theme and document its blur range * Onyx: distinguish grey construction lines from gold dimensions |
||
|
|
7bd66b7c06 |
Sketch dimensions: enter the value in a small window with step arrows (#7246) (#7251)
* claim: #7246 * feat(sketch): enter a dimension's value in a small window with step arrows (#7246) * Dimension window: fit the layer split, and keep the wheel off the camera over the window Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: bherbruck <brennen.herbruck@gmail.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
f74c6605c4 |
Fillet: Mitre or Swept corners where two rounds meet (#11498)
* SMLib wrapper: a swept or mitred turn for constant rounds (Turn) Brep::blend_dropping takes a Turn: Mitre (the default, as before) or Swept, which sets solidcore's FilletSession::set_swept_turns before the corners are made. A swept turn solidcore refuses at CreateFilletCorners comes back as Error::TurnRefused with its reason and place (NoRoom at a concave side edge, else CornerUnsupported). Swept is for Blend::Round only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DtL5M41G8Nua7HvuFPZkmJ * Kernel: fillet rounds turn in a mitre or swept (FilletTurn) fillet_removing, fillet_max, fillet_max_each and fillet_each take a FilletTurn and hand it to SMLib, through the reblend of earlier rounds at a later corner too. A swept corner solidcore does not build is refused as invalid input with its reason and place: no smaller radius builds it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DtL5M41G8Nua7HvuFPZkmJ * Design: a fillet saves its turn, mitre (default) or swept FeatureKind::Fillet gets `turn` (FilletTurn: mitre, the default and not saved, or swept), one pending format file. Evaluation hands it to the kernel, pattern copies included, and refuses a swept turn with a style, fit, corner or setbacks the kernel's swept corner does not take (SWEPT_TAKES). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DtL5M41G8Nua7HvuFPZkmJ * solid.fillet: the turn parameter, and the command's input and output schemas `turn: mitre|swept` on solid.fillet, refused when unknown or with options a swept corner does not take. solid.fillet now has its contract (FilletParams) and reply type (FilletResult), registered with checked!, and leaves schema/unconverted.txt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DtL5M41G8Nua7HvuFPZkmJ * Fillet dialog: a Turns choice, Mitre or Swept A Constant radius fillet's Turns row sends `turn: swept`; choosing a narrowed radius or a curvature corner puts it back to Mitre, and Swept puts those back. Its tooltip says what each does where two rounds turn round a corner edge. New strings in a pending locale file (en, de, ja, ko, zh); glossary entry. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DtL5M41G8Nua7HvuFPZkmJ * Fillet turn: the schema tests' fixes and the complete catalogs' strings The no-contract example in the schema tests is solid.chamfer now that solid.fillet has one; the reply test checks the mid-radii form against the contract (solidcore refuses that law's corner yet, #430) instead of building it; Arabic, Hebrew and Vietnamese, complete catalogs, get the new strings. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DtL5M41G8Nua7HvuFPZkmJ * Fillet schema test: variable and spline forms checked against the contract solidcore fails a variable round on a box edge at this pin (status 1001, as variable_radius_on_a_box_edge), so the reply test checks those forms against the contract instead of building them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DtL5M41G8Nua7HvuFPZkmJ * Fillet turn: the swept rig cases pass; the MCP no-contract example is solid.chamfer cov-fillet-turn-swept-boss-base-r1 and cov-fillet-turn-swept-pocket-sharp-corner-refused-r1 pass now that solid.fillet takes `turn`: off the rig's known-failing list. The MCP bridge test's example of a command without a contract was solid.fillet, which has one now. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DtL5M41G8Nua7HvuFPZkmJ --------- Co-authored-by: jyviko <2501648+jyviko@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
e438a9bbea |
Web app: choose the release, the release candidate or the edge build (#11419)
The web app is now offered at /app/ (latest release), /app-rc/ (newest release candidate) and /app-edge/ (current main), each with its own browser storage. /app/ is built from the latest release's web zip instead of main. |
||
|
|
c5ccb9201d |
Wave 43/45: smlib: rustfmt after the C++ kernel's removal (and 1 more)
2 commits, squashed; the originals stay reachable from branch jyviko/merge-main-develop-solidcore (#11360). - |
||
|
|
ea772a0438 |
Merge develop into main: SolidCraft on the SMLib kernel (v1.1.0-alpha) (#11351)
* UI: rim and wall picking tests for a circle of arcs that is one wall A circle drawn as two half arcs now extrudes to one full-turn wall with its seam edge, and each rim is one closed edge (tangency-labs/smlib#67). The tests keep their intent on that body: a rim clicked once is one item, measured and highlighted whole and picked from either side; a wall picked either side of its seam is the same surface, lit whole, and toggles off from the other side; every face is its own patch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Fillets: a later round at a corner where earlier rounds meet blends them again with it The owner's ruling of 2026-10-30: a later fillet on an edge at a vertex where earlier rounds already meet in a mitre makes the corner rounding all of them at once makes, one smooth patch, the mitre gone. A body made by constant-radius rounds keeps what they were made on and which edges they rounded at which radius; a later round reaching such a corner blends the earlier rounds' edges (from the earliest of those meeting there on) with the new edges in one SMLib blend of the body before them. The result's history is put over the body the later round was given: an earlier round's face is that face trimmed anew (its name kept), the corner patch and the new rounds are the later fillet's. A picked mitre seam has no round of its own: it is refused unless a new edge of its radius meets it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Tests: a later r3 round at an r2 mitre, through the Fillet feature, makes the all-at-once corner Two box edges rounded r2 in one fillet, then the upright edge at their mitre r3 in a second fillet (tangent chain on, so the seam comes with it): 10 faces, 7928.743041 mm³ as fillet_radii of the box gives, the r2 rounds' names kept, the r3 round and the corner patch the second fillet's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Kernel: a body's record of rounds goes with its history, and can be read back The rounds that made a body are over the body its history is over: a new history (an operation carrying a step's result back to its own operands) leaves the record out, so a later round never reads one history against another body. Body::rounds gives the record and Body::with_rounds_of takes one back, checked (edges of the body before them, a fillet's radii, the body's history over that body), for a saved model to keep it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Model cache: a body made by rounds keeps them, so a later round blends them the same after opening A design gave another body when opened from its model cache: the rounds a body was made of lived only in memory, so a later round at their mitre was built sequentially (or refused, as too large) after opening and blended with them when evaluated anew. The saved model now records, per kernel body made by rounds, the body they were made on (a place in the bodies, stored once though no state holds it) and the edges with their radii; reading it attaches them back down each chain, and a thinned model keeps those bodies with the bodies made from them. Model cache format 7. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Tests: a corner patch of rounds 2/3/4 takes no more than the strips leave in its block three_rounds_at_a_corner bounded the patch's extra cut at 3 mm³ beyond the strips, a figure with no derivation; SMLib's all-at-once body at radii 2, 3, 4 takes 3.099 (V 7878.579574 against strips 7881.678). That body is the strips' outside the block its patch lies in: its rounds are the strips' cylinders ending at a's section y = rc, b's x = 20 − rc and c's rails where they meet a's and b's (the patch's four corners, now asserted), so the patch takes at most what the strips leave in that block (11.86 at 2/2/3, 32.69 at 2/3/4). The lower bound is that block; the upper one, at most the strips' volume, stays. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Tests: the io crate's hand-built saved models list their rounds, as format 7 records do Model cache format 7 ( |
||
|
|
6be5be7f0c |
Keys: option to keep model keys out of sketches (#7675)
* Keys: a sketch and the model kept apart on Scope `command_for` fell back to the first enabled command bound to a key, so a model key pressed in a sketch (F, Fillet) still ran the model command. A key now runs only a command of the scope the view is in, or one that works everywhere; otherwise nothing fires. Inspecting, views and file commands (`inspect.*`, `view.*`, `file.*`) count as everywhere, so Measure's I still works in a sketch. #4432's `sketch_and_model_keys_are_kept_apart` is ported to `Scope`. Not ready: main's `the_extrude_key_in_a_sketch_finishes_the_sketch` (#2815) expects E in a sketch to finish it and open Extrude, which this rule stops. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keys: keep model keys out of sketches as an opt-in preference The strict sketch/model split is now Preferences > Shortcuts > Keep model keys out of sketches, off by default. Off, a key resolves exactly as on main (a feature key such as E still finishes the sketch). On, a sketch runs only sketch keys and keys that work everywhere (inspect, view, file). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * rustfmt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
ce6ad21106 |
macOS update: say to quit SolidCraft before replacing it (#7584) (#7886)
* claim: #7584 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019FAWPuFoh9qxn2uS2j53QZ * macOS update: say to quit SolidCraft before replacing it (#7584) After Download and open, the update window told people to drag SolidCraft to Applications, replacing the old copy, then restart it. Finder refuses to replace an app that is running ("the item “SolidCraft” is in use"), so the message now says to quit SolidCraft first, then drag the new copy over and open it again. "Quit" rather than "close": closing the window on macOS can leave the app running. The id update.dmg_opened is unchanged; every catalog that carries it is updated, and the user guide's update tables get the same step. Fixes #7584. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019FAWPuFoh9qxn2uS2j53QZ --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
dadefec702 |
Joint dialog: Find Limits fills the limits from where parts collide (#5968) (#7047)
* claim: #5968 * Joint dialog: Find Limits fills the limits from where parts collide (#5968) joint.find_limits sweeps each value of a joint both ways from where it is, on a copy and with its own limits left out, and answers where the parts it moves first touch another part, where a closed loop stops closing, or that nothing is met within a turn (angles) or the parts' reach (distances). Edit Joint's Limits section gets a Find Limits button that runs it on the joint as the dialog has it, off the window thread, and fills the rows. joint.sweep now tells touching bodies apart from the other bodies of the same two parts: on the Hinge Assembly sample the pins touch where it starts, and the plates used to pass through each other unnoticed. * find_limits: read the session only * find_limits: a joint with nothing to meet, edits during a search, tiny ranges * find_limits: keep touching at the start per pair of parts Per body, the Hinge Assembly sample's plates, which only come flush in the end plane the two leaves share, stopped the search. The leaves never pass into each other: the sample's answer is a whole turn. * find_limits: touching boxes cost no collision work; stale results and rounding * find_limits: each pair of bodies of resting parts held to its own depth; loops without bodies * find_limits: a 32-bit budget it can pass, a repaint with the result, a bad form says so first * find_limits: each pair of resting bodies gets its own margin * find_limits: Arabic, Hebrew and Vietnamese strings (complete catalogs on main) * find_limits: search the joint with Edit Joint's side picks Edit Joint now keeps the joint's sides as picks in its inputs, and its OK commands compare them with what it opened on. Built without them, the commands Find Limits applies first asked for the sides again, so every search failed. --------- Co-authored-by: MateuszSychXpl <151755914+MateuszSychXpl@users.noreply.github.com> |
||
|
|
89f1234f28 |
Browser: placements start closed (#9274) (#9658)
* claim: #9274 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Browser: placements start closed (#9274) A large assembly opened with every placement unfolded, so the browser was a long list to scroll through. Placements now start closed; opening one shows its own placements still closed, and closing and reopening it leaves them as they were. Find in Browser, a pick in the view, Expand All and Collapse All open and close them as before. Preferences > Interface > Components start open (browser_components_open) keeps every placement open from the start, as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Browser: scenarios and the icon audit open placements, which now start closed Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Browser: tests that read rows inside placements set the open-placements preference Three tests added on main since this branch started (joint folders, Features folder marks, group rename) look at rows inside placements, which now start closed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: bherbruck <tenbee91@gmail.com> Co-authored-by: bherbruck <brennen.herbruck@gmail.com> |
||
|
|
c7547eb3a8 |
Extrude: a face picked off the profile's plane is the target by default (#11201)
With a profile or face picked, clicking a face, vertex or parallel plane that is not in the profile's plane now sets Extrude to To Object, not one more profile. Clicking into the Profiles box first makes the next picks profiles again. Preference extrude_auto_to_object (Tools) turns it off. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
b6aabb88ff |
Insert Design: place reused links from their parent origin (#10813) (#10825)
* claim: #10813 * fix: place reused linked designs from parent origin (#10813) |
||
|
|
446590dca1 |
fix(engine): report design variant in timeline.inspect and accept in timeline.add (#10748) (#10792)
* fix(engine): report design variant in timeline.inspect and accept in timeline.add (#10748) * ci: refresh checks to clear cancelled workflow run |
||
|
|
b557f22f97 |
Sketch: a construction/normal switch in the construction line tools (#10258) (#10551)
* Sketch: a construction line with a length can be a normal line (#10258) `construction: false` on a construction line command that has a `length` makes the segment a normal sketch line, ready to close a profile, instead of construction geometry. The default stays construction, and an infinite line is always construction. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: a length box in the construction line tools (#10258) The horizontal, vertical, parallel and perpendicular construction line tools show a Length box beside the pointer from the start. It stays empty (shown as infinite) and leaves the keyboard to the tool's shortcuts until a digit is typed; then the box takes the keyboard. Without a length the tools work as before: one click, an infinite line. With a length the first click sets the start and a second click the side the segment runs to, sent as the command's `length` and `near`, so the segment gets its length dimension. The angle tool has a Length box beside its Angle box. A typed length keeps the start's snap, and the preview draws the segment the click will create. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: a construction/normal switch in the construction line tools (#10258) A Construction | Normal switch sits under the Length box of the construction line tools. Normal sends `construction: false`, so a segment with a length becomes a normal sketch line, ready to close a profile, without converting it afterwards. The switch starts at Construction with each start of a tool. An infinite line is always construction, so without a length the switch is greyed out and its tooltip says why. It belongs to the tool alone: the Sketch Palette's drawing line type (X) is left as it is. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
ce72abacf9 |
Construct: plane through an axis and a point (#10178) (#10472)
* claim: #10178 * feat: add plane through axis and point (#10178) |
||
|
|
24b91bd453 | Sketch Concentric: accept a circle or arc and a sketch point (#10487) | ||
|
|
7bafc99390 |
Send to Slicer: the Print face input takes one face for each body sent (#10468)
With several bodies to send (after Add all bodies, say), the Print face input refused every face. It took a print face only when exactly one body was sent; any other pick was cleared at once, with a note in the status bar only. Each body's print face then had to be set with Ctrl+B, or by sending that body alone. The input now holds the print face of each body being sent. A face picked in it becomes its body's print face, in place of the one it had. A click on a body's print face takes it out and clears only that body's. A face of a body that is not being sent is refused with a message (`ui.print_face_body_not_sent`, in place of `ui.print_face_one_body`). Each change is still one `body.print_face` command, so it undoes on its own. Picks in this window are no longer widened to the other pieces of the face's surface, so a click on a print face takes it out rather than adding its neighbours. The user guide (guide/files.md) says so. The new message is in assets/locales/pending/print-face-each-body.json, in all 31 languages; the old one is removed from the catalogs. Test: dialogs_save_mesh::tests::the_print_face_input_takes_one_face_for_each_body_sent (fails without the change: the second body's face is refused). Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
9d01f6e005 |
Sketch: construction lines with a length (#10258) (#10427)
* claim: #10258 * Sketch: construction lines with a length (#10258) The horizontal, vertical, angle, parallel and perpendicular construction line commands take an optional `length`: the line becomes a construction segment from `at`, running towards `near`, held by a length dimension that follows its expression. Without `length` the line stays infinite, as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Markus Kaltenbrunner <kaltenbrunnermarkus@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
9475e0e1a4 |
Docs/design approach 10063 (#10409)
* claim: #10063 * docs: add a design approach and workflows chapter to the user guide (#10063) Adds guide/design-approach.md after the window tour: the parametric idea, principles for designs that change well, the timeline and rollback marker, bodies vs components and occurrences, common workflows with links, a term map for users of other CAD software, and where to find help. * docs: match the chapter to the app's labels and sketch colours (#10063) Checked in the web app (0.29.0): the timeline strip is headed History, the toolbar shows New Sketch and Parameters for Create Sketch and Change Parameters, and fully constrained geometry turns white in the default dark theme rather than dark. * docs: tighten the design approach chapter's wording (#10063) The glossary covers most, not all, of the chapter's terms; Redo moves forward; the timeline is shown as the History strip; Report a bug drafts a report for the user to file and sends nothing itself. |
||
|
|
e4a67d1e30 |
Assembly: move sketches to the part they're drawn on (#10218) (#10219)
* claim: #10218 * Assembly: move sketches to the part they're drawn on (#10218) `component.move_sketches.to_parts` moves each given sketch, or every sketch in the design, whose plane is an exactly attached face of a part's body into that part through `component.move_sketches`, as one undo step. Sketches with no single part to go to stay where they are, and the reply lists what moved and what stayed, with the reason. The Sketches folder's menu offers it for the folder's sketches (or the selected ones), and a sketch's menu for that sketch or the selected sketches; the status bar says how many moved and why the others stayed. `component.move_sketches` now keeps a face-attached sketch where it is on its face: the sketch is authored in the new component's placement (the face's own when the component owns the face), and its picked point and repair plane are carried into it. Before, a face-attached sketch moved out of the design was left without an author placement and failed to evaluate. * Tests: the moved part is free to move; face anchor path * Tests: move the to_parts test to the component command tests * Shorter label: Move Sketches to Their Parts |
||
|
|
80fb02f0b8 |
Sketch Ellipse: Major radius and Minor radius boxes while drawing (#10279) (#10282)
* Sketch Ellipse: Major radius and Minor radius boxes while drawing (#10279) The Ellipse tool showed no value boxes. After the centre it now shows Major radius, after the end of the major axis Minor radius; a typed value places the point at that size and becomes the ellipse's dimension, as for a circle's Diameter. sketch.draw.dimensioned takes major_radius and minor_radius for sketch.ellipse, so Dimension new shapes covers it too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch Ellipse: test the typed radii in the tool and in sketch.draw.dimensioned, and say so in the guide (#10279) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch Ellipse: rustfmt the new engine test (#10279) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
4594d81f7a |
Gruvbox: light and dark themes with three contrast choices (#10292)
* claim: consolidate Gruvbox contrast variants * Consolidate Gruvbox variants into light and dark contrast choices * Check both original Gruvbox viewport gradient endpoints * Reset Gruvbox scenario state before independent theme checks |
||
|
|
2e3448f348 |
Sketch: an option to make the part active when sketching on its face (#10215) (#10216)
* claim: #10215 * Sketch: an option to make the part active when sketching on its face (#10215) Preferences › Sketch › "Sketching on a part's face makes that part active", off by default. When it is on, a sketch started on a face of another component's body activates that component at the picked placement first and is made there, as after an explicit activate. The part stays active, so what is built from the sketch lands in the same part. For scripts the same is `sketch.create` `activate_part: true`; the reply's `activated` names the component and placement. On an error the active component goes back to what it was. * Tests: a free part, no edge projection, the sketch on the face plane |
||
|
|
8be56316f6 |
Sketch Chamfer: several corners at once, as Fillet does (#8998)
The three sketch chamfers take `points: [corners]` (a point reference or
{a, b} each), as sketch.fillet does: every corner is cut alike in one
edit, and a corner that can't be cut, or is named twice, refuses them all.
The Chamfer window sends every picked corner instead of refusing a second.
Claude-Session: https://claude.ai/code/session_01PVKpSVXR9iiwSM9B25kpvq
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
|
||
|
|
0476154973 |
Update Links: linked designs that changed while the tab was away come back as one undo step (#9743) (#9753)
* claim: #9743 * Update Links: linked designs that changed while the tab was away come back as one undo step (#9743) Coming back to an assembly's tab read each changed link in an Update Links run of its own, so each became its own undo step: one Undo took back one component and left another copy of the same part at the new version. component.update_links now takes `components`, a list, and goes on past a design it cannot read: that link keeps its bodies, is named in `failed` and gets a warning. The tab return sends one request with every changed link, records as read only the ones that were, and says on the status line which one could not be read. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
8f259d5b83 |
Sketch: the Line tool can switch to a tangent arc and back without changing tool (#9489) (#9553)
* claim: #9489 * Sketch: the Line tool can switch to a tangent arc and back without changing tool (#9489) With Preferences > Sketch > "Rest on a line's last point to switch to a tangent arc" on (off by default), leaving the chain's last point and resting back on it for 0.35 s makes the next click a tangent arc, by the existing sketch.arc.tangent command, and the same gesture goes back to lines. A label at the cursor says which. sketch.arc.tangent's end can now name an existing point, so an outline drawn this way closes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Sketch: the cursor label names the command in words (#9489) The label asked the catalog for a message id that doesn't exist, so it showed the id. It now takes the command's translated label, and the test checks the words it paints. Moved clear of the pointer's own badge. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
5bb3b6717f |
Equation curves: the variable can carry its range's unit (#9333) (#9549)
* claim: #9333 * Equation curves: the variable can carry its range's unit (#9333) A curve can set variable_unit "range" (or tick the new box in its window): the variable is then a length, so a ^ 2 / (4 * t) is a length when a is one. Start and end must both be lengths, or one a length and the other a plain number in the design's unit; anything else is refused. Saved only when set, as one pending format change; without it curves behave as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
3c0d4e120e |
Linked designs: one changed while the assembly was closed is read again when it opens (#9739) (#9872)
* Claim #9739 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Linked designs: one changed while the assembly was closed is read when it opens (#9739) A link now keeps the SHA-256 of its design file's bytes as the assembly last read them (DesignLink::file_sha256, a pending format change), set by Insert Design, Relink, Extract to File and Update Links. component.links reports `changed` from it, hashing a file again only when its time or size changed (vfs::design_path_stamp, behind the design-path rule). The app treats a link it meets for the first time whose file changed as not read yet, so opening an assembly, in its own tab or in place of the blank design, reads those parts again as a tab coming back does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Linked designs: read what changed last when a design opens in place of the blank one (#9739) A read is taken up only by the design revision it started from, and adopt bumped the revision after starting it, so the read was dropped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
da23eb1377 |
Sketch dialog follows "Dialog buttons at top" (#9860) (#9884)
* claim: #9860 Co-Authored-By: Claude <noreply@anthropic.com> * Sketch panel follows Dialog buttons at top (#9860) The Sketch panel drew Finish Sketch, Look at and Slice in a footer under its options even with Preferences > Interface > Dialog buttons set to Top. Panel::palette now reads the same published preference as the feature cards and draws its footer row under the header, above the options, when it is Top. With the preference off nothing changes. Changes a default: no Co-Authored-By: Claude <noreply@anthropic.com> * Docs: Dialog buttons at top also moves the Sketch panel's Finish row (#9860) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
9d8ab72da7 |
Ribbon tooltips: help for every remaining toolbar command (#9060) (#9868)
The last 106 commands on the backlog get the two-sentence help under their tooltip, in English, German, Japanese, Chinese, Arabic, Hebrew and Vietnamese: Surface, Sheet Metal, Plastic, Inspect, Construct, Configure, Parameters, Library, View and the few single ones (Bill of Materials, Frame Member, Pattern on Path, Convert Mesh, checkpoints). With that the backlog is empty, so it goes: the test is now every_toolbar_command_has_help, and the docs that mentioned the backlog say so. The help tests use sketch.drag, which is not on the ribbon, as the command without help. |
||
|
|
160662ffec |
Tab colours: per-tab surfaces and fade (#8876) (#9808)
* claim: #8876 * Resolve theme tab surfaces with cached Oklab transitions * Apply tab surfaces to unauthored Render preview backgrounds * Allow quantized endpoint colours late in cubic Render fades * Keep tab surface publication from restyling ordinary widgets |
||
|
|
2f6ca7e46b |
Linux: optional system title bar (server-side decorations) (#9263)
On Linux the window always had no OS decorations and drew Windows-style caption buttons in the application bar. SOLIDCRAFT_TITLEBAR=system, or "titlebar": "system" in graphics.json, now opens the window with the desktop's own title bar and buttons (server-side decorations where the compositor offers them). The default is unchanged; Windows and macOS are unaffected. Claude-Session: https://claude.ai/code/session_01Gnm1n2PVPqghMuR9kHWXfh Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
d7cba9e96d |
Preferences: theme options list and the opacity option (#8876) (#9807)
* claim: #8876 * claim: #8876 * Theme options: persist per-theme values and expose preferences contracts * Restore selected theme mode after stopping a followed theme * claim: #8876 * Preferences: render theme options and apply readable panel opacity * Use floating-point scale expectation in theme preferences scenario * Keep panel opacity colour construction inside theme tokens * Complete theme options translations in Arabic Hebrew and Vietnamese * Let standalone theme sliders fill their option cells |
||
|
|
3b77567932 |
Docs: joint flip needs x for point origins; checkpoints are single use, 16 kept (#9746) (#9844)
joint.create's flip text and the assemblies guide said two origins at one point with the same z stay as they are; a point origin without x takes its x from z, so a part turned about z turns back. Say so, and point to giving x on both origins or joint.as_built. edit.checkpoint and edit.restore_checkpoint now say that restoring or forgetting uses the checkpoint (and later ones) up and that only the last 16 are kept, and the "no checkpoint N" error says why. The editing and mechanisms skills no longer read as if a checkpoint can be restored twice. Co-authored-by: thocsmith <193096300+thocsmith@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
ca005237a1 |
Theme files: options, overlays and requires (#8876) (#9805)
* claim: #8876 * Theme files: add options, overlays and requirements |
||
|
|
3877ef08b9 |
Measure: drag the labels away from the part (#8510) (#9395)
* claim: #8510 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Measure: drag the labels away from the part (#8510) The distance and X/Y/Z labels in the view follow a drag of the pointer and keep a leader to what they measure; a double-click or a new measurement puts them back. A press on a label picks nothing, starts no box selection and opens no Select Other. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
cce337f83f |
Sketch: alignment guides from any hovered point while drawing (#9105) (#9673)
* claim: #9105 * Sketch: alignment guides from any hovered point while drawing (#9105) While a drawing tool waits for a point, hovering a line or arc end, a rectangle corner or a free point wakes the same temporary horizontal/ vertical tracking guide as a circle centre or line midpoint. Idle hovering keeps centres and midpoints only. Preference sketch_tracking_points (on) turns it off. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
8311ae5c5d |
BOM: group purchased children under inseparable parts (#9744) (#9794)
* claim: #9744 * Fix grouped BOM children for inseparable parts |