Compare commits

...

148 Commits

Author SHA1 Message Date
selune 0cbf328bab chore: preserve reviewed X4-exact-nano source proposal and provenance 2026-10-31 04:37:43 +01:00
selune 3559964792 archive: conditional X3 SPLINE acceptance preserving rmorgans prerequisites (unrun) 2026-10-31 03:20:37 +01:00
selune dfb0b3e113 archive: preserve reviewed eleven-path X1 source reconciliation (unresolved lock, unrun) 2026-10-31 01:13:00 +01:00
selune cd39f96d33 archive: preserve reviewed X1 two-file reconciliation on frozen main (unrun source) 2026-10-31 00:59:27 +01:00
selune 67cbfe941e wip(drawings): preserve explicit PDF widths following the owner contract 2026-10-31 00:06:11 +01:00
selune 45286e0489 wip(drawings): preserve F0 checked font-plan sources and original acceptance 2026-10-30 23:33:09 +01:00
selune 5f127aceb0 wip(drawings): preserve additive B1 width and many-page reference source 2026-10-30 22:14:51 +01:00
selune e717739735 wip(drawings): preserve B1 text-plan scaffold and 13 original unrun cases 2026-10-30 20:44:35 +01:00
selune 28d90fae50 fix(drawings): preserve reviewed caller-local circle compatibility proposal 2026-10-30 15:06:40 +01:00
selune 7b18fd5c0f Preserve P2 B1 adaptation analysis and unit-neutral arc diagnostic 2026-10-30 10:30:14 +01:00
selune 992466e76a Preserve unintegrated W10 same-units half-turn converter and PDF reproducer proposals 2026-10-30 10:12:41 +01:00
selune c46fd3acd4 Preserve W21 NoPictures parity and repeatability source proposal 2026-10-30 08:30:35 +01:00
lillith 7d66a4d0ab Clarify Drawings preservation manifest and published index hash
Source preservation only. The manifest now records the actual published index README rather than the initial selection note, and states its pre-Git-normalization hash scope. Original product proposals are unchanged. The canonical index links all branch checkpoints; validation and owner handoffs remain pending.
2026-10-29 11:00:46 +01:00
lillith 0b3bc6e968 Preserve remaining Drawings original source proposals and canonical code index
Canonical preservation of W10, W21, X4 and supporting W38 source proposals. Sources remain deliberately unregistered and unexecuted, with real bases and alternatives documented in proposals/drawings/README.md. Existing contributor claims and PRs remain authoritative; this is not a merge-ready integration candidate.
2026-10-29 10:57:57 +01:00
lillith d8e7a8690a fix(dxf): keep counter and copy tests compatible with strict Clippy
Use fresh local mutable counter values instead of mutable references to
constants. Enumerate the ten original copied shapes after asserting their
independent fixture count. Preserve all production code, numeric expected
values, refusals and the other tests. No lint suppression or ignored tests.

The prior 6b39ee36 attempt stopped at test-target Clippy, before native
test builds/runs and wasm. Both test-only hunks were independently reviewed;
normal formatting passed without changing bytes. New results are pending.
2026-10-29 03:17:21 +01:00
lillith 6b39ee3686 fix(dxf): resolve strict Clippy findings without weakening checks
Remove an unused private Interval helper and collapse the copied-vertex
guard to an equivalent let-chain with identical evaluation order and error.
Preserve all 28 geometry and 10 bounds tests, limits and assertions.

The prior a7f3c78b development attempt stopped at Clippy; IO/engine tests
and wasm were not reached. Both corrective hunks were source-reviewed,
and normal formatting passed. Tests for this new source remain unrun.
2026-10-29 02:59:05 +01:00
lillith a7f3c78b07 feat(dxf): add bounded bulged paths and layered text import (WIP #5319 #5320)
Add the reviewed minimal X1 bulged-path producer, conservative bounds,
ordered layered bulge reader, ELLIPSE/TEXT imports and two original
cross-feature cases. Preserve legacy entry points; retain the two explicit
source-supported fixture migrations, not a blanket assertion relaxation.

Include the three original owner corrections from #8534 to unblock wasm,
without adopting later main or transferring upstream validation.

Normal cargo fmt --all passed. 223 declarations in the nine IO files
(333 including 110 unchanged UI/web declarations) are not test results.
This WIP has not been compiled or run; full CI and caller migration remain.
Earlier-source native passes do not qualify this candidate.

Co-authored-by: Ray <raykholo@users.noreply.github.com>
2026-10-29 02:39:19 +01:00
lillith 471e17f50e feat(dxf): preserve layer-zero imports and nine TEXT alignments (WIP #5319 #5320)
Add explicit alignment production and bounds callbacks, immutable layer-zero
initialization/import, and a reviewed fix retaining its metadata through copies.
Preserve the existing POINT and real writer-reader roundtrip foundation.

156 test declarations across four modules, including 26 additions against the
published parent; this source has NOT been formatted, compiled or run. Separate
source reviews do not qualify runtime. The older-source X2 gate remains separate.
2026-10-28 23:29:45 +01:00
lillith 1891344e07 feat(dxf): preserve POINT and original round-trip acceptance (WIP #5320)
Source-only reviewed four-file increment. 18 added test declarations, not executed. Published at the user's request; current X2 validation continues on unchanged older source.
2026-10-28 22:54:24 +01:00
lillith 1e176d8503 feat(dxf): preserve partial layered reader WIP (#5320)
Stacked on the owned X2 model. Includes 52 declared tests, not executed. Legacy projection and the remaining importer contract are pending; not ready for merge.
2026-10-28 21:57:39 +01:00
lillith fac0043543 feat(dxf): preserve owned file model and shared writer WIP (#5319)
Publish the reviewed partial implementation at the user's request while the corrected normal full gate is running. Not ready or fully validated.
2026-10-28 21:57:39 +01:00
lillith 119c40c814 claim: #5319 2026-10-28 19:37:38 +01:00
github-actions[bot] fe3fb381b1 Regenerate generated files and fold pending files [skip ci] 2026-10-28 18:21:33 +00:00
github-actions[bot] 0778d24801 Regenerate generated files and fold pending files [skip ci] 2026-10-28 18:14:57 +00:00
PaddleStroke 79f53a0999 Sketch dimensions in their own colour in every theme (#7861) (#8124)
* claim: #7861

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

* Sketch dimensions in a colour of their own in every theme (#7861)

Dimension lines, arrows and values were drawn in the same near-black or
near-white as fully constrained sketch curves, so they were hard to tell
apart in a busy sketch. Every theme now sets its own dimension colours:
plum on Light, orchid on Dark, and a hue from each built-in theme's own
palette. Colour vision tests measure them against the curves, the
construction lines and the conflict red, and a new test holds every
shipped theme to readable, distinct dimension colours.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 16:23:47 +00:00
froglemonade2 dba3a226f6 Closing from the background brings the window forward to ask about unsaved changes (#7783) (#7784)
* Closing from the background: the window comes forward to ask about unsaved changes

Right-click › Close on the taskbar while another app had the focus showed the
"save changes?" prompt in a window that stayed behind, so the close seemed to do
nothing. When the close stops at the prompt, the window now asks for the focus
(unminimizing it first) and for the user's attention, which is what native
Wayland offers (xdg-activation) and marks the taskbar entry where the system
refuses the focus. A window already in focus is left alone.

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

* X11: ask the window manager to raise the window as a user action

winit's Focus asks as an application, which KWin's focus-stealing prevention
refuses for a window last used before the switch away: it raised nothing and,
since the attention request was then skipped, did not even mark the taskbar.
On X11 send _NET_ACTIVE_WINDOW with source 2 (a direct user action) through
x11rb, which restores a minimized window too; native Wayland keeps the
attention request. Moves the logic into come_forward.rs.

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

* Come forward once the taskbar menu is gone, without flicker

KWin raised the window, then the taskbar's closing context menu handed the
focus back to the previous app 2 to 11 ms later, so the window only came
forward some of the time; asking again made it flicker. Ask 120 ms after the
close instead, and again only when the focus is taken back within 50 ms of a
request (a slow menu) or never came. A later switch away is the user's own and
the window stays behind.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 16:09:25 +00:00
cronos b72165fd30 Sketch: show temporary centre and midpoint alignment guides (#7903)
* Sketch: show center and midpoint alignment guides

Add transient per-viewport horizontal and vertical guides with a sketch preference. Related tests, native UI, WASM and supplementary Linux checks pass. Full CI remains blocked by unchanged Windows engine dead-code Clippy errors.

* Sketch: complete alignment-guide translations

* Tests: compile chosen-program mutex only on Unix
2026-10-28 16:07:05 +00:00
Frank 8e26fe9388 Measure: number the two picks in the view (#6020) (#6021)
* claim: #6020

* Measure: number the two picks in the view (#6020)

"1" and "2" beside the measured line's ends, as the panel lists the
picks, each just past its end so it stays off the line and its length.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-28 16:05:22 +00:00
semmelrinde c8c9534022 Create Sketch: the grid previews the origin plane under the pointer (#6975) (#7404)
* claim: #6975

* Create Sketch: the grid previews the plane under the pointer (#6975)

While Create Sketch waits for its plane, the grid now lies on the origin or
construction plane under the pointer, so the sketch's plane shows before
the click. A plane's browser row under the pointer lights that plane in the
view, and previews it the same way.

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

* Create Sketch: the planes at the top of the History preview too (#6975)

main now draws the Origin rows at the top of the vertical History as well
(history_rows). Hovering a plane there lights it like its row in the browser:
the plane is handed over the same way the hovered bodies are.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 15:58:33 +00:00
Christian Hammacher aae2c5e417 Assemblies: edit a linked component in place, with the assembly around it (#7672) (#7819)
* Links: update linked designs that changed while the assembly's tab was away

A design coming back to its tab compares the modification time and size of its linked
design files with what they were when it went to the background, and runs Update Links
on the worker thread for those that changed: saved in another tab, another window or by
a checkout. Preference update_changed_links (Design, Linked designs) turns it off.

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

* Docs: the assembly guide says linked designs update when their tab returns

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

* Links: Vietnamese strings, now that vi is a complete catalog

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

* Links: remember what each design last read, so an update that fails is tried again

A design's linked files are now recorded as the design last read them: when Update Links reads a
link without an error, or when the link is first seen. Coming back to the tab reads again what
differs, one link per run, so a file that cannot be read holds up no other and is tried again
the next time, and a part changed while the assembly was shown is taken up on its next return.
Closing several tabs together reads nothing on the way, and the web build, which keeps no file
times, looks at nothing.

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

* Links: no read during a save-changes prompt, records for adopted designs and missing files

A tab shown to answer "save changes?" reads no link before its save, and Cancel there or on a
batch lets the tab left in front read what it skipped. A design opened in place of the blank one
records its links at once, a link whose file is missing is recorded as missing so it is read when
the file comes back, and a read queued for a design that is no longer shown by the time it starts
is dropped. More changed links than can wait at once are read on the next return.

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

* Assemblies: edit a linked component in place, with the assembly around it

Activating a linked component opens the design it comes from in a tab of its own, with the
rest of the assembly drawn faded around it where the component sits, so the part's own history,
browser and commands are at hand. Finish Editing in the browser saves the part, goes back to the
assembly and closes the part's tab when the edit opened it; coming back to the assembly updates
the changed link (or Finish Editing runs Update Links when that is turned off). Update Links in
the part also reads the assembly's links again, off the window thread, and redraws the assembly
around the part; a result for an assembly changed meanwhile is dropped with a message.

The part is an ordinary tab, so saving, autosave, recovery, closing and quitting treat it as any
other design. The model scene's ghost triangles are now drawn (only the preview's were).
Preference edit_linked_in_place turns it off. Builds on the update of changed links when an
assembly's tab returns.

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

* Edit in place: a double-click opens it, Activate only activates

A double-click on a linked component edits it in place, in the browser as on a face in the
view (around the placement clicked), and the component's menu gets Edit in Place. Activate and
the browser's radio button make it the active component as they always did, so a linked
component can still be activated without opening its design.

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

* Double-click on a component's face: edit a linked one in place, activate any other

A double-click on a face in the view activates the component the body belongs to, at that
placement, as a double-click on its row does; a linked one is edited in place. Bodies of the
design itself or of the active component are left alone, and so is a double-click with a
modifier. One preference, double_click_components, covers both gestures.

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

* Edit in place: fixes from review

An edit whose part never opens is forgotten instead of starting on a later open of the same
file, and the web build starts the edit after its synchronous open. Finish Editing goes on only
for a save into the linked file and in the part's own tab, waits for a "changed on disk"
answer, and says so when the part was saved elsewhere. Showing the assembly no longer drops a
refresh, which now records the links it read so coming back reads nothing twice. The faded
assembly is worked out once per picture, a bad mesh index skips its whole triangle, and the
last two status texts come from the catalogs.

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

* Edit in place: Finish Editing on the MODEL tab and the mouse's back button

Finish Editing is a command now, component.finish_edit, with its schemas: the app window
answers it, anywhere else nothing changes, as with view.fit. While a linked design is edited in
place the MODEL tab ends with a FINISH EDITING panel, pinned at the right as FINISH SKETCH is,
with a new left-arrow icon; the browser keeps only the line naming the assembly. The mouse's
back button, or a keyboard's Back key, finishes too unless a dialog, tool or sketch is open.
The assembly guide describes editing in place.

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

* Edit in place: fixes from the second review

Saving the assembly waits while it reads its links for the part
Finish Editing waits for dialogs, tools, sketches and prompts open in the part, also when run as a command
The assembly reads the edited part explicitly when it does not check its links on its own
The FINISH EDITING panel cannot be customized
A tab opened by an edit stays that edit's to close when the part is entered again
The mouse's back button finishes editing; the keyboard's only while no text field has focus
Refreshing the assembly keeps its selection and active component

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

* Edit in place: fixes from the third review

component.finish_edit run as a command opens nothing and answers with an error when it cannot finish; engine.batch and engine.script refuse it
A double-click or Edit in Place while a dialog, tool or sketch is open in the assembly keeps it open
What changes in the assembly while it reads its links without changing its document stays: picks, activation, components dragged but not captured
Showing the assembly while it reads its links starts no second read
A new or opened design in the part's tab ends the edit
Finish Editing keeps the part's tab open while its agent chat runs

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

* Edit in place: Update Links run as a command in the part refreshes the assembly too

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

* Edit in place: the ribbon button reads Finish Edit, as Finish Sketch does

A bare "Finish" took the catalogs' surface-finish translation (German "Oberfläche").

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

* Edit in place: fixes from the fourth review

Finish Edit waits while the part's agent is in the middle of its turn, instead of keeping the tab of any chat open
A part saved while its assembly refreshes is read again when the edit finishes: the refresh records the files as it found them
A double-click on a linked component while something is open in the assembly says so instead of activating it
Commands are recognised in any spelling the engine takes, so engine.batch and engine.script cannot slip Finish Edit through
Update Links run as a command refreshes the assembly from the control channel only, not for the app's own reads
Moves of components the refresh removed are not carried over, and a refusal is one message
The command description and the guide say that the command does not save the part

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

* Edit in place: the command is Finish Edit, as Finish Sketch is

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

* Edit in place: a command to start it, and fixes from the full review

Added component.edit_in_place {component, path?}: the double-click and Edit in Place in the menu run it, and as a command it asks nothing, so a network location not allowed yet or a design open elsewhere makes it fail instead
Finish Edit asked by the part's own agent finishes once that agent's turn ends; the button still waits for the turn
The parameters and design properties panels, with text typed and not applied yet, hold up entering and finishing an edit
A refresh is not taken up under an undo, a queued command or a feature still being computed in the assembly
Refusals say what holds them up (a refresh, a file being read or written) instead of nothing
The browser strip names the assembly that is refreshing, not any assembly
The schema description says the command does not save the part
Korean strings for every new message

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

* Edit in place: fixes from the second full review

The MCP batch tool refuses component.edit_in_place and component.finish_edit as steps instead of sending them one by one
Edit in Place asked while the assembly's agent is in its turn opens the part once the turn ends; a double-click then is refused rather than stopping the agent
Both commands answer queued: true when they wait for the agent's turn, and stopping the agent forgets what it queued
An undo, a queued command or a delete check running in the design holds up entering and finishing an edit
A refresh redraws every edit of the assembly, the parts in other tabs too
In an assembly never saved, a double-click activates the linked component as before
The control and MCP docs list the new batch and script refusals, and the commands list every way they fail

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

* Edit in place: fixes from the third full review

The MCP batch tool refuses the two commands however a step names them, an execute step too
A queued Edit in Place is checked fully when asked for, a second one is refused, and both queued requests wait for what runs in the design instead of being dropped
Disconnecting the agent forgets what it queued, as stopping it does

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

* Edit in place: help text for the Finish Edit button

main now requires help for every toolbar command (#7134), and Finish Edit
is one. Written in every language the branch's catalog carries.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 15:57:44 +00:00
Ajmal Musthafa 2cc6615c2d Enhance two-tangent circle tool: add default radius handling and improve interaction hints (#8116) 2026-10-28 15:57:06 +00:00
Homero Thompson 9c5b3beb73 geom: cover inside_loop and segments_meet in the fill predicates (#6162)
Add unit tests for fill.rs's two ray-casting predicates, which
fill_general.rs relies on to decide which parts of a surface a loop
covers: a point inside/outside a square and an L-shaped (non-convex)
loop, documenting how inside_loop resolves points on an edge or
vertex; and segments that cross, stay apart, touch at an endpoint,
or are collinear with and without overlap for segments_meet.

Closes #38

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-28 15:49:30 +00:00
CamWight 14acdc2a6d Render: one sRGB transfer function (#7161) (#7162)
* Render: one sRGB transfer function, geom::srgb, for the hand-written copies (#7161)

Twelve places wrote the sRGB encode or decode formula out by hand (doc's glass
recipe, engine's render library, glTF import, the PNG film, photographic and
presentation output, the ray tracer's image, the stage, the surface decoder,
texture normalisation and the theme's contrast check). They now call
solidcraft_geom::srgb: encode/decode on 0..1 values, encode8/decode8 for 8-bit
codes. render::surface::srgb8_to_linear stays as a re-export, so its callers
are unchanged.

Same results: the module's tests compare it bit for bit with the formula as the
callers wrote it, over all 256 codes and a dense sweep of linear values plus
the knees, out-of-range values, infinities and NaN, for each way the callers
clamped (after encoding, before it, or not at all), and decoded values either
side of the decode knee, where no 8-bit code falls.

One change: glTF import encoded in f32. Over every f32 in 0..1, 218 of
1,065,353,217 values sit on a rounding tie that f32 got wrong and now give the
neighbouring code (f64 gives the nearer one).

Left as they are: render/job/image.rs (replaced by exact tables in its own
change), the tests and the starter-pack validator that keep their own copy as
an independent reference, and the WGSL shaders (they can't call Rust).

Fixes #7161

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

* Tests: the sRGB codes of five callers that had no test of their output (#7161)

The glass swatch, a library surface applied as a plain appearance, glTF's
fallback for a colour channel that isn't a number, a stage panel and an empty
pixel in presentation output each get an assertion with their sRGB codes worked
out by hand. A planted wrong conversion at each is now caught by that test.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 15:48:56 +00:00
semmelrinde bcb67cc2ec Mirror and Pattern: a body feature reopens with Bodies and its Operation (#8207) (#8298)
Editing a body Mirror from the history showed Object Type Features (the dialog starts from
the timeline selection, the Mirror itself, which turns pattern objects into features) and
dropped its saved Join. The editor now sets the objects back to Bodies for a body Mirror or
Pattern and restores the Mirror's combine.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 15:38:41 +00:00
Jasper van Loenen a8e5bfca73 Fix BOM table being too narrow (#8113) (#8144)
* claim: 8113

* Bill of Materials: size columns to their contents, Description fills the rest (#8113)
2026-10-28 15:28:55 +00:00
raykholo b68d42e5ec Theme: paste a theme into the Import tile (#8226) (#8227)
* claim: #8226

* Theme: paste a theme into the Import tile (#8226)

Ctrl/Cmd+V on Preferences > Interface imports a copied theme file, the tile's
menu offers Paste theme, and a theme file dropped on the tile imports instead
of opening as a design. Pasted text that is not a theme keeps its usual
meaning. The tile reads "file or paste".

* Theme paste: the new strings in Arabic, Hebrew and Vietnamese too (#8226)
2026-10-28 15:28:48 +00:00
github-actions[bot] 1ca2c5299c Regenerate generated files and fold pending files [skip ci] 2026-10-28 17:46:27 +00:00
github-actions[bot] 7d652d0e1f Regenerate generated files and fold pending files [skip ci] 2026-10-28 17:39:36 +00:00
semmelrinde 5f98396460 Dutch: translate the Render workspace's 733 messages (batch 2) (#8283)
* Dutch: translate the Render workspace's 706 messages (batch 2)

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

* Dutch: the 27 Render messages main gained since (the Appearances panel)

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 15:28:41 +00:00
Badger B bffa846a55 Add German translations, batch 3 (#7237) (#8285)
* Add German translations, batch 3 (#7237)

* Use "Ansatz" for boss in German (#7237)

* Fix article for "Ansatz" (#7237)
2026-10-28 15:28:35 +00:00
semmelrinde 62da9deb29 Hungarian: translate the Render workspace's 733 messages (batch 2) (#8286)
* Hungarian: translate the Render workspace's 706 messages (batch 2)

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

* Hungarian: the 27 Render messages main gained since (the Appearances panel)

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 15:28:28 +00:00
semmelrinde d17bc410a9 Galician: translate the Render workspace's 733 messages (batch 2) (#8292)
* Galician: translate the Render workspace's 706 messages (batch 2)

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

* Galician: the 27 Render messages main gained since (the Appearances panel)

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 15:28:21 +00:00
semmelrinde fe210ece6d Malay: translate the Render workspace's 733 messages (batch 2) (#8299)
* Malay: translate the Render workspace's 706 messages (batch 2)

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

* Malay: the 27 Render messages main gained since (the Appearances panel)

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 15:28:06 +00:00
semmelrinde e8d214716d Norwegian Bokmål: translate the Render workspace's 733 messages (batch 2) (#8300)
* Norwegian Bokmål: translate the Render workspace's 706 messages (batch 2)

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

* Norwegian Bokmål: the 27 Render messages main gained since (the Appearances panel)

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 15:27:59 +00:00
P'tite Tête a4d1b5b6a9 Viewport: fewer ambient occlusion samples while the view moves (#7165) (#7214)
* feat: Fewer ambient occlusion samples while the view moves (#7165)

- Draw AO with 8 samples while the view moves, 32 once it has held still for 0.25 s
- Share the settle tracking with adaptive supersampling and repaint when it settles
- ui.screenshot waits for the full-quality frame (at most half a second)
- Test the sample choice, the uniform slot, and ghosting at both counts

* fix: Set the AO sample count in the scale test frame

- scale_tests.rs, new on main, builds a gpu::Frame without ao_samples
- Use AO_SAMPLES, as the other still-frame builders do

---------

Co-authored-by: P'tite Tête <asso@ptitetete.com>
2026-10-28 15:05:34 +00:00
semmelrinde 8589cdfb84 Ukrainian: translate the catalog entries that held English, and the missing ones (#8073)
Co-authored-by: bherbruck <brennen.herbruck@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 15:05:02 +00:00
dudedagger42 4a34a258e1 Logo: an option to draw it in the theme's accent (#8133)
* Logo: an option to draw it in the theme's accent

Preferences > Interface > Logo: Theme's colours (the default, as before) or
Accent, three shades of the theme's accent. ui.prefs logo_accent.

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

* Logo: US spelling for the option's label, as upstream's English catalog uses

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

* Translations for the new options in the five complete catalogs (ar, he, ja, vi, zh)

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 15:04:53 +00:00
Herperlerpicus 3a951bc8c3 Sketch: dimension new shapes as drawn (squashed onto current main) (#5987)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 14:57:54 +00:00
HiroKenEz 4fa051c9fc View angles: an optional readout under the orientation gizmo and a command to set them (#6032) (#6249)
* claim: #6032

* View angles: an optional readout under the orientation gizmo and a command to set them (#6032)

View > View angles (also Preferences > Graphics, or view.angle_readout) shows the
view's pitch, yaw and roll in degrees and Ortho/Persp under the axis view or cube,
updated live; off by default. Clicking the readout opens a small card to type
exact angles, which runs view.apply.

The angles are the camera's own (Camera::view_angles / with_view_angles), about
the up axis: yaw is the heading of the line of sight (Front 0, Left 90, Right -90,
Back 180), pitch the eye's elevation (Top 90, Bottom -90), and a positive roll
turns the model clockwise. view.apply documents this convention and now refuses a
pitch past +/-pi/2.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 14:49:47 +00:00
Homero Thompson 31d6873f7d OBJ export: the body colours travel with the file (#4451) (#6693)
* claim: #4451

* fix(#4451): the body colours travel with the OBJ file

An OBJ export left the colours of the design behind: the mesh file named no
material, so every body arrived in the reader's default grey. The export now
writes a material library (.mtl) next to the mesh file, with a material per
body, and the mesh file names that library with mtllib and picks the material
of each body with usemtl. Every path is checked before anything is written,
the library goes first and the mesh file last, so a mesh file never names a
library that is not there. Only the colour of the body travels: the colours of
single faces and the transparency of a body stay out, as a face colour needs
material groups inside one object. The export that writes one file stays
material-free, so it never names a library it does not write.
2026-10-28 14:44:32 +00:00
github-actions[bot] 545232be37 Regenerate generated files and fold pending files [skip ci] 2026-10-28 17:08:18 +00:00
Nathan Dane c1dee61482 Render shots: strip with thumbnails, Update and Revert for camera changes (#6430) 2026-10-28 12:59:40 -04:00
github-actions[bot] ad182057b9 Regenerate generated files and fold pending files [skip ci] 2026-10-28 16:53:13 +00:00
github-actions[bot] bfe7792592 Regenerate generated files and fold pending files [skip ci] 2026-10-28 16:44:05 +00:00
semmelrinde be2deb8c6f Create Sketch: a face of a combined Mirror's copy keeps its own attachment (#5779) (#8278)
A mirror's or pattern's copy of a face carries its seed's construction certificate, and on a
combined body that certificate finds the seed's face. Capturing an attachment never checked
that the certificate finds the picked face, so a sketch on the mirrored half sat on the
original. The capture now falls back to the face's exact history name when the certificate
names another face, as docs/face-attachments.md describes.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 14:44:32 +00:00
PaddleStroke cecb1d8b66 Naming: a long history of one body no longer overflows the stack on reorder (#7587) (#8159)
* claim: #7587

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

* Naming: name a long history of one body from the oldest up (#7587)

A body's face names are worked out from the names of the body it was made
from, recursively. After a few hundred features in a row whose names
nothing asked for, reordering or moving an earlier feature re-evaluated
them all and the first name lookup (a fillet at the end) recursed once per
feature, overflowing the 1 MB window-thread stack on Windows. Name every
16th earlier version oldest first so no lookup recurses through more than
16 of them; the names are the same.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 14:43:42 +00:00
semmelrinde 427bd730f0 Title bar: a longer version moves Report a bug left instead of covering it (#5621) (#8280)
The version right of Report a bug had a fixed 60 points, enough for v0.25.1 but not for a
release candidate such as v0.21.0-rc.1, whose text was painted over the button. The bar now
measures the version and reserves its width plus a gap, never less than before. The extra
width comes only from the document tabs' spare room: where they would keep less than one tab,
the version is hidden, as on a narrow bar.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 14:33:25 +00:00
PaddleStroke 10b8faeba3 Windows: an export over a file another program holds briefly waits for it, up to 2 s (#8104) (#8125)
* claim: #8104

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

* Windows: an export over a file another program holds briefly waits for it, up to 2 s (#8104)

write_atomic replaces the target with one rename. Windows refuses that rename
(os error 5 or 32) while another program, such as an antivirus or indexer
scanning a file written a moment earlier, has the file open without delete
sharing. The retry gave up after 127 ms of waiting, which a scan under load
outlasts, so render.export and library.export over an existing file failed
with "Access is denied".

The retry now keeps doubling its wait up to 250 ms, about 2 s in all. If the
file is still held after that, the error says the file is in use by another
program, followed by the system's own message. The old file stays whole
throughout, as before.

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

* Saving over a read-only file fails at once, and says why Windows refused

Access denied (os error 5) is also what Windows gives for a read-only or
ACL-denied target, which waiting does not fix. A read-only target is now
refused without the 2 s wait, with "the file is read-only". Any other refusal
that outlasts the wait says another program may have the file open or it is
read-only, followed by the system's own message.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 14:32:20 +00:00
Dane Doubell 649ab0ef91 Sketch dimension: a slot's two caps measure the centre-to-centre distance (#7464) (#7488)
* Sketch dimension: a slot's two caps measure the overall length (#7464)

* Sketch dimension: slot caps need tangent sides, not just shared lines (#7464)

* Sketch dimension: slot caps measure the centre-to-centre distance (#7464)

---------

Co-authored-by: Dane Doubell <2853036+danedoubell@users.noreply.github.com>
2026-10-28 14:23:48 +00:00
PaddleStroke 8be7bb0201 Insert design: file names get the dialog's width (#8097) (#8122)
* claim: #8097

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

* Insert design: file names get the width the size and actions leave (#8097)

The web app's "Files in this browser" window listed stored files in an egui
Grid sized from cell content: the wide action buttons took most of the fixed
window width, the name and size columns were cut, and the rest was empty.

Add ui_kit::name_list on the kit's table grid: the name column takes the
width the other columns leave, the other columns are as wide as their widest
cell (measured as drawn, a changed measurement discards the frame), and a
name is cut with an ellipsis and its full text on hover only when it does
not fit. The window is a little wider (still capped at the browser width).

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 14:23:31 +00:00
Lars Jansen 67d5051792 Ribbon: keep the SKETCH tab shown outside a sketch (#7904) (#7906)
* claim: #7904

* feat(ui): keep the Sketch tab shown outside a sketch; its drawing tools start one (#7904)
2026-10-28 14:14:08 +00:00
Homero Thompson 7e8f87dc57 Extrude: a face shared by two bodies is resolved in the active occurrence (#419) (#6469)
* claim: #419

* fix(#419): a face shared by two bodies is resolved in the active occurrence
2026-10-28 14:13:45 +00:00
Colin Faulkingham 84016f036e Redefine: the reply reports the features it rebuilt (#5694) (#8244)
* claim: #5694

* Redefine: the reply reports the features it rebuilt (#5694)

timeline.redefine builds the edited feature and the features after it in its trial session;
the session's own evaluation then only takes those results from what the trial kept, so the
reply reported that second evaluation and read as "nothing was rebuilt" although the geometry
changed. Report the trial's rebuild, plus anything the session still had to compute itself, as
timeline.edit reports the same change; `restored` keeps counting only genuine reuse of earlier
results.

Tests: redefining_reports_the_features_it_rebuilt fails before the change with
{"feature": 2, "recomputed": 0, "restored": 2} and passes after it;
redefining_computes_the_later_features_once still guards the single computation (the reply
doubles if the kept results are lost).
2026-10-28 14:02:44 +00:00
raykholo 5f90d06452 Preferences: reverse vertical pan direction (#5240) (#5454)
* claim: #5240

* Preferences: reverse vertical pan direction (#5240)

Add "Reverse vertical pan direction" beside the horizontal setting in
Preferences > Navigation. pan_reverse_y defaults off, so older settings
files load unchanged, and flips the vertical part of two-finger pan on
every canvas through navigation::handle, independent of the horizontal
setting. Labels in en, ja, zh, de, and ko.

* Reverse vertical pan: strings as a pending locale file, with Arabic, Hebrew and Vietnamese

* Control protocol: pan_reverse_y in the sorted ui.prefs list (#5240)
2026-10-28 13:59:38 +00:00
Colin Faulkingham 27772ddba1 Keep command dialogs above Browser and History (#8174) (#8203)
* claim: #8174

* fix(ui): keep command dialogs above workspace panels (#8174)
2026-10-28 13:59:28 +00:00
semmelrinde e1b49238ba Italian: translate the Render workspace's 733 messages (batch 2) (#8250)
* Italian: translate the Render workspace's 706 messages (batch 2)

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

* Italian: the 27 Render messages main gained since (the Appearances panel)

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 13:58:52 +00:00
github-actions[bot] ba35509ca0 Regenerate generated files and fold pending files [skip ci] 2026-10-28 16:12:44 +00:00
github-actions[bot] 32f11961e9 Regenerate generated files and fold pending files [skip ci] 2026-10-28 16:06:14 +00:00
semmelrinde 4dda001210 Traditional Chinese: translate the Render workspace's 706 messages (batch 2) (#8272)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 13:58:23 +00:00
semmelrinde f49d5c2f29 Indonesian: translate the Render workspace's 706 messages (batch 2) (#8271)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 13:58:13 +00:00
github-actions[bot] afde0f8073 Regenerate generated files and fold pending files [skip ci] 2026-10-28 15:32:53 +00:00
Nathan Dane 2897d3b22e Render library: Appearances card with a sphere grid, scopes, favourites and recents (#6429) 2026-10-28 13:41:24 +00:00
bherbruck 9bcb2ffe68 Drawings: first landing from the drawings branch (#8249)
* Drawing sheets: sizes, the ISO 5457 border and its marks (#3875) (#5108)

* Drawing sheets: sizes and the ISO 5457 border (#3875)

A sheet is a paper size and an orientation: ISO A0 to A5, Letter, Legal,
ANSI A to F, architectural A to E1, or a custom size (finite, above 0 and
at most 5,000 mm a side), landscape by default and either way for every
size.

A border profile is the rule for its border, and layout() works it out
for a sheet: the frame inside the margins, and the reference fields with
their labels. The ISO profile has a 20 mm filing margin on the left and
10 mm elsewhere, a 0.7 mm frame, fields of 50 mm out from the centre
lines with the corner fields taking what's left, rows lettered from the
top without I and O (AA, AB and on past Z), columns numbered from the
left, and an A4 sheet labelled on its top and right only. A profile can
divide the frame equally instead, or have no grid.

The records sit in geom, next to the section records, so saving,
rendering and export can all use them. Nothing is saved or drawn yet:
there is no command and no format change. Margins that leave no drawing
space, values that aren't finite, fields outside 1 to 1000 mm, more than
200 equal fields and unknown JSON fields are refused.

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

* Drawing sheets: ISO 5457's centring and trimming marks (#3875)

A drawing border profile now also holds the grid reference border and the
centring and trimming marks, either of which can be left out. The ISO
profile follows ISO 5457:1999 (read in its identical adoption,
IS 10711:2001):
- the grid reference border 5 mm outside the drawing border on every
  side, with the field labels between the two;
- four centring marks on the sheet's centre lines, from the grid
  reference border to 10 mm inside the drawing border;
- at each corner a trimming mark of two overlapping 10 x 5 mm
  rectangles, in the margin outside the grid reference border.

The labelled sides are now a rule worked out for each sheet: ISO 5457's
(the top and right of A4, all four sides of the others) or fixed sides.
So one profile labels every size correctly. validate() checks what
doesn't depend on the sheet, for when a profile is read; layout() calls
it, then checks the rest against the sheet.

Refused:
- a grid reference border that isn't finite, is negative or is wider
  than a margin;
- a centring mark that isn't above 0, would reach past the sheet's
  centre lines, or is on a drawing border those lines miss;
- a trimming mark that isn't above 0, is wider than it is long, is
  wider than the margin left outside the grid reference border, or is
  longer than half the sheet's shorter side.

The grid rule's JSON is now externally tagged ("none",
{"from_centre": {"field_mm": 50}}), as the sheet size is, so an unknown
field is refused in every form; the internally tagged "none" ignored
one. Nothing is saved yet, so the shape change costs nothing.

The names follow the glossary, and ISO 5457's "drawing sheets": the
module is drawing_sheet (was sheet, which means sheet metal elsewhere
here), DrawingBorderProfile and SheetLayout (were BorderProfile and
BorderLayout), sheet_border and drawing_border (were paper and frame),
and Sheet::size_mm (was paper_mm). The first part of S1 is still a draft,
so the renames are made here rather than in a commit of their own.

The extra centring marks ISO 5457 asks for on sheets larger than A0
aren't here yet. Still nothing is saved or drawn.

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

* Drawing sheets: a lighter built-in border, the filing margin a choice (#3875)

Cameron's decisions after seeing the sheet in the app, 2026-10-23:
- No trimming marks in the built-in profile: the filled corner blocks
  take a lot of ink. trimming_mark_mm stays, so a profile can still ask
  for them.
- Centring marks stop at the drawing border: from the grid reference
  border to the drawing border, never into the drawing area (on A4 they
  crossed the tables). centring_mark_mm keeps its meaning, how far a
  mark reaches inside the drawing border, and now takes 0, the built-in
  value, as grid_border_mm already takes 0 for "on the drawing border".
  A mark of no length (a reach of 0 with no grid reference border) is
  refused.
- Margins of 10 mm all round. ISO 5457's 20 mm filing margin on the
  left, for drawings that get bound, is a named choice: filing_margin,
  off when not given. On, it stands in for margins.left_mm, which is
  kept, and still checked, for when it's off again. The 20 mm is
  FILING_MARGIN_MM, and validate() and layout() both take the margins
  from one helper, laid_out_margins().

A3 landscape is now 400 x 277 at (10, 10), with eight 50 mm columns.
With the filing margin it is 390 x 277 at (20, 10) again, the same as a
20 mm left margin set by hand. A profile with all three choices on
(ISO 5457's full border) lays out exactly as the built-in profile did
before, and the tests keep the old hand values for it.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* Drawing W23a workshop plate oracle fixtures (#4950) (#4962)

* test(oracle): reviewer-aligned parameterized workshop plate fixtures (#4950)

Independent analytic W23 expected values and seven verified models,
including four R10 corners and the 2 mm tangent top chamfer.
Document accepted Drawing states and commit regenerated docs/oracle.md
from successful workflow run #29 (90/90 pass).

* fix(oracle): correct W23 chamfer centroid and clarify drawing session ownership

* Paper scene: plain records of what is drawn on a sheet (#4890 A1) (#5513)

geom::paper holds what a sheet shows as plain data: groups of strokes and fills, each group tagged
with the object that drew it (an opaque id) and its kind, with one validation pass over a bounded
record count. Seg2's checks and the coordinate rule move into profile.rs so section and paper share
them, and drawing_sheet takes its side and line limits from paper, so each limit is written once.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* Drawing sheets: centring marks across the whole margin (#3875) (#5554)

The built-in sheet's centring marks now run from the trimmed sheet's edge to the drawing border.
From the grid reference border, as before, a mark was the same length as a grid field mark, and on
A3 it sat on one (the sheet's centre falls on a field edge), so it no longer read as a mark once the
grid reference border's outline is left out (Cameron, after the prototype on #3875).

- DrawingBorderProfile.centring_mark_start: sheet_edge (the built-in's, and when not given) or
  grid_border (ISO 5457's figure 5); ISO's full border in the tests asks for grid_border.
- A mark still needs a length: one that stops on the drawing border needs room outside it on the
  side it starts from, every margin for sheet_edge, the grid reference border for grid_border.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* Drawing sheets: no centring or trimming mark longer than the largest sheet's side (#3875) (#6410)

A border profile capped every length at 5000 mm (the largest sheet's side) but two: a
centring mark's reach inside the drawing border and a trimming mark's length. A file could
give either a huge whole number, such as 18446744073709551615. The read's number check passes
whole numbers, so the profile took it as 1.8e19 mm, and saving wrote it as a decimal the next
read refused: a drawing that saved but didn't open again. K2's fuzz test of drawing files
(#3890) found it.

Both now take the cap the margins have, `MAX_SIDE_MM`, in `validate`, so the file is refused
when it's read. Layout's own checks against the sheet are unchanged, so a 5000 mm mark still
validates and is refused only on a sheet too small for it.

Tests: the hostile-profile test refuses 5000.000001 mm and 1.8e19 mm for each mark, and takes
5000 mm on its own; 4 planted faults (each cap removed or made one short) are all caught.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* Bill of materials types: phantom, reference, purchased and inseparable (#3874) (#5107)

* Bill of materials types: phantom, reference, purchased and inseparable (#3874)

A component's bill of materials type is a part property (`bom_type` in its metadata, set with
component.metadata.set and read by component.metadata, as part_number is), so older releases
keep it and no format change is needed. It isn't a design property: the Design Properties
dialog doesn't list it and document.metadata.set refuses it. A word this build doesn't know
reads as normal and is kept.

assembly.bom counts by type: a phantom has no row and what it holds counts where it is placed,
in the same rows as the same parts there; a reference counts nowhere, and nothing inside it
does; purchased and inseparable components are one row, and in parts only an inseparable
component's purchased parts are listed too. Rows of one part number but different types are
different rows. Rows and children carry bom_type. With no types set the rows are as before.

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

* Glossary: bill of materials and bill of materials type (#3874)

The bill of materials types are a new idea, so the glossary gets their
term, with the five types, and "normal" gets its fourth meaning in the
table of words with more than one meaning.

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

* Bill of materials types: a plain line for each (#3874)

The guide's table and the glossary entry say what each type is for in
plain words: something you make, something just to group, something to
use as a reference, something you buy, something made as one piece.
The names stay the five standard ones.

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

* Bill of materials: kits fold together only when their contents' types match (#3874)

With group_children, two kits with one part number share a row when what they hold reads the
same. That reading (kit_key) compared each child by part number and count, but not by its bill
of materials type, though rows themselves are told apart by type. So a kit holding a made bolt
and a kit holding a bought one, both KIT, folded into one KIT x2 row listing the first kit's
bolt twice: the other type was lost, and which one depended on creation order. 0xlillith found
it in review of #5107.

kit_key now includes each child's type. Equal part number, type and contents still fold.

Test: two KIT kits each holding a BOLT fold into one row of two; once one bolt is purchased they
are two rows, each listing its own bolt. Planted fault (the type left out of the key): caught.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* Drawing files: a drawing saved as a container or as plain JSON, never read as a design (#3890) (#7098)

* File format families: drawings share the design format's versioning (#3890)

The format code works for a family of files: its own tag, its own numbers and
its own folder of change files, with one reading of a file's format, one
refusal of a file a newer build saved and one upgrade for every family. Designs
(solidcraft/N) are one family and keep everything they had: FORMAT and FORMATS
are as they were, and pending_names, format_string, version_of and read mean
what they did. Drawings (solidcraft-drawing/N) are the other, with format 1 as
their first record and each later change one file in
crates/doc/src/drawing/format/pending/, as design changes are. Nothing saved
changes.

A design tag never reads as a drawing's or the other way round, and a file that
names no format is a design from before format strings, never a drawing. Every
refusal names its family; a design's read word for word as before. A design
listing a pending change this build doesn't have is now refused as a newer
build's before its content is checked, as a newer number already was, so a
newer build's fields never read as damage. The list reader is
take_names(v, key, noun), the shape #4811 uses for its own list.

For the maintainer, the release step changes: scripts/fold-format-pending.sh
now folds every family that crates/doc/build.rs lists (FAMILIES), each into
its own next number: designs into crates/doc/src/format/v<N>/ as before,
drawings into crates/doc/src/drawing/format/v<N>/ from 2. With nothing pending
in a family it says so and moves nothing. Its test folds a drawing change into
v2 beside the design changes. docs/releasing.md, CONTRIBUTING.md and AGENTS.md say so.

build.rs lists each family's changes from its own folder, each folder's
versions contiguous from its own base.

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

* Drawing record: format 1 of the drawing family (#3890)

A drawing is now a record of its own (crates/doc/src/drawing.rs): its name,
the designs it draws (sources: an id and the design file's path, relative to
the drawing's folder as a linked design's is), its properties under the design
metadata's rules, its units (each design's own, or one length unit of the
expression unit table), its content language (a BCP 47 tag) and its sheets.
A sheet holds its paper, a copy of its drawing border's profile, the
resolution its pictures are rendered at (300 dpi unless it says, 25 to 2400),
the component it documents and whether it is left out of the sheet count or
of printing. This is format 1 of the drawing family; each later kind of
record adds one file in crates/doc/src/drawing/format/pending/.

The rules: one id counter for every object, raised above the largest id when
a file is read and never rewound; every reference is an id that must resolve,
or the file is damaged and refused, never patched; 1 to 1,000 sheets, at most
64 sources, names of 1 to 256 bytes, paths of 1 to 4,096 bytes without NUL.
The same drawing always saves as the same bytes.

Drawing::from_json reads at most 16 MiB of text, then runs the family's format
check, the number check, the upgrade, the typed record (unknown fields refused
everywhere) and Drawing::validate. The number check is now one function every
family calls, Family::check_numbers, told which field holds other tools' data;
a design's refusals read as before.

Nothing saves or opens a drawing yet: the container is the next step.

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

* Drawing ids: random and collision-free from format 1 (#3890)

A drawing's objects now take random ids, the form jyviko chose on #3890 from
#1017: no counter, so objects added on two branches never share an id and
never edit one line. The allocator is one module for drawings now and designs
later (#626 Phase 3), crates/doc/src/ids.rs: an IdSource gives nonzero u64s by
splitmix64 from a seed, each checked against the ids in use and drawn again
when it is one, or when it is 0. A run never draws a number twice, so at most
one draw per id in use comes before a free one, and a seeded run over a file
the same seed made still gets a new id. IdSource::seeded gives the same ids
for tests and replays; IdSource::from_entropy seeds a session from the
standard library's hash keys, the time and a count, with no new dependency.

In a file an id is 13 characters of Crockford base32, lowercase
(0000000000001 to fzzzzzzzzzzzz): ids::encode writes it and ids::decode reads
only that spelling, case-sensitive, so an id has one form to search for.
Anything else, 0 included, makes the drawing damaged. The drawing loses
next_id (a file that holds one is refused), and Drawing::new and allocate_id
take the IdSource. Messages name ids as the file writes them. The component a
sheet documents stays its design's own number until designs move over.

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

* Drawing record: a drawing too large to reopen isn't saved (#3890)

from_json reads at most MAX_DRAWING_BYTES (16 MiB), but to_json had no limit. Other tools'
properties are kept as they came, and indenting them can grow a drawing read in at about 4 MB
past 16 MiB (two million zeros in one array), so the next read refused what the save had just
written. 0xlillith found it in review of #3891.

to_json now returns a Result and refuses JSON longer than a read takes ("drawing too large to
save (at most 16 MiB)"), so every drawing saved opens again. Nothing writes drawing files yet, so
the error reaches the future file writer before it publishes anything.

Test: that case is refused, and a smaller compact drawing saves and reopens unchanged.

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

* Drawing files: a drawing saved as a container or as plain JSON, never read as a design (#3890)

K3 of the drawing storage plan (W11.2): the file a drawing is saved in. Nothing writes one from a
command yet; opening and saving come with K5.

- A drawing container is a design container holding `drawing.json` (Deflate, as `document.json`)
  in place of `document.json`, and `container.json` says so:
  {"content": "drawing", "format": "solidcraft-container/1"}. A design's `container.json` is as it
  was, with no `content`. The plain JSON form is the drawing's own text. Both give the same bytes
  every save, so a drawing can live in version control as text.
- `io::file_kind` tells a design from a drawing by `container.json` or by the JSON's format. The
  design reader refuses a drawing ("this file is a SolidCraft drawing, not a design: open it as a
  drawing") and the drawing reader a design; plain JSON only asks when it isn't a design, so
  reading a design costs nothing more. A container's content this build doesn't know, or a drawing
  container that also holds a design's `document.json`, is refused.
- `read_drawing` (bytes, either form), `read_drawing_file` (one seekable handle, the design
  reader's checks) and `write_drawing_container`; `DRAWING_EXT` (`scdwg`) and
  `is_drawing_path` beside the design's.
- The container writer's set-up and finish, the file opening and the container sniffing move into
  one function each, which designs and drawings both use. The container's own checks (budgets,
  entries, the ZIP directory) are the design container's, word for word.

Tests: a drawing round-trips through both forms byte for byte, and the container holds exactly
`container.json` and `drawing.json`; `file_kind` on both forms of both kinds; each reader refuses
the other's file; unknown content, a stray `document.json`, a missing drawing, an unknown
container version and a damaged drawing refused; both forms from disk, and a directory refused;
mutation fuzz of both forms (an error or a drawing, never a panic).

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* Paper scene: SVG of a sheet, its lines, arcs, cubics and fills (#4890 A3a) (#7032)

The first export of a paper scene, as SVG first (jyviko and 0xlillith on #4890), from the research
in the plan's §16. A3b adds ellipses, hyperbolas and Béziers above degree 3, which this refuses as
"not supported yet".

- `geom::paper::Prepared`: writers read a scene through `Scene::prepare`, which checks it first, so
  none reads one unchecked. Clipping goes there too, once (A8).
- `geom::paper::arc_pieces`: an arc's ends in pieces of at most a quarter turn, the last its own end.
  A half turn drawn from its ends is ill-conditioned: rounded to the nanometre (six decimals of a millimetre) its
  centre moves up to 1e-2 mm, where a quarter turn's stays under 1e-6 mm.
- `io::paper::paper_svg`: one user unit a millimetre, the size in mm on the root; y flipped by
  writing the height less y, so the file's numbers are page coordinates and an anticlockwise arc
  has sweep flag 0; lines `L`, arcs `A` (never large-arc), cubics `C`, parabolas `Q`; fills
  black and even-odd; one path per item; groups as `data-object` and `data-kind` (object ids can't
  be XML ids). No background, so cutters see only the marks.
- Numbers are whole nanometres (six decimals of a millimetre): no exponent, no "-0", the same bytes every time. They are the
  writer's own state too, so a joint is written once and a closed path ends exactly on its first
  point. Numbers are written straight onto the document, with no text made per number. A width
  under half a nanometre is written as one, and a piece too short for the grid is merged into the
  next, both counted in the report; a path's last piece has no next, so it is kept however short
  (unless it has no length). Output over 64 MiB is refused.

Tests: the A3 drawing border's whole document; quarter, 270°, clockwise and whole-turn arcs, and a
circle of two halves giving the same four quarters; the quarter-turn boundary both sides; cubics and
parabolas, and the conics refused; the number format; a closed path whose start and end round
apart; a sliver merged; an open path's short last line and arc kept, and one of no length dropped; read back through our own SVG reader (lines exactly, the arc as an arc);
the scene's JSON mutated into the writer (never a panic).

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* Drawing W17a: view definitions as data (#4816) (#4817)

* claim: #4816

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

* Drawing views as data: named views, scales and the map onto paper (#4816, W17a P1)

What a drawing view is, before anything draws it (geom::drawing_view):
- NamedView: the six principal views and the isometric views from the four upper corners, each
  an exact basis (a Plane whose normal points back at the viewer), never taken from a camera,
  whose pitch clamp would tilt a top view, with no -0 to write out; `iso` reads as the
  front-right one.
- basis_looking: any other view from its direction, an up and an origin (paper x = direction x up,
  paper y = x x direction), refusing a zero direction, an up along it, or an origin that isn't
  finite or within 1e12 mm. W07's
  {direction, up, origin} view reads through it.
- Scale: paper : model as two positive numbers, read and written as "1:2", from 1:100000 to
  1000:1; Scale::fit picks the largest ISO 5455 preset (50:1 to 1:10000) at which a view fits a
  space (W07's "fits the page" default), compared as size x paper <= room x model so an exact
  fit at a reduction isn't lost to rounding.
- ViewFrame: a view's basis, scale and place on paper, the point of its plane at `centre`
  landing at `position_mm`. Its paper map moves the view's curves and their accuracy onto
  paper (paper error = scale x model error); `boundary` maps a box of its plane onto paper from
  its four corners.

In geom, where Seg2 lives:
- Similarity2 and Seg2::similar (new): scale, turn and shift a segment exactly, an arc staying an
  arc. Similarity2::new refuses a scale that isn't above 0 and works the turn out once, not per
  point;
- Seg2::map_controls: a segment's control points mapped by any function. It was doc's
  sheet::map_controls; its four callers in doc use the method now, unchanged.

CurveAccuracy::scaled gives a curve's accuracy at another scale.

Tests: each named view's basis and viewer side, and the same bases from a direction and up; a 50 mm cube in every principal view at 1:1 and
1:2, and in isometric (edges 50 x sqrt(2/3), outline 50 x sqrt(2)); the view's centre on its
position (W07's 100 x 20 front view on A3 at 2:1); scales read, written and refused; the fitted
scale, an exact fit at 1:5 and ISO's smallest; no -0 in any named view's axes; an origin refused by
its own message; hostile bases, centres and positions; every segment kind moved by a similarity,
and the similarities refused; scaled accuracy.

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

* Drawing views: the bottom view pinned, square near parallel, bounded scales and boxes (#4816)

From DevonHope's review of #4817:
- The tests pin all six principal views exactly. The direction-and-up test uses literal ups,
  so a bottom view turned half round now fails it.
- basis_looking squares x to the direction before normalising. Near the 1e-9 threshold the
  normal was up to 8.8e-9 rad off; now it is about 1e-16.
- Scale::fit fits nothing for a size or room that is negative or not finite. A size of 0 still
  sets no limit that way.
- Each side of a scale is 1e-6 to 1e6, so a scale writes at most 49 characters.
- ViewFrame::boundary returns a Result. It refuses a box that is inside out or not finite on
  paper, instead of dropping a corner.
- paper_map, boundary and seg_to_paper say which coordinates they take.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* Drawing W18 S2: title blocks as data (#3875) (#3877)

* Title blocks: what a cell shows and where its text goes (#3875)

geom::cell holds a title-block cell's content: parts of text and fields
(component, drawing, sheet, revision or prompt, by key, with an optional
unit and decimals kept as written for the resolver to check), at most 64
parts and 4096 bytes of text, with no control character but a line break.
Beside it are a resolved value (live, overridden and drifted, or missing,
with "-" for each part that couldn't be read and why), an override with
the value it replaced, and the projection a drawing's views use (first or
third angle), which the title block's symbol will read.

A fit warns and never cuts: a count of characters, not bytes, with its own
count for text in Chinese, Japanese, Korean or Yi characters.

The cell text rule places a label and a value: the label's baseline 1 mm
plus its cap height below the cell's top, the value box under it inset by
1 mm, one line centred in the box, and wrapped or several lines down from
its top at the font's pitch, with a warning when the last falls below the
box. Wrapping by width, width warnings and glyphs a font lacks need the
text measured, so they wait for the paper scene's text.

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

* Title blocks: definitions and their place on a sheet (#3875)

geom::title_block holds a title block's definition: its size (1 to 1000
mm a side), its outline and cell line widths, and up to 64 cells. Each cell
has a snake-case name of its own, a rectangle measured from the block's
lower-right corner, an optional one-line label with its cap height, and a
value: text from cell content, with its cap height, alignment and fit, or
the projection symbol, which reads the drawing's projection and is never
fixed in the block.

validate() checks a definition on its own, as when one is read: cells
inside the block and not overlapping (touching is fine), label and value
cap heights that fit, and the content's own limits. layout() puts the
block on the drawing border's lower-right corner of a sheet, refusing one
that doesn't fit, and gives each cell's rectangle, its label's place and
its value box by the cell text rule. On A3 landscape a 180 x 54 mm block
runs from (230, 10) to (410, 64); it fits A5 landscape and every larger
sheet, but not A5 upright.

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

* Cell text: a value box lies within the paper's coordinates (#3875)

place_lines took any finite, ordered value box, but centring one far out (min x 1e308, max x
1.1e308) overflows: the anchor came back infinite, with no warning. 0xlillith found it in review
of #3877.

The paper scene already bounds every coordinate it holds by MAX_COORDINATE_MM (twenty times
the longest sheet side). That limit is now public, and place_lines keeps its box inside it, so
its anchor is always finite: one rule for what a paper coordinate may be.

Tests: the hostile-box test refuses both overflow cases from the review and a box just past the
limit on each side, and places lines in a box the size of the whole paper limit. The fuzz test's
numbers now include values past the limit (1.1e5, ±1e308).

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

* Title blocks: padding from the lines' inner edges, one label rule, nothing unread (#3875)

A cell's text is padded from the inner edge of its lines: each side of a cell moves in by half
the line drawn on it (the outline's on the block's edges, a cell line's inside), so a wide
outline never covers the text. Before, the padding ran from the line's centre.

The label's one-line rule lives with the cell text rules (`cell::check_label`), where parts
lists will find it. The cell types nothing read yet (`Override`, `Resolved`, `State`,
`Problem`, `Reason` and `MISSING`) wait for the resolver that will read them.

The tests check the exact thresholds inside the lines (a label that leaves no room, a value
that just fits), pick each of the lines, alignment and wrapping on their own so every
combination comes up, and lay fuzzed blocks out on every standard sheet, either way, with and
without the filing margin.

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

* Title blocks: the drawing border's line, descenders, room where the block sits (#3875)

From DevonHope's review of #3877:
- Each cell's lines are clamped to the inner edge of the drawing border's line. That line runs
  along the block's right and bottom edges, and along any other edge it reaches, as when the
  block fills the border. Aabb2::intersection, the 2D twin of Aabb3's, does the clamping.
- layout checks each cell's room again where the block sits (place_cells, which validate runs
  at the origin), so rounding at the real corner can't turn a cell inside out.
- The cell text rule counts descenders, at 3/10 of the cap height (ISO 3098's lettering B).
  They may reach into the padding under a value box, never past it to a line. place_lines
  warns Height when they would, and validate asks it whether one line fits.
- The module doc no longer links to a private function.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* Drawing W06a: exact orthographic hidden lines for the analytic subset (#2455) (#2457)

* Drawing W06a: exact orthographic hidden lines for the analytic subset (#2455)

crates/geom/src/hlr (L0): prepare once per body, then hidden_lines for a
scene of placed bodies. Edges and face silhouettes are projected from their
exact curves, split where projections cross, and each piece is classified by
rays toward the viewer against the trimmed faces: visible, hidden or
explicitly uncertain, never guessed. Planes, cylinders, cones, spheres and
tori are supported whether stored as analytic records, revolutions or spline
patches; freeform faces are reported and make what they could hide
uncertain. Screen geometry is Seg2 with the W01a accuracy vocabulary: exact
lines and conic arcs where the projection is exact, bounded chords
otherwise. docs/drawing-hlr.md holds the contract and its limits.

* geom/hlr: handle the brep records main gained in #3093

Main's exact model storage (#3093) added Curve::SurfaceIntersection,
Surface::PlaneThrough and Surface::PlacedRevolution, and the HLR matches on
the records no longer compiled. A plane through three points is a plane: it
is trimmed and intersected as one, and a box stored that way draws the same
bits as one with axis-stored planes. The procedural intersection curve and
the placed revolution (whose affine placement may scale it unevenly) are
refused by prepare as not supported yet, until the kernel adapter handles
them. The records' positions move with the body's centre like the others.

* geom/hlr: pad plane faces' boxes, so a plane record off by rounding still hides

Plane faces took the box of their boundary chords unpadded, flat along the
normal. When the plane record and its edges disagree by rounding (a unit cube's
top plane one ulp above its edges, a 100 mm cube's 1e-11), the ray toward the
viewer reached the plane just outside that box, the slab test culled the hit,
and the back edges came out Visible with no doubt. Every face's box is now
padded by 1e-6 of its size, as curved faces' boxes already were. Reported by
DevonHope on #2457.

* geom/hlr: limits from review: trim samples, scene extent, crossing pairs, surface groups

From DevonHope's review of #2457:
- Options::trim_samples must be 1 to MAX_TRIM_SAMPLES (4096).
- Placed bodies must stay within MAX_COORDINATE (1e12 mm, as section and brep
  bound stored numbers). Placements 1e200 apart made the scene's size infinite
  and every tolerance taken from it with it, so everything came out Visible.
- The crossing search counts its candidate pairs before it starts and meets
  each pair only in the first grid cell the two segments share, instead of
  keeping a set of the pairs met, which could outgrow wasm's 4 GB before the
  500 million pair budget tripped. The same pairs in the same order.
- prepare groups faces on one quadric or torus by comparing each face with
  the faces of its kind whose size agrees to the tolerance (sorted), not with
  every face; at most 50 million comparisons. prepare_cancellable polls a
  cancel callback between edges, faces and comparisons.

* geom/hlr: boundary chords on a grid, and no fine pass over coincident curved chords

The cost items of DevonHope's review of #2457:
- Every ray hit asked how far it lies from its face's boundary by scanning all
  of the face's chords (4096 per circle; a plate's face with 256 holes has
  about a million). The chords are now bucketed on a uniform grid over the
  boundary's box, cells at least as long as the longest chord, and the test
  looks only at the cells around the point. It finds exactly the chords the
  scan finds.
- Chords of two curved curves that lie on each other end to end (aligned holes
  seen along their axes) were cut into 16 by 16 pieces and intersected, to
  find crossings that are only noise within the curves' tolerance. They are
  now skipped; visibility changes where a coincident run starts or ends, and
  chords that only partly overlap still find those.
- Fixtures: a plate with holes, coaxial cylinders seen along their axis, and
  300 placements.

* geom/hlr: pad boxes by the body's coordinates too; coincident chords only to rounding

Review of the previous commits found two holes:
- The padding grew with the face's size, but rounding grows with where the body
  was modelled: a 0.001 mm cube 1e7 mm out, its top plane one step (1.9e-9 mm)
  above its edges, still had its hit culled. The pad now adds 1e-12 of the
  body's offset.
- Two chords were taken for coincident when their ends lay within each other's
  sag, which in a coarse scene can hide real crossings: an arc can bulge across
  a line 1 mm off its chord twice. Only chords that coincide to rounding are
  skipped now; identical projections, the costly case, still are.

* geom/hlr: coincident curves meeting at shared sample points do not cross

Timing the review's scenes showed that skipping coincident chords was not
enough: chords of two coincident curves also touch end to end at every sample
point they share, and each touch was a crossing to refine and split at. 64
coaxial cylinders seen along their axis gave 8.3 million crossings (19 s), 64
cylinders one behind another along the line of sight 4.2 million (214 s;
before these commits the crossing budget refused it). A touch at a shared
sample point is now dropped when the two curves also coincide, to rounding, on
both sides of it. Where a coincident run starts or ends one side differs, and
the touch is kept.

* geom/hlr: the own-face margin allows for rounding where a body was modelled

The far 0.001 mm cube of the previous commit showed a second effect of records
rounded at large coordinates: its top plane, one ulp (1.9e-9 mm) above its
edges, hid the top edges themselves, because a ray leaving an edge met its own
face 3.2e-9 mm along, past the own-face margin of 1e-6 of the face (1.4e-9).
The margin now also covers 1e-14 of the body's offset (about 45 ulps of its
coordinates), which only matters for parts far smaller than their distance
from the origin.

* geom/hlr: no parity test for a hit on the boundary, where it is uncertain anyway

* docs/drawing-hlr: the fixtures of the review's second round

---------

Co-authored-by: MateuszSychXpl <151755914+MateuszSychXpl@users.noreply.github.com>

---------

Co-authored-by: CamWight <91156642+CamWight@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Benny1496 <163034806+Benny1496@users.noreply.github.com>
Co-authored-by: Mateusz Sych <151755914+SychPL@users.noreply.github.com>
Co-authored-by: MateuszSychXpl <151755914+MateuszSychXpl@users.noreply.github.com>
2026-10-28 13:31:16 +00:00
Ahmad Khan 6af571eb40 Flat Pattern: show the whole flat size (#7495) (#7496)
* claim: #7495

* Flat Pattern: show the whole flat size (#7495)

Each side of the flat size and the thickness get their own row (Flat size X, Flat size Y,
Thickness), so the panel's width no longer cuts the value off after its first side.

* Flat Pattern: the flat size labels in Arabic, Hebrew and Vietnamese (#7495)
2026-10-28 13:25:09 +00:00
ermanyop-stack a5f472c23e Prevent angular drags from collapsing construction geometry (#8148) (#8160)
* Reject newly collapsed angular reference lines (#8148)

Reject angular solutions that collapse a reference relative to its input length. Cover constrained drags and already-short references. Engine replay and full CI validation remain in progress.

* Cover live and non-live angular drags (#8148)

Adds a replay of #8148 for live and non-live drags. The integration test compiles locally, but the Windows GNU test executable exits with STATUS_ACCESS_VIOLATION before running tests, including with --list/--help. Kept in the draft PR pending validation on a working native runner.
2026-10-28 12:44:16 +00:00
semmelrinde 34efb90489 Romanian: translate 946 messages the catalog was missing (batch 1) (#8193)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:44:10 +00:00
Tarik Sijerčić f060702676 i18n: add Bosnian, Croatian and Serbian interface languages (#7813)
* i18n: add Bosnian (bs), Croatian (hr) and Serbian (sr) catalogs

Full translations of all English messages, the pending ones included,
kept in step with one shared terminology:

- Bosnian (Bosanski): ijekavian, Latin script.
- Croatian (Hrvatski): ijekavian, Latin script, Croatian standard terms
  (točka, kut, brid, ploha, značajka, spremi, izbornik, sučelje).
- Serbian (Српски): ekavian, Cyrillic script; brand and file names,
  acronyms, units, key names and placeholders stay in Latin.

The Browser panel is "Stablo modela" so it is never confused with a web
browser, and the History panel is the timeline ("Vremenska traka"), not
the undo history, per the glossary.

Registers the three catalogs, adds them to the new-language test, a
pending attribution file, and a terminology note in docs/localization.md.

* i18n(bs, hr, sr): translate the 195 messages added on main since the catalogs were made

Covers the navigation bar customisation, the render stage, the new
command help texts and the Assistant start-up preferences, so the three
catalogs again carry every English message.
2026-10-28 12:38:27 +00:00
Homero Thompson d6b1d03695 Browser: an exact body name wins over a case-only sketch match (#6967) (#7004)
* claim: #6967

* Browser: an exact body name wins over a case-only sketch match (#6967)
2026-10-28 12:22:27 +00:00
Mateusz Sych e181015fd1 MCP save: a folder the agent opened or saved a design in stays in scope (#7181) (#7216)
* claim: #7181

* MCP save: a folder the agent opened or saved a design in stays in scope (#7181)

The agent's default folders held the open design's folder only while that
design stayed open there, so after a new design, an opened STEP file or a
save-as elsewhere a save beside the earlier design was refused, while the
same save through the control port worked.

The MCP server now keeps, for the rest of its run, the folder of every
design file a call opened or saved (open, save, and doc.open, file.save,
file.save_as through execute or batch, path given in full) and, headless,
of every design open in its session. Such a call only succeeded because the
folder was already in scope, so naming a path adds nothing. The folders get
the open design folder's terms (inside home or temp, not hidden, hidden
entries unreachable), at most 16. Bridged, they go to the app as
design_folders, which it judges the same way.

The save tool description and docs/mcp.md say how to add a folder with
--allow-path.

* MCP scope: a design's folder is the folder its file resolves to (#7181)

A link in another folder to a design inside the agent's folders passes the
scope check, which follows it, but its own folder was what got remembered
(and, for the open design, what counted while it was open). Take the folder
of the file as the check resolves it.

* Control test: a hidden file the export format accepts (#7181)

---------

Co-authored-by: MateuszSychXpl <151755914+MateuszSychXpl@users.noreply.github.com>
2026-10-28 12:22:20 +00:00
Homero Thompson 387e86729c Sketch: the rounded rectangle completes from a vertex like the plain one (#7878) (#7943)
* claim: #7878

* Sketch: the rounded rectangle completes from a vertex start point (#7878)
2026-10-28 12:20:46 +00:00
Dahak Builds 64ff25f380 Fix sketch drag breaking midpoint-constrained line solver (#7635) (#7810)
* claim: #7635

* Keep the drag cursor on the manifold of an ill-conditioned sketch (#7635)

A construction line collapsed to zero length makes its angle row's entries
on that line ~1e7 while the same row's entries on the measured line are ~1.
Dragging an endpoint of the midpoint-pinned line then failed two ways: the
null-space rank analysis, which scaled rows only, hid the small (physically
meaningful) entries below its pivot tolerance and let the measured line
rotate freely; and the cursor's refinement, which demanded a TOL-tight
correction the ill-conditioned system cannot deliver, gave up entirely and
let the drag leave an unsolvable step placed - breaking the perpendicular
and angle constraints.

Equilibrate the null-space Jacobian on both sides (columns by their largest
entry, then rows) so one row's entries share a scale, and let the cursor
keep working from a pose the solver itself calls solved (residual below
ACCEPT) when refinement stalls above TOL, accepting corrected trials at the
same tolerance the final validation uses.

---------

Co-authored-by: Dahak Builds <dahakbuilds@users.noreply.github.com>
2026-10-28 12:20:40 +00:00
Jomguy2 1dba7f7f04 Agent chat: OpenCode Go preset with per-model endpoints (#6111)
* agent chat: OpenCode Go preset with per-model endpoints

One preset (https://opencode.ai/zen/go/v1) covers every Go model: each
model is routed to its endpoint family (chat completions, responses,
messages, Gemini), always with the x-opencode-session header Go
requires. Unknown models fall through protocols when Go names the
mismatch; the conversation and tools translate per protocol.

* agent chat: keep Go reasoning metadata, route all listed models (#5656)

* fix agent chat Go endpoints to documented inference routes

* style: collapse long assert in Go routing test (cargo fmt)

* refactor: share Go tool/args helpers, table-driven protocol routing (no behavior change)

* refactor: share GoCallAccum across Go reply parsers (no behavior change)

* refactor: share part/call extractors across Go history converters (no behavior change)

* refactor: share post_to envelope between post and go_post (no behavior change)

* refactor: pass system note into go_responses_input, drop history clone (no behavior change)

* refactor: lazy Gemini name map, shared go_tools, named tool-call cap (no behavior change)

* refactor: share shaped-tool wrapper across Go tool converters (no behavior change)

* fix: set request_timeout_s in Go test setups for rebased main (no behavior change)

* fix: expect ToolsAvailable first in tool-loop tests (matches new event order)

* simplify: reuse tool_arguments, drop restater comments (no behavior change)

---------

Co-authored-by: Julius <julius@localhost>
Co-authored-by: Jom_g <jom_g@users.noreply.github.com>
Co-authored-by: HoloPort <holoport@localhost>
2026-10-28 12:20:19 +00:00
N3MI-DG 7d9b28e20d Context menu: only the row under the pointer stays highlighted while a flyout closes (#8065) (#8066)
* claim: #8065

* Context menu: only the row under the pointer stays highlighted while a flyout closes (#8065)

A row that owns a flyout kept its highlight for the whole of the flyout's
closing delay, so the row the pointer had settled on lit up alongside it.

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

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-10-28 12:19:51 +00:00
github-actions[bot] 48bcc83e2e Regenerate generated files and fold pending files [skip ci] 2026-10-28 14:56:01 +00:00
austin62jake 1e3cb3e36e Motion interference: a check cut short is not clear, and budget_s gives it time (#7855) (#7934)
* claim: #7855

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

* Motion interference: a check cut short by its work budget is not clear (#7855)

motion.interference stops when its work budget runs out (truncated) but
answered clear: collisions.is_empty(), so a check that reached only the first
steps read as a pass: a gear pair checked for 14 of 61 samples was "clear".
clear is now true only when every sample was checked and none collide.

The budget is an argument of interference_within, so a test can cut a check
short: B slides up to touching A, a full check is clear, and the least work
that checks a first step stops after 1 of 16 samples with clear: false (it
was clear: true before). The guide and the mechanisms skill say the same.

The issue's second request, a budget_s on motion.interference, is not here.

Refs #7855.

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

* Motion interference: budget_s gives a check the time it needs (#7855)

The work budget is fixed, so a gear pair drawn in detail was cut short
after a few samples, or refused before its first one. motion.interference
now takes budget_s (seconds, above 0, at most 86400, as inspect.interference
allows): the check then runs until that time instead of the work budget,
looked at before each sample, and echoes budget_s in its answer. Without
budget_s nothing changes. The refusal before a first step now names the
budget that ran out and suggests budget_s.

Tests: given a time, the smallest work budget (which checks no step) no
longer stops the check, through motion.interference too; budget_s 0, -1,
1e9 and "soon" are refused.

Fixes #7855.

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>
2026-10-28 12:19:10 +00:00
Inguss 4d6664e4ca fix(ui): expose Redefine Sketch Plane in History menus (#8024) 2026-10-28 12:18:53 +00:00
raykholo d56dc310b0 Browser: Collapse All keeps the clicked row open (#8032) (#8033)
Collapse All from a component or placement row folds everything under that
row and leaves the row itself open, matching the whole-tree Collapse All,
which already keeps the design row open.
2026-10-28 12:18:28 +00:00
semmelrinde 4ab612ea67 Standard Parts and Contact Set: label the rows in words, not with raw keys (#8005)
* Standard Parts and Contact Set: label the rows in words, not with raw keys

The Insert Part dialog listed a size's dimensions under the library's
keys (d, head height, socket depth), and the Contact Set dialog's
checkbox read "enabled". The dimensions now take messages (Nominal
diameter, Head height, Socket depth, ...) and the checkbox reads
Enabled, translated like the rest of the dialogs.

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

* Contact Set: translate the Enabled checkbox's label

ui_kit::checkbox paints the text it is given; the callers translate it,
as Configuration Rules' Enabled does.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:17:07 +00:00
semmelrinde 73f06753b6 Swedish: translate 946 messages the catalog was missing (batch 1) (#8181)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:16:54 +00:00
semmelrinde 292177e085 Preferences: the tab colour strip names the tabs as the ribbon does (#8027)
The Interface page's strip of tab accent colours looked up its own
word-cased names ("Sheet Metal", "Surface"), which the catalogs
mostly don't carry or carry with another meaning: in German it read
"Sheet Metal" and "Flächenkörper" where the ribbon says Blech and
Fläche. It now names each tab the way the ribbon does, through the
tab's heading message, and the Form tab gets one.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:16:48 +00:00
Colin Faulkingham d7111c7326 Ribbon: keep workspace captions inside the switcher (#7931) (#7956)
* claim: #7931

* Fix translated workspace captions overflowing the switcher (#7931)
2026-10-28 12:16:19 +00:00
github-actions[bot] 745184f2fc Regenerate generated files and fold pending files [skip ci] 2026-10-28 14:26:54 +00:00
semmelrinde 942f11169c Preferences: the snap-suppress choice and Direct interaction in the user's language (#8067)
* Preferences: the snap-suppress choice and Direct interaction in the user's language

The Hold to stop snapping choice joined its keys with an English "or"
("Cmd or Option", the default) in every language, and Navigation's
Direct interaction setting and its note had no message. The choice now
reads through a message with the keys as placeholders, and the setting
gets its two messages.

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

* Move the new test away from where another open PR adds one

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:15:48 +00:00
semmelrinde 029cf29b49 Dialogs: 54 labels that read English in every language get messages (#8049)
* Dialogs: 54 labels that read English in every language get messages

The construction dialogs' selection fields (First edge, Second point,
Through point, ...), the joint types (Rigid, Revolute, Slider, ...), the
Sheet Metal and Plastic rules' rows (K Factor, Flange Gap, Min Draft,
...) and a few options and prompts are passed to the label translator as
English source text that no catalog carried, so they showed English in
every language. They are added in one pending file, with the eleven
usual translations, and a test makes sure every dialog's selection
fields keep a message.

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

* Dialog labels: German Flange Gap is Flanschspalt, as the catalog's Flansch

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:15:35 +00:00
semmelrinde 7ad059aec9 Italian: translate 719 messages the catalog was missing (batch 1, all but the Render workspace) (#8062)
The Italian catalog lacked 1350 of the English messages. This batch
translates the 719 outside the Render workspace: Preferences, the
Assistant, the help texts, command labels, materials, navigation and
the rest. It uses the catalog's own terms (Schizzo, Lavorazione, Corpo,
Giunto, Cronologia, Struttura, Risalto, Appoggio, Aggancio a scatto).
The Render workspace's 600 messages are left for a second batch while
that workspace is still being built.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:15:24 +00:00
github-actions[bot] a2a00aa9ee Regenerate generated files and fold pending files [skip ci] 2026-10-28 13:58:14 +00:00
github-actions[bot] 59551c59ab Regenerate generated files and fold pending files [skip ci] 2026-10-28 13:49:47 +00:00
semmelrinde bf1b09698c Insert Part: the part families and the Name hint in the user's language (#8018)
* Insert Part: name the part families in the user's language

The Type list of Insert Part and the Change Part Size dialog showed the
library's English family names (Socket head cap screw, Hex nut, ...) in
every language. Each family now has a message under its library id,
and a family the catalogs don't know keeps the library's name.

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

* Insert Part: the Name field's automatic hint in the user's language

The hint was the English word "automatic"; it now takes the catalogs'
parts.automatic_name, which every language already translates.

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

* Move the family-name helper and its test away from where #8005 adds its own

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:15:15 +00:00
semmelrinde fc2142b407 Turkish: translate the 200 messages the catalog was missing (#8070)
* Turkish: translate the 113 messages the catalog was missing

The Turkish catalog lacked 113 of the English messages: the newer
Preferences settings, the hole presets, the slicer messages, the
Assistant's start-up options and tool summaries, and the Render
workspace's stage, shots and inspector labels. They are translated in
one pending file, with the catalog's own terms.

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

* Translate the 87 messages main added since (the navigation bar's)

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:15:03 +00:00
semmelrinde d3b2c715d3 Dialogs: translate the texts a few dialogs draw themselves (#8056)
* Dialogs: translate the texts a few dialogs draw themselves

The joints' Play/Stop buttons, the Motion Study's Loop and the BOM's
sub-parts checkboxes, the Stitch tolerance hint, the Flange type and the
Emboss wrap note were drawn as English literals; the joint lists named
each joint's type by its Rust name (PinSlot, PointOnPlane). They now take
messages, and the joint lists use the Type box's label, translated.

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

* Move the new test away from where another open PR adds one

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:14:51 +00:00
semmelrinde 09308fceb1 Dialogs: 96 hints and refusals that read English in every language get messages (#8083)
The Surface, Sheet Metal, Plastic, Frame, Move, Align, Assembly, Cam,
Coupling, Sweep, Part Size and sketch editing dialogs refuse their
inputs with English sentences ("select bodies first", "pick faces of
one body"). The dialog translates a refusal through the catalogs as it
shows it, but no catalog carried these 96, so they showed English in
every language. They are added in one pending file with the eleven
usual translations.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:14:41 +00:00
semmelrinde 8f87509f7d Russian: translate 841 messages the catalog was missing (batch 1) (#8077)
Everything outside the Render workspace, which is still being built:
Preferences and the new navigation bar, the Assistant, the help texts,
command labels, materials, hole presets, the slicer messages and the
remaining dialog labels, with the catalog's own terms.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:14:34 +00:00
semmelrinde c962e5e8cd Traditional Chinese: translate 897 messages the catalog was missing (batch 1) (#8078)
Everything outside the Render workspace, which is still being built:
Preferences and the new navigation bar, the Assistant, the help texts,
command labels, materials, hole presets, the slicer messages and the
remaining dialog labels, with the catalog's own terms.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:14:33 +00:00
semmelrinde 7df858594d Indonesian: translate 898 messages the catalog was missing (batch 1) (#8098)
Everything outside the Render workspace, which is still being built:
Preferences and the new navigation bar, the Assistant, the help texts,
command labels, materials, hole presets, the slicer messages and the
remaining dialog labels, with the catalog's own terms.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:14:22 +00:00
semmelrinde fed9605357 Sketch: the status in the view and the browser's editing mark in the user's language (#8084)
* Sketch: the status in the view and the browser's editing mark in the user's language

While a sketch is edited, the view's corner said "Sketch1 — 2 degrees of
freedom" (or "fully constrained", "constraints conflict") and the
browser marked the sketch "(editing)" or "(attachment lost)", in
English whatever the language; one degree of freedom read "1 degrees of
freedom". They now take messages: the catalogs' existing degrees-of-
freedom ones and four new ones.

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

* Sketch status and editing mark: the sketch's default name as shown elsewhere

The browser shows a default name in the user's language ("Skizze 1")
except on the edited sketch's row, whose mark made it a different text;
the view's status kept the stored name too. Both now use the name as the
browser shows it.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:13:38 +00:00
semmelrinde bf1886e90a Motion dialogs: translate the notes and refusals they draw themselves (#8096)
Motion Study, Motion Trace, the motion plot, Explode and the contact
check drew their notes and refusals as they got them ("add a key for a
joint first", "select a point on a component", "none"), so they read
English in every language. They now go through the label translator, and
the four that no catalog carried get messages.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:13:38 +00:00
phanoob dfa9afd39f Sketch: leaving a sketch opened inside a component gives the active component back (#8127) (#8157)
Double-clicking a sketch row inside a component (an inserted fastener's sketch)
activates that component so the sketch is edited in its placement. Finish and
Cancel only closed the sketch, so the component stayed active and every other
body stayed faded.

Edit Sketch now remembers the component and placement active before it
activated the sketch's own (also when sketch.edit activates the component of a
face-attached sketch), and leaving the sketch makes that one active again, as
Finish already puts the history marker back. A component activated while the
sketch is open stays active.

Co-authored-by: Phanoob <phanoob@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:13:15 +00:00
semmelrinde 944c658c90 Czech: translate 867 messages the catalog was missing (batch 1) (#8188)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:12:06 +00:00
semmelrinde 8f8df03358 Navigation: Maya and HFSS mouse presets (#6474, #2742) (#8184)
Maya moves the camera with Alt and any button (left orbits, middle pans,
right zooms), middle drag also pans. HFSS pans with Alt+left drag and zooms
with Shift+Alt+left; its Ctrl+left orbit is the drag from empty space every
preset already has, so a Ctrl+click on geometry still adds to the selection.
The help texts are in the catalog for every locale that has the other
presets' help.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:12:05 +00:00
github-actions[bot] 92fc868aa9 Regenerate generated files and fold pending files [skip ci] 2026-10-28 13:22:20 +00:00
github-actions[bot] 33281cf3bc Regenerate generated files and fold pending files [skip ci] 2026-10-28 13:13:50 +00:00
semmelrinde d64816437a Dutch: translate 942 messages the catalog was missing (batch 1) (#8172)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:12:02 +00:00
semmelrinde 8210e94b6d Malay: translate 888 messages the catalog was missing (batch 1) (#8216)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:11:08 +00:00
semmelrinde f6d969f98a Hungarian: translate 946 messages the catalog was missing (batch 1) (#8199)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:11:06 +00:00
dudedagger42 59faca3850 Canvas and Decal: send the picked face, so a large design takes the image (#5592) (#5593)
* claim: #5592

* Canvas and Decal: send the picked face, so a large design takes the image (#5592)

A click with Canvas or Decal sent only the point, so the engine searched every face of every
body for it and gave up on a large design ("face capture work limit exceeded"). Send the
picked body, face index and path as Create Sketch does; canvas.decal takes that face pick too.

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

* Canvas and Decal test: drop the check that a point alone gives up

On upstream main a sketch on a face by its point alone no longer gives up on this design, so
the test keeps only what the picked face has to do: both images land on it.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:11:01 +00:00
semmelrinde 29a2f33664 Galician: translate 888 messages the catalog was missing (batch 1) (#8214)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:10:58 +00:00
sascha2101 9d4d7932ee Sketch: offer an arc length dimension for a selected arc (#6039) (#6264)
* claim: #6039

* Sketch: offer an arc length dimension for a selected arc (#6039)

The arc length dimension already existed in the engine (sketch.dimension with
type arc_length), but nothing in the UI led to it: the Dimension tool and the
context menu always gave an arc its radius.

With exactly one arc selected, the sketch context menu now offers Arc Length
Dimension next to Sketch Dimension, which adds the dimension through the
existing command.

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

* test: move the arc length menu test up to avoid a merge conflict

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

---------

Co-authored-by: sascha2101 <221609842+sascha2101@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:10:45 +00:00
github-actions[bot] 54a207cb8b Regenerate generated files and fold pending files [skip ci] 2026-10-28 12:44:09 +00:00
github-actions[bot] 5bf5de49a5 Regenerate generated files and fold pending files [skip ci] 2026-10-28 12:35:35 +00:00
semmelrinde cee995e776 Norwegian Bokmål: translate 693 messages the catalog was missing (batch 1) (#8218)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:10:34 +00:00
Nathan Dane b86c75544e Appearance: read the look chain and replace a look everywhere in one undo step (#6428) 2026-10-28 12:10:31 +00:00
yhamil04 249318cffb Right-click opens the menu despite tiny pointer movement (#5517) (#7939)
* claim: #5517

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

* Right-click opens the menu despite tiny pointer movement (#5517)

A Magic Mouse moves the pointer a fraction of a point as it is clicked.
The right button orbited on any movement, and the menu needed exactly
zero movement in the release frame, so most right-clicks only nudged
the view. The right button now navigates once the press can no longer
be a click (egui's click distance and time), catching up with the
travel since the press, and a right-click is egui's click.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:08:27 +00:00
Colin Faulkingham 6f8ee10a86 Appearance: apply browser actions to all selected bodies (#7935) (#7941)
* claim: #7935

* fix: apply browser appearance changes to selected bodies (#7935)
2026-10-28 12:08:21 +00:00
N3MI-DG 30cb1238f7 Browser: reveal a placed body's row when it is picked or found (#7947) (#7948)
* claim: #7947

* Browser: reveal a placed body's row when it is picked or found (#7947)

The off-screen skip in `entry_row` keeps the reveal target's row alive so it
still has a rect to scroll to, but it matched `app.tree.reveal` (a world body
name) against `Entry::key` (the placement-local name). For a placed body those
never match, so the row returned early and the `scroll_to_rect` below it, which
does use `row_key`, was never reached. `app.tree.reveal` is then cleared at the
end of the frame, so there was no second chance.

Match the skip on `row_key` minus its `b:` prefix, as the `scroll_to_rect`
already does.

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

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-10-28 12:08:01 +00:00
raykholo db999b2a98 Control protocol: the ui.prefs settings as a sorted list, one per line (#7747) (#7988) 2026-10-28 12:07:43 +00:00
semmelrinde e59decda95 Primitive dialogs: label the size fields in words, not with the parameter names (#7995)
The Box, Cylinder, Cone, Sphere, Torus and Coil dialogs labelled their
size rows with the command's parameter names (length, top_diameter,
section_size), in every language. Each row now takes a message: Length,
Top diameter, Major radius, Section size, translated as the rest of the
dialog is.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:07:37 +00:00
github-actions[bot] aca80f2054 Regenerate generated files and fold pending files [skip ci] 2026-10-28 10:25:10 +00:00
Nathan Dane 0b2efd60b9 Render browser: scene tree with Environment, Lights, Shots and Objects rows, resolved appearances and a Browser selection (#6427) 2026-10-28 09:58:57 +00:00
amolinari-autotex 54f613e4dd Preserve linked component materials and appearances (#7609) (#7616)
* Fix linked component materials and appearances (#7609)

* Linked components: the cached link read carries the source properties

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

* Update Links: a link without recorded inherited properties is read again

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

* Preserve authored linked-face overrides and apply cached source properties

---------

Co-authored-by: bherbruck <brennen.herbruck@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 09:33:49 +00:00
github-actions[bot] ae07e36a7d Regenerate generated files and fold pending files [skip ci] 2026-10-28 07:57:59 +00:00
Nathan Dane 18fe82ab26 Render workspace: focus view, compact docks, a Browser chip at narrow widths and a localisation pass (#7376) 2026-10-28 07:29:53 +00:00
github-actions[bot] 372badfc1b Regenerate generated files and fold pending files [skip ci] 2026-10-28 06:43:04 +00:00
Nathan Dane 1781b4d323 Render workspace: move the Inspector or Browser dock to either side with view.render_dock and a header menu (#7230) 2026-10-28 06:15:13 +00:00
github-actions[bot] cf5dc813e2 Regenerate generated files and fold pending files [skip ci] 2026-10-28 04:43:28 +00:00
Nathan Dane b0c8c466b0 Navigation bar: icons for visual styles, selection modes and display (#6585) (#6898)
* Navigation bar: slot model and one-row renderer (#6585)

* Navigation bar: customisation section in Preferences (#6585)

* Navigation bar: icons for visual styles, selection modes and display (#6585)

* Navigation bar: redraw the Bodies, Parts and Components selection icons (#6585)

* Navigation bar: refine the Ground shadow, Ambient occlusion, Parts and Components icons (#6585)

* Navigation bar: solid cube and a longer arc for the Ground shadow icon (#6585)

* Navigation bar: the owner accepts the new icons as final (#6585)
2026-10-28 04:16:44 +00:00
github-actions[bot] 85aaed2ccb Regenerate generated files and fold pending files [skip ci] 2026-10-28 03:48:50 +00:00
Nathan Dane 110efa3598 Render: allow picking in the product view with a Body, Face or Component filter and outline the selection in the product pass only (#6426) 2026-10-28 03:20:43 +00:00
P'tite Tête 9fb41f8378 feat: Start a new selection's preview without waiting for the obsolete one (#7167) (#7261)
- Leave the running preview behind when the selection moves to another setup, asked to stop
- Keep at most two obsolete previews running; streaming, tools and other inputs wait as before
- Keep no result of a cancelled watched evaluation in the shared evaluation cache
- Test the detaching, the cancel reaching the spawned job, and the cache guard

Co-authored-by: P'tite Tête <asso@ptitetete.com>
2026-10-28 01:32:17 +00:00
bherbruck 79214b6b49 Release 0.25.1 (#7983)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 20:58:27 -04:00
github-actions[bot] 49c0faa7da Regenerate generated files and fold pending files [skip ci] 2026-10-28 00:50:43 +00:00
bherbruck 2cdfe050db Extrude to Object: a Join leaves the body it runs to alone when that body is in another component (#7975)
#6471 joined the body a To Object extent runs to into the tool, whatever its component.
A connector's boss extruded up to an enclosure's face (each in its own component) merged the
enclosure into the connector, and features referencing the swallowed body failed after it.
The body it runs to now joins only when it is in the feature's own component, or when the
feature names it as a target.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 20:48:28 -04:00
CamWight 303fddb20e Browser: Bodies folders only where they help: Always, Several bodies only (the default) or Never (#4217) (#4219)
* claim: #4217

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

* Browser: Bodies folders only where they help: Always, Several bodies only (the default) or Never (#4217)

A new preference on the Interface page, in the Layout section under Browser, sets when a
component's bodies sit in a Bodies folder of their own. Several bodies only lists a component's
lone body, when it has no groups, straight under its placement. Never lists every component's
bodies and groups there. Always keeps the folder as before. The design's own Bodies folder and a
folder hidden with its eye always stay.

One rule, browser::bodies_folded, decides it for the rows and for the menu. A folded folder
draws no row and stays open; its items move up one level, and their own eyes, hover and drops do
its jobs. While a folder is folded, its placement's menu takes the folder's Create Components from
Bodies and Group Selected; New Group and Show All were already there.

ui.prefs takes browser_bodies_folders (always, several, never) and refuses other values; saved
preferences read an unknown value as the default. The s37 scenario sets Always so that it still
checks the Bodies folder's chevron.

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

* Browser: Bodies folders in Arabic, Hebrew and Vietnamese too (#4217)

Arabic, Hebrew, Japanese, Vietnamese and Chinese are complete catalogues, so
every_complete_catalog_carries_every_english_message fails a new message any of them lacks. The
preference's four messages get their Arabic, Hebrew and Vietnamese text, in the words those
catalogues already use for a body and a folder.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 00:24:17 +00:00
github-actions[bot] 03606ec97b Regenerate generated files and fold pending files [skip ci] 2026-10-27 23:59:03 +00:00
taylorhayis c4fb42f665 Preferences: search settings (#2218) (#6002)
* claim: #2218

* Preferences: search settings across every page (#2218)

A field at the top of Preferences filters the live controls with the same scorer as command search, including a dropdown's current value and the English source of a translated label.

* Preferences search: keep the plain page list for its tests (#2218)

The production dialog always draws the search strip, so the no-header entry is test-only and no longer warns as unused.

* Preferences search: show only the settings that match (#2218)

A page name or a loose string of letters was keeping the rest of that page on screen, including notes and the mouse legend.

* Preferences search: drop stray chrome and clear from the field (#2218)

The colour swatches and folded Advanced heading were painted on every query, and the field had no way to empty itself.

* Preferences search: fold shortcut matches and drop the blank gaps (#2218)

* Preferences search: stop unmatched pages painting over the hit (#2218)

* Preferences search: a page tab clears the search and shows that page (#2218)

* Preferences search: keep OK and the graphics checkboxes in view (#2218)

A dropdown that skipped its real height on a dialog's first frame left OK outside the window, and the search strip used up the rows the graphics page needs. The shortcut fold is in the UI kit gallery.

* Preferences search: type a query and open the match from the keyboard (#2218)

A printable key or Cmd/Ctrl+F focuses Search settings, arrows move through the matches, and Enter opens that row. Escape clears the query before it can close the dialog, and clearing returns to the page that was up when the search started.

* Preferences search: translate the search strings for the complete catalogs (#2218)

Arabic, Hebrew and Vietnamese are delivered complete, so Search settings and the empty result need a translation there. German and Korean get the same two strings.
2026-10-27 23:27:33 +00:00
yhamil04 00e31c24fd Sketch: Delete on a picked profile deletes the curves around it (#7107) (#7120)
* claim: #7107

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

* Sketch: Delete on a picked profile deletes the curves around it (#7107)

While a sketch is being edited, a profile picked by clicking inside a
shape stands for the curves of its outer loop, so Delete removes the
shape instead of failing with "a profile goes with its sketch". Holes
inside it are shapes of their own and stay. Outside the sketch a
profile still goes only with its sketch.

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

* Delete a picked letter's whole text, not just its outline (#7107)

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 23:04:41 +00:00
bherbruck 03b8f4138b New designs save as .sc; .solidcraft files still open (#7325)
* claim: new designs save as .sc

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

* New designs save as .sc; .solidcraft files still open and keep their name on Save

DESIGN_EXT is now "sc"; DESIGN_EXTS lists sc, solidcraft and solvecraft and
every open path (dialogs, drag-drop, recent files, CLI, MCP, links, the web
picker) accepts all three. Save of an opened .solidcraft file writes that
file; Save As, autosave, recovery and crash reports use .sc. Windows, macOS
and Linux register .sc alongside the older extensions.

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

* Update UI tests for the .sc default extension

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 22:41:40 +00:00
github-actions[bot] 613b468ef5 Regenerate generated files and fold pending files [skip ci] 2026-10-27 22:58:37 +00:00
yhamil04 c0a0da225a Ribbon tooltips: help for the Solid > Modify tools, and new toolbar commands must have it (#2758) (#7134)
* Ribbon tooltips: help for the Solid > Modify tools; new toolbar commands need it (#2758)

Writes the two-sentence help for the 16 Modify tools that had none (en, fr,
ja, zh), and adds a test that fails when a toolbar command has no help; the
190 older ones are on a backlog that only shrinks. AGENTS.md, CONTRIBUTING.md
and the Adding a command guide say so.

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

* Ribbon tooltips: the help test reads the ribbon as the toolbar lays it out (#2758)

Review: commands placed by a workspace section without .at(...) were not
checked; 79 of them join the backlog. Physical Material's help no longer
promises the centre of mass.

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

* Ribbon tooltips: French help uses the glossary terms (#2758)

Matériau, Apparence and Scinder, as rlartot asked in review; Delete Face
says the hole stays open.

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

* Ribbon tooltips: the help rule fits the commands skill's size limit (#2758)

AGENTS.md became a router to skills on main, so the rule lives in
skills/solidcraft-commands/SKILL.md, kept under its 3600-character limit.

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

* Ribbon tooltips: Arabic, Hebrew and Vietnamese help; the backlog follows main (#2758)

Arabic, Hebrew and Vietnamese are complete catalogs now, so the 16 texts
come in those too. Twelve toolbar commands that landed before the rule
join the backlog; the Render commands, which left the ribbon, leave it.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 22:30:15 +00:00
607 changed files with 137632 additions and 3680 deletions
+3
View File
@@ -1,3 +1,6 @@
# Preserve canonical source receipts and the runtime icon-discovery snapshot.
.gitattributes text eol=lf
/assets/icons/ui/design/requested_icons.txt text eol=lf
# SolidCraft designs (.sc): a JSON document or a ZIP container, never Scala source, so they
# stay out of GitHub's language statistics. Git's own text/binary detection handles both kinds.
*.sc -linguist-detectable
+1 -1
View File
@@ -19,7 +19,7 @@ body:
attributes:
label: Steps to reproduce
description: |
What you clicked or typed, in order. For a problem on a particular design, `solidcraft-cli script design.solidcraft --out repro.json` turns its history into a script that `solidcraft-cli eval repro.json` replays; attach it, trimmed to the failing step if you can.
What you clicked or typed, in order. For a problem on a particular design, `solidcraft-cli script design.sc --out repro.json` turns its history into a script that `solidcraft-cli eval repro.json` replays; attach it, trimmed to the failing step if you can.
Using an AI agent with SolidCraft's MCP server? The `solidcraft-reporting` skill in [`skills/`](https://github.com/tangency-labs/solidcraft/tree/main/skills) has it reproduce the problem in a fresh design and write these steps for you.
placeholder: |
1. Sketch a circle on the XY plane
+21
View File
@@ -429,6 +429,20 @@ Original SolidCraft drawings, Open for owner review; no runtime assignments.
| assets/icons/ui/design/svg/model/status_recovery.svg | SolidCraft contributors | original icon master (64 grid) | MIT OR Apache-2.0 |
| assets/icons/ui/design/svg/model/frame_member.svg | SolidCraft contributors | original icon master (64 grid) | MIT OR Apache-2.0 |
| assets/icons/ui/design/svg/model/render_environment.svg | SolidCraft contributors | original Studio icon master (64 grid): dome with a grey cube inside | MIT OR Apache-2.0 |
| assets/icons/ui/design/svg/flat/style_shaded.svg | SolidCraft contributors | original icon master (64 grid) | MIT OR Apache-2.0 |
| assets/icons/ui/design/svg/flat/style_wireframe.svg | SolidCraft contributors | original icon master (64 grid) | MIT OR Apache-2.0 |
| assets/icons/ui/design/svg/flat/style_hidden_edges.svg | SolidCraft contributors | original icon master (64 grid) | MIT OR Apache-2.0 |
| assets/icons/ui/design/svg/flat/style_translucent.svg | SolidCraft contributors | original icon master (64 grid) | MIT OR Apache-2.0 |
| assets/icons/ui/design/svg/flat/select_faces_edges.svg | SolidCraft contributors | original icon master (64 grid) | MIT OR Apache-2.0 |
| assets/icons/ui/design/svg/flat/select_bodies.svg | SolidCraft contributors | original icon master (64 grid) | MIT OR Apache-2.0 |
| assets/icons/ui/design/svg/flat/select_features.svg | SolidCraft contributors | original icon master (64 grid) | MIT OR Apache-2.0 |
| assets/icons/ui/design/svg/flat/select_parts.svg | SolidCraft contributors | original icon master (64 grid) | MIT OR Apache-2.0 |
| assets/icons/ui/design/svg/flat/select_components.svg | SolidCraft contributors | original icon master (64 grid) | MIT OR Apache-2.0 |
| assets/icons/ui/design/svg/flat/select_sketch.svg | SolidCraft contributors | original icon master (64 grid) | MIT OR Apache-2.0 |
| assets/icons/ui/design/svg/flat/display.svg | SolidCraft contributors | original icon master (64 grid) | MIT OR Apache-2.0 |
| assets/icons/ui/design/svg/flat/grid.svg | SolidCraft contributors | original icon master (64 grid) | MIT OR Apache-2.0 |
| assets/icons/ui/design/svg/flat/ground_shadow.svg | SolidCraft contributors | original icon master (64 grid) | MIT OR Apache-2.0 |
| assets/icons/ui/design/svg/flat/ambient_occlusion.svg | SolidCraft contributors | original icon master (64 grid) | MIT OR Apache-2.0 |
| assets/icons/ui/design/svg/model/placeholder.svg | SolidCraft contributors | two-tone modelling icon master (64 grid), original SolidCraft artwork | MIT OR Apache-2.0 |
| assets/icons/ui/design/svg/model/plane.svg | SolidCraft contributors | two-tone modelling icon master (64 grid), original SolidCraft artwork | MIT OR Apache-2.0 |
| assets/icons/ui/design/svg/model/plane_angle.svg | SolidCraft contributors | two-tone modelling icon master (64 grid), original SolidCraft artwork | MIT OR Apache-2.0 |
@@ -581,6 +595,13 @@ Original SolidCraft drawings, Open for owner review; no runtime assignments.
| assets/styles/ui/themes/cga.json | SolidCraft contributors | original SolidCraft theme file using the 16 colours of the IBM Color Graphics Adapter (black, cyan, magenta, and white of its high-intensity palette 1 for the interface) | MIT OR Apache-2.0 |
| assets/styles/ui/themes/1-bit.json | SolidCraft contributors | original SolidCraft theme file | MIT OR Apache-2.0 |
| assets/styles/ui/themes/1-bit-dark.json | SolidCraft contributors | original SolidCraft theme file | MIT OR Apache-2.0 |
| `assets/locales/pending/navbar-customisation.json` | SolidCraft contributors | Original navigation bar editor translations | MIT OR Apache-2.0 |
| `assets/locales/pending/navbar-slots.json` | SolidCraft contributors | Original navigation slot translations | MIT OR Apache-2.0 |
| assets/locales/bs.json | Tarik Sijercic (tsijercic1) | Original Bosnian translation of SolidCraft's English catalog; no commercial CAD text used | MIT OR Apache-2.0 |
| assets/locales/hr.json | Tarik Sijercic (tsijercic1) | Original Croatian translation of SolidCraft's English catalog; no commercial CAD text used | MIT OR Apache-2.0 |
| assets/locales/sr.json | Tarik Sijercic (tsijercic1) | Original Serbian (ekavian, Cyrillic) translation of SolidCraft's English catalog; no commercial CAD text used | MIT OR Apache-2.0 |
| assets/icons/ui/design/svg/model/finish_edit.svg | SolidCraft contributors | original icon master (64 grid) | MIT OR Apache-2.0 |
| `assets/locales/pending/sketch-tracking-guides.json` | SolidCraft contributors | Original alignment-guide preference labels and help text | MIT OR Apache-2.0 |
## Code adapted from sibling projects
+10 -1
View File
@@ -136,6 +136,7 @@ The [architecture page](docs/architecture.md) has the layer table. The short ver
[Adding a command](docs/book/src/dev/commands.md#adding-a-command); a test warns about a
command without them, and will fail it once required), engine tests that measure the result (volume, area,
face/edge/vertex counts against a value you can derive), and for UI work a scenario (below).
A command on the toolbar also ships with its help tooltip (step 6 of Adding a command).
6. **One set of camera controls.** Every page or canvas that shows a view (the modelling
viewport, the Render preview, and any new page such as a flat pattern or drawing) calls
`navigation::handle` (`crates/ui-egui/src/navigation.rs`) for its camera input, with
@@ -267,7 +268,9 @@ a conflict. `crates/doc/src/format/pending/README.md` has an example.
**At release time** the maintainer runs `scripts/fold-format-pending.sh`, which moves the pending
files into `crates/doc/src/format/v<N>/` and fixes that number for good (see
[docs/releasing.md](docs/releasing.md)). Never add a file to a `v<N>/` folder afterwards.
[docs/releasing.md](docs/releasing.md)). Never add a file to a `v<N>/` folder afterwards. Drawings
follow the same rules with their own numbers, from 1, in `crates/doc/src/drawing/format/` (see its
`pending/README.md`), and the same script folds them.
## Lists many changes add to
@@ -283,6 +286,12 @@ and a fresh CI run:
- **Commands without schemas** (`crates/engine/src/schema/unconverted.txt`): sorted, one id per
line, and it only shrinks. Converting a command removes its line; a new command is never added
to it.
- **Toolbar commands without help** (`BACKLOG` in `crates/ui-egui/src/command_help.rs`): sorted,
one id per line, and it only shrinks. Writing a command's help removes its line; a new command
is never added to it.
- **`ui.prefs` settings** (`docs/control-protocol.md`): one line per setting, sorted by name, in
the list under the protocol table; add a new setting on its own line rather than editing a shared
row.
- **Languages** (`crates/ui-egui/src/i18n.rs`): one per line, English first, then by id (a test
checks it).
- **Generated files**: `THIRD-PARTY-LICENSES.txt` and `docs/features.md` are rewritten on `main`
Generated
+18 -17
View File
@@ -4208,7 +4208,7 @@ dependencies = [
[[package]]
name = "solidcraft"
version = "0.25.0"
version = "0.25.1"
dependencies = [
"block2 0.6.2",
"eframe",
@@ -4238,15 +4238,16 @@ dependencies = [
"ureq",
"windows-sys 0.61.2",
"winit",
"x11rb",
]
[[package]]
name = "solidcraft-3dx-client"
version = "0.25.0"
version = "0.25.1"
[[package]]
name = "solidcraft-cli"
version = "0.25.0"
version = "0.25.1"
dependencies = [
"image",
"log",
@@ -4258,7 +4259,7 @@ dependencies = [
[[package]]
name = "solidcraft-derive"
version = "0.25.0"
version = "0.25.1"
dependencies = [
"proc-macro2",
"quote",
@@ -4267,7 +4268,7 @@ dependencies = [
[[package]]
name = "solidcraft-doc"
version = "0.25.0"
version = "0.25.1"
dependencies = [
"log",
"serde",
@@ -4284,7 +4285,7 @@ dependencies = [
[[package]]
name = "solidcraft-engine"
version = "0.25.0"
version = "0.25.1"
dependencies = [
"image",
"log",
@@ -4305,7 +4306,7 @@ dependencies = [
[[package]]
name = "solidcraft-geom"
version = "0.25.0"
version = "0.25.1"
dependencies = [
"serde",
"serde_json",
@@ -4314,7 +4315,7 @@ dependencies = [
[[package]]
name = "solidcraft-gpu"
version = "0.25.0"
version = "0.25.1"
dependencies = [
"image",
"log",
@@ -4334,7 +4335,7 @@ dependencies = [
[[package]]
name = "solidcraft-io"
version = "0.25.0"
version = "0.25.1"
dependencies = [
"cadmpeg-core",
"cadmpeg-ir",
@@ -4358,7 +4359,7 @@ dependencies = [
[[package]]
name = "solidcraft-kernel"
version = "0.25.0"
version = "0.25.1"
dependencies = [
"log",
"proptest",
@@ -4378,7 +4379,7 @@ dependencies = [
[[package]]
name = "solidcraft-mcp"
version = "0.25.0"
version = "0.25.1"
dependencies = [
"serde_json",
"solidcraft-engine",
@@ -4387,7 +4388,7 @@ dependencies = [
[[package]]
name = "solidcraft-render"
version = "0.25.0"
version = "0.25.1"
dependencies = [
"image",
"moxcms",
@@ -4401,7 +4402,7 @@ dependencies = [
[[package]]
name = "solidcraft-sketch"
version = "0.25.0"
version = "0.25.1"
dependencies = [
"serde",
"serde_json",
@@ -4412,14 +4413,14 @@ dependencies = [
[[package]]
name = "solidcraft-space-mouse"
version = "0.25.0"
version = "0.25.1"
dependencies = [
"serde",
]
[[package]]
name = "solidcraft-ui-egui"
version = "0.25.0"
version = "0.25.1"
dependencies = [
"arboard",
"egui",
@@ -4449,7 +4450,7 @@ dependencies = [
[[package]]
name = "solidcraft-web"
version = "0.25.0"
version = "0.25.1"
dependencies = [
"eframe",
"egui",
@@ -5994,7 +5995,7 @@ checksum = "e450f9b2ed1dff33c94c12589a87338689467b9c4f5d8a5710bd09a847d2c8a7"
[[package]]
name = "xtask"
version = "0.25.0"
version = "0.25.1"
dependencies = [
"proc-macro2",
"serde",
+1 -1
View File
@@ -5,7 +5,7 @@ members = ["crates/*", "apps/*", "xtask"]
exclude = ["vendor"]
[workspace.package]
version = "0.25.0"
version = "0.25.1"
edition = "2024"
license = "MIT OR Apache-2.0"
rust-version = "1.95"
+1 -1
View File
@@ -74,7 +74,7 @@ other is a tracked bug.
- **Parameters and configurations** with unit-aware expressions.
- **Assemblies** with joints, motion studies, contact sets, interference and mass properties.
- **Sheet metal** with flanges, hems, fold/unfold and flat patterns, and plastic enclosure features.
- **Files:** STEP, IGES, 3MF, STL, OBJ and glTF in and out where supported, URDF export, `.solidcraft` designs.
- **Files:** STEP, IGES, 3MF, STL, OBJ and glTF in and out where supported, URDF export, `.sc` designs (`.solidcraft` files from earlier releases still open).
- **Desktop app, browser app, headless CLI and MCP server**, all running the same commands.
The full list is in [docs/capabilities.md](docs/capabilities.md) and [docs/features.md](docs/features.md);
@@ -68,7 +68,7 @@ fn run() -> Result<(), String> {
let generation_start = Instant::now();
let (commands, command_timings) = session.run_script_timed(&recipe, false).map_err(|e| e.to_string())?;
let generation_seconds = generation_start.elapsed().as_secs_f64();
let design_path = output.with_extension("solidcraft");
let design_path = output.with_extension(solidcraft_engine::io::DESIGN_EXT);
session.execute("file.save_as", &json!({"path":design_path})).map_err(|e| e.to_string())?;
let scene = solidcraft_engine::product_scene::extract(&session).map_err(|e| e.to_string())?;
let bodies: Vec<Value> = scene
+5 -2
View File
@@ -8,7 +8,7 @@
//! no fixture.
//!
//! ```text
//! solidcraft-cli bench-agent [--scale F] [--script-out script.json] [--save design.solidcraft]
//! solidcraft-cli bench-agent [--scale F] [--script-out script.json] [--save design.sc]
//! ```
//! prints one JSON line per hundred commands (mean and max milliseconds, bodies so far), then the
//! build total, then the phases `bench-open` prints for the saved design.
@@ -205,7 +205,10 @@ pub fn run(args: &[String]) -> Result<(), String> {
);
let path = match flag("--save") {
Some(p) => p.clone(),
None => std::env::temp_dir().join(format!("bench-agent-{}.solidcraft", std::process::id())).to_string_lossy().into_owned(),
None => std::env::temp_dir()
.join(format!("bench-agent-{}.{}", std::process::id(), solidcraft_engine::io::DESIGN_EXT))
.to_string_lossy()
.into_owned(),
};
s.execute("file.save", &json!({"path": path})).map_err(|e| e.to_string())?;
let r = crate::cmd_bench_open(std::slice::from_ref(&path));
+15 -15
View File
@@ -1,10 +1,10 @@
//! SolidCraft headless command line.
//!
//! ```text
//! solidcraft-cli run <script.json|design.solidcraft|part.step|mesh.3mf> [--in design|part.step|mesh.3mf] [--out FILE]... [--save FILE] [--quiet] [--results] [--timings] [--profile] [--json-out FILE] [--allow-errors]
//! solidcraft-cli eval <script.json|design.solidcraft|part.step> [--in design.solidcraft|part.step] [--json-out FILE] (alias: inspect) measurements as JSON
//! solidcraft-cli script <design.solidcraft> [--out script.json] the design's history as a command script
//! solidcraft-cli bench-open <design.solidcraft | part.step> [--parse-only] [--save OUT.solidcraft] [--display LEVEL [--edit NAME EXPR]] [--ops script.json] loading timings as JSON lines
//! solidcraft-cli run <script.json|design.sc|part.step|mesh.3mf> [--in design|part.step|mesh.3mf] [--out FILE]... [--save FILE] [--quiet] [--results] [--timings] [--profile] [--json-out FILE] [--allow-errors]
//! solidcraft-cli eval <script.json|design.sc|part.step> [--in design.sc|part.step] [--json-out FILE] (alias: inspect) measurements as JSON
//! solidcraft-cli script <design.sc> [--out script.json] the design's history as a command script
//! solidcraft-cli bench-open <design.sc | part.step> [--parse-only] [--save OUT.sc] [--display LEVEL [--edit NAME EXPR]] [--ops script.json] loading timings as JSON lines
//! solidcraft-cli bench-agent [--scale F] [--save F] [--script-out F] a ~1,300-body design built command by command, timed
//! solidcraft-cli bench-assistant --connect 127.0.0.1:PORT [--token T] --base-url URL --model NAME [--tasks 1,2,5] [--repeat N]
//! [--timeout-s 300] [--json out.json] [--markdown out.md]
@@ -56,19 +56,19 @@ struct Command {
}
/// `run`'s lines in the usage.
const USAGE_RUN: &str = " solidcraft-cli run <script.json|design.solidcraft|part.step> [--in design.solidcraft|part.step] [--out FILE]... [--save FILE] [--quiet] [--results] [--timings] [--profile] [--json-out FILE] [--allow-errors]\n solidcraft-cli run --in <design.solidcraft|part.step> [--out FILE]...\n (a timeline feature that fails fails the run and nothing is written; --allow-errors writes anyway)\n (--timings prints {timings: [{index, command, ms}], total_ms} for a script, with --results its results too;\n --profile adds each command's profile: {boolean_ms, tessellate_ms, other_ms}, the kernel's share)\n";
const USAGE_RUN: &str = " solidcraft-cli run <script.json|design.sc|part.step> [--in design.sc|part.step] [--out FILE]... [--save FILE] [--quiet] [--results] [--timings] [--profile] [--json-out FILE] [--allow-errors]\n solidcraft-cli run --in <design.sc|part.step> [--out FILE]...\n (a timeline feature that fails fails the run and nothing is written; --allow-errors writes anyway)\n (--timings prints {timings: [{index, command, ms}], total_ms} for a script, with --results its results too;\n --profile adds each command's profile: {boolean_ms, tessellate_ms, other_ms}, the kernel's share)\n";
/// `eval`'s lines in the usage.
const USAGE_EVAL: &str = " solidcraft-cli eval <script.json|design.solidcraft|part.step> [--in design.solidcraft|part.step] [--json-out FILE] (alias: inspect)\n solidcraft-cli eval --in <script.json|design.solidcraft|part.step> [--json-out FILE]\n (with both inputs, runs the positional script on --in before measuring; does not automatically save the modified design)\n (--json-out FILE writes the JSON that run (with --results, else the measurement) and eval print to FILE instead of stdout,\n as plain UTF-8: a shell's > can re-encode it, e.g. Windows PowerShell adds a byte-order mark)\n";
const USAGE_EVAL: &str = " solidcraft-cli eval <script.json|design.sc|part.step> [--in design.sc|part.step] [--json-out FILE] (alias: inspect)\n solidcraft-cli eval --in <script.json|design.sc|part.step> [--json-out FILE]\n (with both inputs, runs the positional script on --in before measuring; does not automatically save the modified design)\n (--json-out FILE writes the JSON that run (with --results, else the measurement) and eval print to FILE instead of stdout,\n as plain UTF-8: a shell's > can re-encode it, e.g. Windows PowerShell adds a byte-order mark)\n";
/// `script`'s lines in the usage.
const USAGE_SCRIPT: &str = " solidcraft-cli script <design.solidcraft|script.json> [--out script.json]\n (the design's history as a command script that eval and run replay)\n";
const USAGE_SCRIPT: &str = " solidcraft-cli script <design.sc|script.json> [--out script.json]\n (the design's history as a command script that eval and run replay)\n";
/// `bench-open`'s lines in the usage.
const USAGE_BENCH_OPEN: &str = " solidcraft-cli bench-open <design.solidcraft | part.step> [--parse-only] [--save OUT.solidcraft] [--display LEVEL [--edit NAME EXPR]] [--ops script.json]\n (--ops: after opening, run each command of the script and undo it, timing the command, the\n evaluations it caused and the view it leaves: placing and meshing what changed)\n";
const USAGE_BENCH_OPEN: &str = " solidcraft-cli bench-open <design.sc | part.step> [--parse-only] [--save OUT.sc] [--display LEVEL [--edit NAME EXPR]] [--ops script.json]\n (--ops: after opening, run each command of the script and undo it, timing the command, the\n evaluations it caused and the view it leaves: placing and meshing what changed)\n";
/// `bench-agent`'s lines in the usage.
const USAGE_BENCH_AGENT: &str = " solidcraft-cli bench-agent [--scale F] [--save design.solidcraft] [--script-out script.json]\n";
const USAGE_BENCH_AGENT: &str = " solidcraft-cli bench-agent [--scale F] [--save design.sc] [--script-out script.json]\n";
/// `bench-assistant`'s lines in the usage.
const USAGE_BENCH_ASSISTANT: &str = " solidcraft-cli bench-assistant --connect 127.0.0.1:PORT [--token T] --base-url URL --model NAME [--tasks 1,2,5] [--repeat N] [--timeout-s 300] [--json out.json] [--markdown out.md]\n";
/// `snapshot`'s lines in the usage.
const USAGE_SNAPSHOT: &str = " solidcraft-cli snapshot <script|design> [--in design.solidcraft|part.step] --out shot.png [--width W] [--height H] [--view NAME | --camera JSON] [--no-grid] [--no-axes]\n [--body NAME:opacity=0.3,color=#rrggbb]... [--tool NAME]... [--section z=27]\n solidcraft-cli snapshot --in <design.solidcraft|part.step> --out shot.png ...\n (as with run, --in starts from a design and the script runs on top of it; an option snapshot doesn't take is an error;\n --view: iso, front, back, top, bottom, left, right, or the name of a view saved in the design with view.save;\n --camera: {target: [x,y,z], yaw, pitch, distance, fov?} in mm and radians, as the MCP screenshot takes it (docs/mcp.md);\n --no-grid and --no-axes leave the ground grid (on Z 0) and the origin's axes out of the picture;\n --body: how one body is drawn, as appearance.assign takes it: opacity 0-1 (below 1 is see-through, so what is inside\n it shows) and color #rrggbb, either or both, once per body;\n --tool: draw this body solid in the tool colour and every other body see-through, so a cut's or a join's tool body\n is visible inside the material it meets; a later --body overrides it;\n --section: cut the model as inspect.section does, so the inside shows: z=27 (the plane through that world\n coordinate, keeping the smaller side), add ,flip to keep the other side, or XY, XZ, YZ, or its own JSON)\n";
const USAGE_SNAPSHOT: &str = " solidcraft-cli snapshot <script|design> [--in design.sc|part.step] --out shot.png [--width W] [--height H] [--view NAME | --camera JSON] [--no-grid] [--no-axes]\n [--body NAME:opacity=0.3,color=#rrggbb]... [--tool NAME]... [--section z=27]\n solidcraft-cli snapshot --in <design.sc|part.step> --out shot.png ...\n (as with run, --in starts from a design and the script runs on top of it; an option snapshot doesn't take is an error;\n --view: iso, front, back, top, bottom, left, right, or the name of a view saved in the design with view.save;\n --camera: {target: [x,y,z], yaw, pitch, distance, fov?} in mm and radians, as the MCP screenshot takes it (docs/mcp.md);\n --no-grid and --no-axes leave the ground grid (on Z 0) and the origin's axes out of the picture;\n --body: how one body is drawn, as appearance.assign takes it: opacity 0-1 (below 1 is see-through, so what is inside\n it shows) and color #rrggbb, either or both, once per body;\n --tool: draw this body solid in the tool colour and every other body see-through, so a cut's or a join's tool body\n is visible inside the material it meets; a later --body overrides it;\n --section: cut the model as inspect.section does, so the inside shows: z=27 (the plane through that world\n coordinate, keeping the smaller side), add ,flip to keep the other side, or XY, XZ, YZ, or its own JSON)\n";
/// `render`'s lines in the usage.
const USAGE_RENDER: &str = " solidcraft-cli render <script|design> --out image.png [--setup NAME] [--width W] [--height H] [--transparent] [--overwrite] [--timeout SECONDS]\n [--progressive] [--samples N] [--max-depth N] [--seed N] [--exposure EV] [--lighting FILE.json] [--environment FILE.json] [--tone-map reinhard|aces_fitted]\n";
/// `exec`'s lines in the usage.
@@ -83,7 +83,7 @@ const USAGE_ORACLE: &str = " solidcraft-cli oracle <case-dir>... [--json]\n";
const USAGE_FUZZ: &str =
" solidcraft-cli fuzz [--from N] [--count N] [--jobs J] [--timeout S] [--steps N] [--minimise] [--out DIR] [--report FILE]\n";
/// `mcp`'s lines in the usage.
const USAGE_MCP: &str = " solidcraft-cli mcp [--headless] [--in design.solidcraft|script.json] [--connect 127.0.0.1:PORT [--token T]] [--allow-path DIR]... [--allow-any-path]\n [--param-check off|warn|strict] [--render-gpu]\n solidcraft-cli mcp setup [--dry-run] [--client opencode|claude-desktop|claude-code|cursor] [--live]\n (adds a `solidcraft` server, with this program's path, to each installed AI client; --live adds `solidcraft-live` for the running app; alias: mcp install)\n";
const USAGE_MCP: &str = " solidcraft-cli mcp [--headless] [--in design.sc|script.json] [--connect 127.0.0.1:PORT [--token T]] [--allow-path DIR]... [--allow-any-path]\n [--param-check off|warn|strict] [--render-gpu]\n solidcraft-cli mcp setup [--dry-run] [--client opencode|claude-desktop|claude-code|cursor] [--live]\n (adds a `solidcraft` server, with this program's path, to each installed AI client; --live adds `solidcraft-live` for the running app; alias: mcp install)\n";
/// `crashes`'s lines in the usage.
const USAGE_CRASHES: &str = " solidcraft-cli crashes [list [--json] | show <id> | replay <id> | dir | clear [<id>]]\n";
/// `licences`'s lines in the usage.
@@ -653,7 +653,7 @@ fn cmd_mcp(args: &[String]) -> Result<(), String> {
if let Some(s) = &scope {
let roots: Vec<String> = s.roots().iter().map(|r| r.display().to_string()).collect();
eprintln!(
"solidcraft mcp: files limited to {} and the open design's folder (--allow-path DIR adds one, --allow-any-path lifts the limit)",
"solidcraft mcp: files limited to {} and the folders of designs opened or saved here (--allow-path DIR adds one, --allow-any-path lifts the limit)",
roots.join(", ")
);
let design_dir = flag(args, "--in")
@@ -817,7 +817,7 @@ fn bench_ops(mut s: Session, script: &str) -> Result<Session, String> {
/// Separate file reading, JSON decoding/repair, timeline evaluation and display meshing.
pub(crate) fn cmd_bench_open(args: &[String]) -> Result<(), String> {
let path = args.first().ok_or("usage: solidcraft-cli bench-open <design.solidcraft | part.step> [--parse-only]")?;
let path = args.first().ok_or("usage: solidcraft-cli bench-open <design.sc | part.step> [--parse-only]")?;
let t = std::time::Instant::now();
let step = solidcraft_engine::io::is_step_path(path);
let limit = if step { solidcraft_engine::io::MAX_STEP_BYTES } else { solidcraft_engine::io::MAX_DESIGN_BYTES };
@@ -863,13 +863,13 @@ pub(crate) fn cmd_bench_open(args: &[String]) -> Result<(), String> {
json!({"step": "mesh", "ms": t.elapsed().as_secs_f64() * 1000.0, "place_ms": place_ms, "bodies": st.bodies.len(), "triangles": triangles})
);
let flag = |name: &str| args.iter().position(|a| a == name);
// `--save PATH`: save the opened design without its model cache (to PATH.plain.solidcraft) and
// `--save PATH`: save the opened design without its model cache (to PATH.plain.sc) and
// as the app does, with it, then read the cache back.
let s = match flag("--save").and_then(|i| args.get(i + 1)) {
Some(out) => {
let mut s = s;
// Without the cache first, for comparison.
let plain = format!("{out}.plain.solidcraft");
let plain = format!("{out}.plain.{}", solidcraft_engine::io::DESIGN_EXT);
let t = std::time::Instant::now();
s.execute("file.save_as", &json!({"path": plain, "cache": false})).map_err(|e| e.to_string())?;
let plain_ms = t.elapsed().as_secs_f64() * 1000.0;
+3 -3
View File
@@ -92,7 +92,7 @@ fn designs() -> Vec<(String, PathBuf)> {
add("regressions", root.join("examples/regressions"), "json");
add("demo", root.join("examples/demo"), "json");
add("typical", root.join("tests/action_matrix/designs"), "json");
add("demo", root.join("tests/action_matrix/designs"), "solidcraft");
add("demo", root.join("tests/action_matrix/designs"), solidcraft_engine::io::DESIGN_EXT);
let mut cases: Vec<PathBuf> =
std::fs::read_dir(root.join("tests/oracle")).unwrap().flatten().map(|e| e.path()).filter(|p| p.join("recipe.json").is_file()).collect();
cases.sort();
@@ -105,7 +105,7 @@ fn designs() -> Vec<(String, PathBuf)> {
/// Build a design from its file.
fn load(path: &Path) -> Result<Session, String> {
let mut s = Session::default();
if path.extension().is_some_and(|x| x == "solidcraft") {
if solidcraft_engine::io::is_design_container_path(path) {
s.execute("doc.open", &json!({"path": path.to_string_lossy()})).map_err(|e| e.to_string())?;
return Ok(s);
}
@@ -1558,7 +1558,7 @@ fn sketches_on_loft_and_sweep_faces() {
#[test]
fn press_pull_on_the_pi_case_floor() {
reproduces(
Some("tests/action_matrix/designs/pi-case.solidcraft"),
Some("tests/action_matrix/designs/pi-case.sc"),
json!([{"command": "solid.press_pull", "params": {"face": [30, 20, 0], "distance": 1}}]),
);
}
@@ -75,12 +75,15 @@ fn designs() -> Vec<(String, Session)> {
.unwrap()
.flatten()
.map(|e| e.path())
.filter(|p| p.extension().is_some_and(|x| x == "solidcraft" || x == "json") && !p.to_string_lossy().ends_with(".expected.json"))
.filter(|p| {
(solidcraft_engine::io::is_design_container_path(p) || p.extension().is_some_and(|x| x == "json"))
&& !p.to_string_lossy().ends_with(".expected.json")
})
.collect();
files.sort();
for p in files {
let name = p.file_stem().unwrap_or_default().to_string_lossy().to_string();
let s = if p.extension().is_some_and(|x| x == "solidcraft") {
let s = if solidcraft_engine::io::is_design_container_path(&p) {
open(&p)
} else {
let mut s = Session::default();
@@ -150,7 +153,7 @@ fn pi_case_faces_per_step_at_both_heights() {
const FACES: [(usize, usize); 13] =
[(2, 6), (3, 10), (4, 19), (5, 19), (6, 25), (7, 43), (8, 43), (9, 55), (10, 55), (11, 59), (12, 59), (13, 63), (14, 79)];
let dir = scratch_dir("pi");
let design: Value = serde_json::from_slice(&std::fs::read(root().join("tests/action_matrix/designs/pi-case.solidcraft")).unwrap()).unwrap();
let design: Value = serde_json::from_slice(&std::fs::read(root().join("tests/action_matrix/designs/pi-case.sc")).unwrap()).unwrap();
let at = |height: &str, file: &str| {
let mut d = design.clone();
for p in d["params"].as_array_mut().unwrap() {
+6 -1
View File
@@ -145,7 +145,7 @@ fn eval_and_inspect_reject_invalid_options_before_script_execution_or_reporting(
#[test]
fn cli_loads_both_design_encodings_by_contents() {
let dir = Scratch::new();
for extension in ["solidcraft", "solvecraft", "json"] {
for extension in ["sc", "solidcraft", "solvecraft", "json"] {
let saved = dir.0.join(format!("box.{extension}"));
json_output(cli().arg("run").arg(dir.script()).arg("--save").arg(&saved).output().unwrap());
let bytes = std::fs::read(&saved).unwrap();
@@ -412,6 +412,11 @@ fn legacy_extension_and_format_tag_still_open() {
assert_eq!(body_count(&resaved), 2);
let reopened = solidcraft_engine::io::read_design(&std::fs::read(&resaved).unwrap()).unwrap();
assert!(reopened.to_json().contains("\"solidcraft/"));
// `.solidcraft` (before `.sc`) opens as `--in` and as the design to evaluate; `.sc` too.
let current = dir.0.join("current.sc");
json_output(cli().args(["run", "--in"]).arg(&resaved).arg(dir.script()).arg("--save").arg(&current).output().unwrap());
assert_eq!(body_count(&current), 3);
assert!(solidcraft_engine::io::is_design_container(&std::fs::read(&current).unwrap()), "a .sc file is a design container");
}
/// `snapshot` starts from `--in` as `run` does (its script runs on that design), and refuses an
@@ -1,5 +1,5 @@
//! Straight edges stay one edge after many cuts (#1049). The owner's design
//! (`tests/action_matrix/designs/crazy-geom-cuts.solidcraft`, saved by 0.10.0): five extrudes,
//! (`tests/action_matrix/designs/crazy-geom-cuts.sc`, saved by 0.10.0): five extrudes,
//! joins and cuts, over four sketches, three of them on faces of the body with the faces'
//! edges projected. Cuts used to leave the straight edges of the walls they sliced split at
//! vertices nothing else used, so an edge that is one straight line was drawn (and lit on hover)
@@ -14,7 +14,7 @@ use solidcraft_engine::doc::kernel::{FaceSurface, face_surface};
use solidcraft_engine::geom::Vec3;
fn design() -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR")).join("../../tests/action_matrix/designs/crazy-geom-cuts.solidcraft")
Path::new(env!("CARGO_MANIFEST_DIR")).join("../../tests/action_matrix/designs/crazy-geom-cuts.sc")
}
fn open(path: &Path) -> Session {
+18 -8
View File
@@ -169,10 +169,15 @@ pub fn upload_limit(extensions: &[&str]) -> Option<usize> {
(!extensions.is_empty() && extensions.iter().all(image)).then_some(solidcraft_engine::doc::canvas::MAX_CANVAS_BYTES)
}
/// The file type a Save As dialog offers for `name`: (description, MIME type, extension).
pub fn save_type(name: &str) -> (&'static str, &'static str, &'static str) {
let json = std::path::Path::new(name).extension().is_some_and(|e| e.eq_ignore_ascii_case("json"));
if json { ("Plain JSON design", "application/json", ".json") } else { ("SolidCraft design", "application/octet-stream", ".solidcraft") }
/// The file type a Save As dialog offers for `name`: (description, MIME type, extension). A
/// design is `.sc` unless the name already has an older design extension, which it keeps.
pub fn save_type(name: &str) -> (&'static str, &'static str, String) {
let ext = std::path::Path::new(name).extension().and_then(|e| e.to_str()).map(str::to_ascii_lowercase);
match ext.as_deref() {
Some("json") => ("Plain JSON design", "application/json", ".json".into()),
Some(e) if solidcraft_engine::io::is_design_ext(e) => ("SolidCraft design", "application/octet-stream", format!(".{e}")),
_ => ("SolidCraft design", "application/octet-stream", format!(".{}", solidcraft_engine::io::DESIGN_EXT)),
}
}
/// Is this a cancelled dialog (the browser's `AbortError`)? Not an error to show.
@@ -264,7 +269,7 @@ mod web {
let options = Object::new();
let _ = Reflect::set(&options, &"suggestedName".into(), &name.into());
let (description, mime, extension) = save_type(name);
let _ = Reflect::set(&options, &"types".into(), &types(description, mime, extension));
let _ = Reflect::set(&options, &"types".into(), &types(description, mime, &extension));
options
}
@@ -349,7 +354,9 @@ mod web {
let options = Object::new();
let _ = Reflect::set(&options, &"multiple".into(), &JsValue::FALSE);
let extensions = Array::new();
for e in [".solidcraft", ".solvecraft", ".json", ".step", ".stp", ".3mf", ".stl", ".obj", ".glb", ".gltf", ".fcstd", ".3dm", ".dxf", ".svg"] {
let designs = solidcraft_engine::io::DESIGN_EXTS.iter().map(|e| format!(".{e}"));
let others = [".json", ".step", ".stp", ".3mf", ".stl", ".obj", ".glb", ".gltf", ".fcstd", ".3dm", ".dxf", ".svg"].map(String::from);
for e in designs.chain(others) {
extensions.push(&e.into());
}
let accept = Object::new();
@@ -667,6 +674,7 @@ mod tests {
#[test]
fn only_design_opens_use_the_disk_dialog() {
assert!(opens_design(&[]));
assert!(opens_design(&["sc"]));
assert!(opens_design(&["solidcraft"]));
assert!(opens_design(&["solvecraft"]));
assert!(!opens_design(&["step", "stp"]));
@@ -710,9 +718,11 @@ mod tests {
#[test]
fn the_save_dialog_offers_the_type_of_the_name() {
assert_eq!(save_type("Plate.solidcraft").2, ".solidcraft");
assert_eq!(save_type("Plate.sc").2, ".sc");
assert_eq!(save_type("Plate.JSON").2, ".json");
assert_eq!(save_type("Plate").2, ".solidcraft");
assert_eq!(save_type("Plate").2, ".sc");
// A design opened under an older extension keeps it.
assert_eq!(save_type("Plate.solidcraft").2, ".solidcraft");
}
#[test]
+19 -10
View File
@@ -24,11 +24,13 @@ pub const OPFS: &str = disk::OPFS_PREFIX;
pub const DOWNLOADS: &str = disk::DOWNLOADS_PREFIX;
/// Files brought in from the computer.
pub const UPLOAD: &str = "/upload/";
/// The autosave of unsaved work (in OPFS: `recovery.solidcraft` and `recovery.json`).
const RECOVERY: &str = "recovery.solidcraft";
/// The autosave earlier releases kept (compatibility shim, docs/compatibility.md): recovered
/// when there is no current one.
const LEGACY_RECOVERY: &str = "recovery.solvecraft";
/// The autosave of unsaved work (in OPFS: `recovery.sc` and `recovery.json`), named with
/// `solidcraft_engine::io::DESIGN_EXT`.
const RECOVERY: &str = "recovery.sc";
/// The autosaves earlier releases kept, newest first, one per entry of
/// `solidcraft_engine::io::LEGACY_DESIGN_EXTS` (compatibility shim, docs/compatibility.md): the
/// newest is recovered when there is no current one.
const LEGACY_RECOVERY: [&str; 2] = ["recovery.solidcraft", "recovery.solvecraft"];
const RECOVERY_META: &str = "recovery.json";
/// What to do with a file brought in from the computer.
@@ -38,6 +40,8 @@ pub enum Intent {
Open,
/// Add its bodies to the open design (STEP, 3MF, STL).
Insert,
/// Import it as a theme: it was dropped on Preferences' Import tile (#8226).
Theme,
}
/// A stored design, as the file panel lists it.
@@ -282,9 +286,10 @@ pub fn start(files: &Rc<Files>) {
}
let mut entries = Vec::new();
let has_recovery = all.iter().any(|(n, _, _)| n == RECOVERY);
let legacy = (!has_recovery).then(|| LEGACY_RECOVERY.into_iter().find(|l| all.iter().any(|(n, _, _)| n == l))).flatten();
for (name, bytes, modified) in all {
if name == LEGACY_RECOVERY {
if !has_recovery {
if LEGACY_RECOVERY.contains(&name.as_str()) {
if legacy == Some(name.as_str()) {
vfs::insert(&format!("{OPFS}{RECOVERY}"), bytes);
}
continue;
@@ -424,7 +429,9 @@ pub fn autosave(files: &Rc<Files>, doc: Option<(&solidcraft_engine::doc::Documen
}
None => spawn_local(async move {
let _ = remove_file(RECOVERY).await;
let _ = remove_file(LEGACY_RECOVERY).await;
for legacy in LEGACY_RECOVERY {
let _ = remove_file(legacy).await;
}
let _ = remove_file(RECOVERY_META).await;
}),
}
@@ -610,13 +617,15 @@ fn choose_file(accept: &str) -> Result<js_sys::Promise, String> {
}
/// Read files dropped on the page.
pub fn take_drops(files: &Rc<Files>, raw: &mut egui::RawInput) {
/// `theme`: the pointer is over Preferences' Import tile, so the files are themes.
pub fn take_drops(files: &Rc<Files>, raw: &mut egui::RawInput, theme: bool) {
let intent = if theme { Intent::Theme } else { Intent::Insert };
for f in std::mem::take(&mut raw.dropped_files) {
let files = files.clone();
spawn_local(async move {
let name = f.path().file_name().map(|n| n.to_string_lossy().to_string()).unwrap_or_else(|| "dropped".into());
match f.bytes_async().await {
Ok(b) => files.arrive(name, b, Intent::Insert),
Ok(b) => files.arrive(name, b, intent),
Err(e) => files.say(format!("{name}: {e}"), true),
}
});
+9 -4
View File
@@ -72,10 +72,10 @@ impl Download {
}
let Some((name, bytes)) = self.pending.take() else { return };
// The extension selects the design loader even when the URL has no extension.
let path = "/linked/design.solidcraft";
let path = &format!("/linked/design.{}", solidcraft_engine::io::DESIGN_EXT);
vfs::insert(path, bytes);
app.open_path(path);
if app.session.path.as_deref() == Some(path) {
if app.session.path.as_deref() == Some(path.as_str()) {
app.session.path = None;
app.session.doc_mut().name = name;
app.session.mark_unsaved();
@@ -90,9 +90,14 @@ async fn fetch(value: &str) -> Reply {
let window = web_sys::window().ok_or("No browser window")?;
let page_origin = window.location().origin().map_err(|_| "Cannot read page origin")?;
let url = design_url(value, &page_origin)?;
let name = url.path_segments().and_then(|mut segments| segments.next_back()).filter(|name| !name.is_empty()).unwrap_or("Design.solidcraft");
let name = url.path_segments().and_then(|mut segments| segments.next_back()).filter(|name| !name.is_empty()).unwrap_or("Design");
let decoded = js_sys::decode_uri_component(name).ok().and_then(|name| name.as_string()).unwrap_or_else(|| name.to_owned());
let name: String = decoded.strip_suffix(".solidcraft").unwrap_or(&decoded).chars().take(255).collect();
// `arm.sc` (or a legacy `arm.solidcraft`) is named `arm`.
let stem = match decoded.rsplit_once('.') {
Some((stem, ext)) if !stem.is_empty() && solidcraft_engine::io::is_design_ext(ext) => stem,
_ => decoded.as_str(),
};
let name: String = stem.chars().take(255).collect();
let response = JsFuture::from(window.fetch_with_str(url.as_str())).await.map_err(|_| "Network request failed or the host refused CORS access")?;
let response: web_sys::Response = response.dyn_into().map_err(|_| "Invalid download response")?;
design_url(&response.url(), &page_origin).map_err(|_| "Design redirected to a URL that does not use HTTPS or the page's own origin")?;
+59 -52
View File
@@ -271,6 +271,10 @@ mod web {
!companion
});
for (name, bytes, intent) in incoming {
if intent == Intent::Theme {
solidcraft_ui_egui::prefs::import_theme_bytes(&mut self.app, bytes);
continue;
}
let design = solidcraft_engine::io::is_design_path(&name);
let path = if design && intent == Intent::Open {
// A design from the computer is kept in the browser (a copy), so Save works.
@@ -287,7 +291,7 @@ mod web {
};
match intent {
Intent::Open => self.app.open_path(&path),
Intent::Insert => self.app.drop_path(&path),
Intent::Insert | Intent::Theme => self.app.drop_path(&path),
}
self.files.panel.set(false);
}
@@ -353,7 +357,8 @@ mod web {
}
let mut act: Option<(&'static str, String)> = None;
let closed = solidcraft_ui_egui::ui_kit::Window::new(egui::Id::new("sc_browser_files"), "folder", "Files in this browser")
.cards(3.0)
// Room for long names; the kit still caps the window at the browser's width.
.cards(4.0)
.show_body(ctx, |ui| {
ui.horizontal(|ui| {
if ui_kit::button(ui, "Open from computer…", ui_kit::Button::Normal).clicked() {
@@ -381,61 +386,62 @@ mod web {
return;
}
let entries = self.files.entries.borrow().clone();
if entries.is_empty() {
ui.label("Designs you save appear here. They stay in this browser.");
}
egui::ScrollArea::vertical().max_height(360.0).show(ui, |ui| {
egui::Grid::new("opfs_files").num_columns(3).spacing([12.0, 6.0]).show(ui, |ui| {
// The name takes the width the size and the actions leave (#8097).
let empty = "Designs you save appear here. They stay in this browser.";
ui_kit::name_list(ui, "opfs_files", &["Name", "Size", "Actions"], empty, |list| {
for e in &entries {
match &mut self.renaming {
Some((from, to)) if *from == e.name => {
let r = ui_kit::cell_editor(ui, ui.make_persistent_id(("stored_file_name", from.as_str())), to, "", false);
if std::mem::take(&mut self.rename_focus) {
r.request_focus();
}
if r.lost_focus() {
act = Some(if ui.input(|i| i.key_pressed(egui::Key::Enter)) {
("rename", to.clone())
} else {
("rename_cancel", String::new())
});
list.row(&e.name, |row| {
match &mut self.renaming {
Some((from, to)) if *from == e.name => row.cell(|ui| {
let r =
ui_kit::cell_editor(ui, ui.make_persistent_id(("stored_file_name", from.as_str())), to, "", false);
if std::mem::take(&mut self.rename_focus) {
r.request_focus();
}
if r.lost_focus() {
act = Some(if ui.input(|i| i.key_pressed(egui::Key::Enter)) {
("rename", to.clone())
} else {
("rename_cancel", String::new())
});
}
}),
_ => {
row.name(&e.name);
}
}
_ => {
ui.label(&e.name);
}
}
ui.label(format!("{:.1} KB", e.size as f64 / 1024.0));
ui.horizontal(|ui| {
if ui_kit::button(ui, "Open", ui_kit::Button::Small).clicked() {
act = Some(("open", e.name.clone()));
}
let design = solidcraft_engine::io::is_design_path(&e.name);
if !design
&& ui_kit::button(ui, "Insert", ui_kit::Button::Small)
.on_hover_text(solidcraft_ui_egui::i18n::tr("web.files.insert_stored_drawings_hint"))
row.cell(|ui| ui.label(format!("{:.1} KB", e.size as f64 / 1024.0)));
row.cell(|ui| {
if ui_kit::button(ui, "Open", ui_kit::Button::Small).clicked() {
act = Some(("open", e.name.clone()));
}
let design = solidcraft_engine::io::is_design_path(&e.name);
if !design
&& ui_kit::button(ui, "Insert", ui_kit::Button::Small)
.on_hover_text(solidcraft_ui_egui::i18n::tr("web.files.insert_stored_drawings_hint"))
.clicked()
{
act = Some(("insert", e.name.clone()));
}
if ui_kit::button(ui, "Rename", ui_kit::Button::Small).clicked() {
self.renaming = Some((e.name.clone(), e.name.clone()));
self.rename_focus = true;
}
if ui_kit::button(ui, "Save to computer…", ui_kit::Button::Small)
.on_hover_text("A copy in a file you choose; the stored design stays here")
.clicked()
{
act = Some(("insert", e.name.clone()));
}
if ui_kit::button(ui, "Rename", ui_kit::Button::Small).clicked() {
self.renaming = Some((e.name.clone(), e.name.clone()));
self.rename_focus = true;
}
if ui_kit::button(ui, "Save to computer…", ui_kit::Button::Small)
.on_hover_text("A copy in a file you choose; the stored design stays here")
.clicked()
{
act = Some(("save_copy", e.name.clone()));
}
if ui_kit::button(ui, "Download", ui_kit::Button::Small).clicked() {
act = Some(("download", e.name.clone()));
}
if ui_kit::button(ui, "Delete", ui_kit::Button::Small).clicked() {
act = Some(("delete", e.name.clone()));
}
{
act = Some(("save_copy", e.name.clone()));
}
if ui_kit::button(ui, "Download", ui_kit::Button::Small).clicked() {
act = Some(("download", e.name.clone()));
}
if ui_kit::button(ui, "Delete", ui_kit::Button::Small).clicked() {
act = Some(("delete", e.name.clone()));
}
});
});
ui.end_row();
}
});
});
@@ -630,7 +636,8 @@ mod web {
ctx.request_repaint_after(delay);
}
if self.launch.persists() {
files::take_drops(&self.files, raw);
let theme = solidcraft_ui_egui::prefs::theme_drop_target(&self.app, ctx);
files::take_drops(&self.files, raw, theme);
} else {
raw.dropped_files.clear();
}
+5
View File
@@ -96,6 +96,11 @@ libc = "0.2"
[target.'cfg(all(unix, not(target_os = "macos")))'.dependencies]
winit = { version = "0.30", default-features = false, features = ["x11"] }
# Bringing the window forward on X11 when a close asks about unsaved designs (src/come_forward.rs):
# the window's id, and the window manager request winit doesn't send (MIT OR Apache-2.0; both
# already in the tree through eframe and winit).
raw-window-handle = "0.6"
x11rb = { version = "0.13", default-features = false }
[build-dependencies]
embed-resource = "3.0.11"
+234
View File
@@ -0,0 +1,234 @@
//! Bringing the window forward when a close stops at "save changes?".
//!
//! A close from the taskbar or a window switcher reaches the window while another app has the
//! focus. The prompt it opens is only seen once the window comes forward, so the window asks for
//! the focus then. A window the user is already in is left alone.
//!
//! winit's Focus asks as an application, which a window manager with focus-stealing prevention
//! (KWin's default) refuses for a window used before the switch away: it only marks the taskbar
//! entry. On X11 the request is sent again with the source EWMH gives "direct user actions"
//! (`_NET_ACTIVE_WINDOW`, source 2), which is what this is: the prompt is the rest of the user's
//! close. Native Wayland has no way for a window to raise itself, so there the attention request
//! (xdg-activation) lets the compositor raise it or mark its taskbar entry.
//!
//! When: not at once. KWin raises the window, then the taskbar's closing context menu hands the
//! focus back to the app that had it, a few milliseconds later, and the window would flicker
//! forward and back. So the window asks once the menu is gone, `FIRST_AFTER` the close. It asks
//! again only if the focus is taken back right after it came (a slow menu) or never came; a later
//! switch is the user's own, and the window stays where the user put it.
use std::time::{Duration, Instant};
/// From the close to the first request: past the taskbar menu's focus hand-back (2 to 11 ms on
/// KDE Plasma 6), too short to notice.
const FIRST_AFTER: Duration = Duration::from_millis(120);
/// After the first request, how long the window asks again when it loses the focus: short of
/// anything the user does next.
const KEEP_ASKING: Duration = Duration::from_millis(400);
/// The least time between two requests.
const AGAIN_AFTER: Duration = Duration::from_millis(100);
/// Focus lost this soon after a request was taken back by the taskbar menu; later, by the user.
const TAKEN_BACK_WITHIN: Duration = Duration::from_millis(50);
/// The window coming forward after a close that asks about unsaved designs.
#[derive(Default)]
pub struct ComeForward {
/// The first request and the end of asking; `None`: not asking.
window: Option<(Instant, Instant)>,
/// The last request.
last: Option<Instant>,
/// The window has had the focus since the last request.
held: bool,
}
/// What a frame does while the window is coming forward.
#[derive(Debug, PartialEq)]
enum Step {
/// Ask for the focus now.
Ask,
/// Look again after this long.
Wait(Duration),
/// Done asking.
Done,
}
impl ComeForward {
/// A close stopped at the prompt: ask for the focus shortly.
pub fn start(&mut self, now: Instant) {
let first = now + FIRST_AFTER;
self.window = Some((first, first + KEEP_ASKING));
self.last = None;
self.held = false;
}
/// Every frame: ask once the taskbar menu is gone, and again while the focus is taken back.
pub fn tick(&mut self, ctx: &egui::Context, frame: &eframe::Frame) {
if self.window.is_none() {
return;
}
let (focused, minimized) = ctx.input(|i| (i.viewport().focused, i.viewport().minimized));
// The app may be idle: a frame to look again.
match self.step(Instant::now(), focused) {
Step::Ask => {
bring(ctx, frame, minimized);
ctx.request_repaint_after(AGAIN_AFTER);
}
Step::Wait(after) => ctx.request_repaint_after(after),
Step::Done => {}
}
}
fn step(&mut self, now: Instant, focused: Option<bool>) -> Step {
let Some((first, until)) = self.window else { return Step::Done };
if now >= until {
self.window = None;
return Step::Done;
}
if now < first {
return Step::Wait(first - now);
}
let Some(last) = self.last else {
if focused == Some(true) {
// The user went back to the window already.
self.window = None;
return Step::Done;
}
self.last = Some(now);
return Step::Ask;
};
if focused == Some(true) {
self.held = true;
return Step::Wait(until - now);
}
if self.held {
if now.duration_since(last) >= TAKEN_BACK_WITHIN {
// The user switched away: leave the window there.
self.window = None;
return Step::Done;
}
self.held = false;
}
let next = last + AGAIN_AFTER;
if now < next {
return Step::Wait(next - now);
}
self.last = Some(now);
Step::Ask
}
}
/// Ask for the focus once.
fn bring(ctx: &egui::Context, frame: &eframe::Frame, minimized: Option<bool>) {
#[cfg(all(unix, not(target_os = "macos")))]
let raised = match x11_activate(frame) {
Ok(sent) => sent,
Err(e) => {
log::warn!("bringing the window forward through X11: {e}");
false
}
};
#[cfg(not(all(unix, not(target_os = "macos"))))]
let raised = {
let _ = frame;
false
};
for c in commands(minimized, raised) {
ctx.send_viewport_cmd(c);
}
}
/// The viewport commands for a window in the background; `raised`: the X11 request went out,
/// which also restores a minimized window.
fn commands(minimized: Option<bool>, raised: bool) -> Vec<egui::ViewportCommand> {
if raised {
return vec![egui::ViewportCommand::Focus];
}
let mut commands = Vec::new();
if minimized == Some(true) {
commands.push(egui::ViewportCommand::Minimized(false));
}
commands.push(egui::ViewportCommand::Focus);
commands.push(egui::ViewportCommand::RequestUserAttention(egui::UserAttentionType::Informational));
commands
}
/// Ask the X11 window manager to activate the window as a user action. `Ok(false)`: the window
/// isn't an X11 window (native Wayland).
#[cfg(all(unix, not(target_os = "macos")))]
fn x11_activate(frame: &eframe::Frame) -> Result<bool, String> {
use raw_window_handle::{HasWindowHandle, RawWindowHandle};
use x11rb::connection::Connection;
use x11rb::protocol::xproto::{ClientMessageEvent, ConnectionExt, EventMask};
let handle = frame.window_handle().map_err(|e| e.to_string())?;
let window = match handle.as_raw() {
RawWindowHandle::Xlib(h) => u32::try_from(h.window).map_err(|e| e.to_string())?,
RawWindowHandle::Xcb(h) => h.window.get(),
_ => return Ok(false),
};
// A connection of its own: winit's isn't reachable, and a close that asks is rare.
let (conn, screen) = x11rb::connect(None).map_err(|e| e.to_string())?;
let root = conn.setup().roots.get(screen).ok_or("no X11 screen")?.root;
let atom = conn.intern_atom(false, b"_NET_ACTIVE_WINDOW").map_err(|e| e.to_string())?.reply().map_err(|e| e.to_string())?.atom;
// Source 2: a direct user action; the time is the server's current time.
let event = ClientMessageEvent::new(32, window, atom, [2, x11rb::CURRENT_TIME, 0, 0, 0]);
conn.send_event(false, root, EventMask::SUBSTRUCTURE_REDIRECT | EventMask::SUBSTRUCTURE_NOTIFY, event).map_err(|e| e.to_string())?;
conn.flush().map_err(|e| e.to_string())?;
Ok(true)
}
#[cfg(test)]
mod tests {
use super::{AGAIN_AFTER, ComeForward, FIRST_AFTER, KEEP_ASKING, Step};
use eframe::egui::{UserAttentionType, ViewportCommand as C};
use std::time::{Duration, Instant};
/// The first request waits until the taskbar menu has handed the focus back. The window asks
/// again when the focus is taken back right after it came, or never came, no more often than
/// every `AGAIN_AFTER` and only for `KEEP_ASKING`; a later switch away is the user's.
#[test]
fn the_window_asks_once_the_taskbar_menu_is_gone() {
let t0 = Instant::now();
let ms = |n: u64| Duration::from_millis(n);
let at = |n: u64| t0 + ms(n);
let (first, again, keep) = (FIRST_AFTER.as_millis() as u64, AGAIN_AFTER.as_millis() as u64, KEEP_ASKING.as_millis() as u64);
let mut f = ComeForward::default();
assert_eq!(f.step(t0, Some(false)), Step::Done, "not started");
f.start(t0);
assert_eq!(f.step(t0, Some(false)), Step::Wait(FIRST_AFTER), "the menu is still closing");
assert_eq!(f.step(at(5), Some(false)), Step::Wait(ms(first - 5)));
assert_eq!(f.step(at(first), Some(false)), Step::Ask);
assert_eq!(f.step(at(first + 3), Some(true)), Step::Wait(ms(keep - 3)), "raised");
// A slow menu takes the focus back 10 ms later: ask again, not before AGAIN_AFTER.
assert_eq!(f.step(at(first + 10), Some(false)), Step::Wait(ms(again - 10)));
assert_eq!(f.step(at(first + again), Some(false)), Step::Ask);
assert_eq!(f.step(at(first + again + 3), Some(true)), Step::Wait(ms(keep - again - 3)));
// The user clicks another app 200 ms later: the window stays behind.
assert_eq!(f.step(at(first + again + 200), Some(false)), Step::Done);
assert_eq!(f.step(at(first + again + 300), Some(false)), Step::Done);
// Never raised (the request was refused): ask again every AGAIN_AFTER, for KEEP_ASKING.
f.start(t0);
assert_eq!(f.step(at(first), None), Step::Ask, "unknown focus counts as out of focus");
assert_eq!(f.step(at(first + again), Some(false)), Step::Ask);
assert_eq!(f.step(at(first + keep), Some(false)), Step::Done);
// Back in the window before the first request: nothing to do.
f.start(t0);
assert_eq!(f.step(at(first), Some(true)), Step::Done);
}
/// Without the X11 request: focus, and the attention mark where focus is refused; a minimized
/// window is restored first.
#[test]
fn a_window_closed_from_the_background_comes_forward() {
let forward = [C::Focus, C::RequestUserAttention(UserAttentionType::Informational)];
assert_eq!(super::commands(Some(false), false), forward);
assert_eq!(super::commands(None, false), forward, "unknown counts as not minimized");
let minimized = super::commands(Some(true), false);
assert_eq!(minimized.first(), Some(&C::Minimized(false)));
assert_eq!(minimized.get(1..), Some(&forward[..]));
// The window manager took the X11 request: nothing left to mark.
assert_eq!(super::commands(Some(true), true), [C::Focus]);
}
}
+12 -2
View File
@@ -1,6 +1,6 @@
//! SolidCraft desktop app.
//!
//! Usage: `solidcraft [--control <port>] [--sample] [--crash-log] [--safe-mode] [design.solidcraft | part.step]`
//! Usage: `solidcraft [--control <port>] [--sample] [--crash-log] [--safe-mode] [design.sc | part.step]`
//!
//! `--safe-mode` (or `SOLIDCRAFT_SAFE_MODE=1`) starts with default settings, no recovery offer and
//! the software renderer; see `startup` and docs/book/src/guide/troubleshooting.md.
@@ -20,6 +20,7 @@
#[cfg(not(target_os = "macos"))]
#[path = "../../../assets/icons/app/shared/source/app_icon.rs"]
mod app_icon;
mod come_forward;
mod control_server;
mod device_lost;
#[cfg(target_os = "windows")]
@@ -84,6 +85,8 @@ struct App {
frames: u32,
/// Started over the control channel: the window doesn't ask for the foreground.
take_focus_unwanted: bool,
/// Coming forward after a close that asks about unsaved designs.
come_forward: come_forward::ComeForward,
/// The graphics device: lost, it can't draw again (`App::watch_device`, #4172).
gpu: Option<LostWatch>,
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
@@ -139,7 +142,13 @@ impl eframe::App for App {
if ctx.input(|i| i.viewport().close_requested()) && !self.solve.quit_requested {
ctx.send_viewport_cmd(egui::ViewportCommand::CancelClose);
solidcraft_ui_egui::documents::request_quit(&mut self.solve);
// Closed from the taskbar or a window switcher while another app had the focus: the
// "save changes?" prompt is only seen once the window comes forward.
if !self.solve.quit_requested {
self.come_forward.start(std::time::Instant::now());
}
}
self.come_forward.tick(ctx, _frame);
#[cfg(target_os = "macos")]
for f in if self.solve.file_picker_busy() { Vec::new() } else { open_documents::take() } {
self.solve.open_path_async(&f);
@@ -778,7 +787,7 @@ fn main() -> eframe::Result {
}
"--help" | "-h" => {
println!(
"usage: solidcraft [--control PORT] [--sample] [--theme-file THEME.json] [--crash-log] [--safe-mode] [design.solidcraft | part.step]"
"usage: solidcraft [--control PORT] [--sample] [--theme-file THEME.json] [--crash-log] [--safe-mode] [design.sc | part.step]"
);
return Ok(());
}
@@ -1060,6 +1069,7 @@ fn main() -> eframe::Result {
starting,
frames: 0,
take_focus_unwanted: control_port.is_some(),
come_forward: come_forward::ComeForward::default(),
gpu,
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
space_mouse,
+3
View File
@@ -27,6 +27,9 @@ error = { master = "status_error", accent = "surface" }
warning = { master = "status_warning", accent = "mesh" }
ground = "c_fix"
# Visual style: Shaded with edges is the generic style icon.
style_shaded_edges = "style"
# Same finished drawing, different semantic operation. Colours live only in palette.toml.
sketch_break = { master = "break", accent = "sketch" }
sketch_cancel = { master = "close", accent = "sketch" }
@@ -1,6 +1,8 @@
accessibility false
activate false
agent_chat false
align false
ambient_occlusion false
appearance false
arc3 false
arc_center false
@@ -83,6 +85,8 @@ decal false
delete false
delete_face false
dimension false
display false
dots false
draft false
draft_analysis false
drive false
@@ -101,6 +105,7 @@ eye false
fastener false
fillet false
finish false
finish_edit false
fit false
fit_section false
flange false
@@ -110,7 +115,9 @@ folder false
frame_member false
gear false
graph false
grid false
ground false
ground_shadow false
help false
hem false
hole false
@@ -210,6 +217,11 @@ section false
select false
send false
settings false
settings_keyboard false
settings_monitor false
settings_mouse false
settings_palette false
settings_plug false
sheet_rules false
shell false
shield false
@@ -247,6 +259,11 @@ star false
status_error false
status_recovery false
style false
style_hidden_edges false
style_shaded false
style_shaded_edges false
style_translucent false
style_wireframe false
suppress false
surface false
surface_blend false
+15
View File
@@ -6,6 +6,7 @@
"agent_chat": "4a9ae0e7e2c360b4858b3175674c93d096705c92318fecd481e849f3ae650bf4",
"agent_link": "2f20d89a0e3e9b28744910dddf7f282a1099ccd91aa160c9841c5b1d9ea9ed0f",
"align": "05615db7dd9e4be56ae898e59a68c548b8a8447794442a9a394940651204bc4f",
"ambient_occlusion": "973f8ef2326aeaf0face576e5a2c79c7ef3d13638b2c51a5aad199e4ef7edb02",
"appearance": "b3162edd92291a5ef402e8499cd52be05beb2fa7eda641163c3f6e98325de2bf",
"arc3": "fdca3d501fd557ac989376a12e9c4fa8231fde2b455c20724d1079a466153e9c",
"arc_center": "3a5fdeb1d64fc6741f944c4435870b05fccab62293e270da692c6681155cbc51",
@@ -88,6 +89,7 @@
"dimension": "a926b7c64bc8ca99d8d6dcbb81b95235bd3fc34fbed049aca8b01b4d1147c15d",
"disclosure_closed": "49a350c6f2efae78de0be96c524ebee1fd1291ea449a84224b88d37164a4e807",
"disclosure_open": "d13ce3f97e3e362a9904fa2bf3412f3f00e4136bc23538b92d41483961d280de",
"display": "58b45e5e2230eaf2c80f74b3be2e02a23714c90d6fb03b59ed093a1949993163",
"dots": "600f7ff209d93145fc938bc4f6a1e34473e6b9ee22a5b4718f133bc7da5ee58d",
"draft": "9c0fc361cacd0ad95ccd54794f4825dfc9901a83a3de752a588faec365d0ee09",
"draft_analysis": "eb39c0f90e9cf226da6307365a76015e900dd692dc3f0fdc8f02fe717226261f",
@@ -117,7 +119,9 @@
"folder": "c19f5230df45a1bda1e92e89de38bba21c91e6eca0517eb15847a7712012d1e5",
"gear": "25a1ca48a587850da1104a46005a330873ed196246e3d04e12cf61f26ad2b0d5",
"graph": "7156caedd2dbfa2ae53da18b7a2204b8db66c45126859d36caf049a3fd4335a4",
"grid": "084b5040d57e9d5183b3db1fad0d17a13ab5bae64676eef703cc06622f9c7438",
"ground": "23e2471a9d6872e83028e0e219e330cef1930a4d89456a0fefa1bda8a7e3eb81",
"ground_shadow": "a96809ed87f5047c2d7f1274908ed7b65b180613322ac9c10eb0f9d6296c1b66",
"help": "8ce4060577483dbdb510be147d2827de50ac20029354008fca55abc0c7edf05d",
"hem": "f9b1aafbedcf3dc90c26be308814638e0095fbe31b0647092507343fa60af011",
"hole": "f82d47751f826e08682db847a270897474661bfe9f35b6d3678f49a203172563",
@@ -263,6 +267,12 @@
"screw": "5e30570785360d6a591ea22862a82f1cf62228385c1e96382536db8a453ac791",
"section": "cdd13f99f15f6d59bfa21c747810608d6afd00cb8207faf0337928c8521e7eae",
"select": "fdf6431270006ca7409c60c37cfed59572de04229f104ec723e6010ffa2b7163",
"select_bodies": "8e6e61e083e6097535da3b98d41b607b40fc81b72bbd8c7fb903618c5b35c568",
"select_components": "3e6cc847b334e92ce7ec5e5f35dfa929572e0974239790d76563ca4e20b26789",
"select_faces_edges": "7b99b5370b1647bf8cea57df7a1053caab641c2f4a94c4d797b9679e6f38d6f1",
"select_features": "b050bc19ce86d135cbe50998be681555110e92e179c4c7b101170c6b62c19943",
"select_parts": "569adc5595a64187411d8ffeea69eab3b76ddfa33aeead6fd728efdd993bcccc",
"select_sketch": "b0605b34a14d4173f7ed80d877109ec0b891a1b395bcab5743a603ed2eae240a",
"send": "f83b6cdab792f9567a81d46d7828ed20795513c57a2c7d00fbbe6bd14d2f5848",
"settings": "9193dd3a1007c43660d0d47b6499cb2571338b67949e1a99df112057b9bf2b8a",
"settings_keyboard": "4968c70788094365af9c6e2b1c15b2aac45cf21212a14b8a256daf1ffe17f41a",
@@ -309,6 +319,11 @@
"stitch": "6c3205d64007b771ed78d6f8055867578439fb25d591563b32dbd3343c98732d",
"stop": "36967eb4d423370d0d6c679b0a71f8d09f4fb2c73eed3e8cc50c604c44b0c32b",
"style": "6c2b04234b82ea4858c80190cc7208c60f549358253005afc35ab4e29506b578",
"style_hidden_edges": "a707dfc0bdcabe9144865f569abfcb478e493143cbd4331efc1404cf3082f6d2",
"style_shaded": "6e5f8f9a9030ab3717f8b2192bbfd3f6b515ad398acf6cb41bc24f1298bc73b4",
"style_shaded_edges": "6c2b04234b82ea4858c80190cc7208c60f549358253005afc35ab4e29506b578",
"style_translucent": "c46b0cd485cfb9023514908357048b5cba9017a0c4976239da1e98f50e4ab5f9",
"style_wireframe": "af7e575d378b5b6850bee9d3ca384efab95c8d4c876c5e3524f3ea771c4380a3",
"suppress": "c54fbc01c12c0175d78cd63f692e8aaf73fc2cac79752b2a3ad821ac32734343",
"surface": "ba0e839ce0ee03e7ff95a2389a5ecb20bd80c713064d9b1bd5f461f4a80d1921",
"surface_blend": "0642f3b4af7d22f379a3c74f54c7b1c9eef0bdda19372ce4df73c0e56bdd7bbc",
@@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
<title>Ambient occlusion</title>
<g opacity="0.22"><path d="M13 51L51 51A38 38 0 0 0 13 13Z" fill="currentColor" stroke="currentColor" stroke-width="0" stroke-linejoin="round" stroke-linecap="round"/></g>
<g opacity="0.38"><path d="M13 51L40 51A27 27 0 0 0 13 24Z" fill="currentColor" stroke="currentColor" stroke-width="0" stroke-linejoin="round" stroke-linecap="round"/></g>
<g opacity="0.62"><path d="M13 51L29 51A16 16 0 0 0 13 35Z" fill="currentColor" stroke="currentColor" stroke-width="0" stroke-linejoin="round" stroke-linecap="round"/></g>
<path d="M13 10L13 51L54 51" fill="none" stroke="currentColor" stroke-width="5.6" stroke-linejoin="round" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 758 B

@@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
<title>Display</title>
<path d="M10 22L54 22M10 42L54 42" fill="none" stroke="currentColor" stroke-width="5.6" stroke-linejoin="round" stroke-linecap="round"/>
<circle cx="24" cy="22" r="10.5" fill="#ffffff"/>
<circle cx="42" cy="42" r="10.5" fill="#ffffff"/>
<circle cx="24" cy="22" r="6.4" fill="currentColor"/>
<circle cx="42" cy="42" r="6.4" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 448 B

+5
View File
@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
<title>Grid</title>
<path d="M12 12L52 12L52 52L12 52Z" fill="none" stroke="currentColor" stroke-width="5.6" stroke-linejoin="round" stroke-linecap="round"/>
<path d="M25.3 12L25.3 52M38.7 12L38.7 52M12 25.3L52 25.3M12 38.7L52 38.7" fill="none" stroke="currentColor" stroke-width="4" stroke-linejoin="round" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 407 B

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
<title>Ground shadow</title>
<path d="M32 4.8 L48.1 13.9 L48.1 32.1 L32 41.2 L15.9 32.1 L15.9 13.9Z" fill="currentColor" stroke="currentColor" stroke-width="1.2" stroke-linejoin="round" stroke-linecap="round"/>
<path d="M9.34 31.35A25 11 0 1 0 54.66 31.35" fill="none" stroke="currentColor" stroke-width="5.2" stroke-linejoin="round" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 433 B

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
<title>Bodies</title>
<path d="M32 6 L55 19 L55 45 L32 58 L9 45 L9 19Z" fill="currentColor" stroke="currentColor" stroke-width="1.2" stroke-linejoin="round" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 254 B

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
<title>Components</title>
<path d="M22.91 5.75 L41.09 16.25 L22.91 26.75 L4.72 16.25ZM4.72 16.25 L22.91 26.75 L22.91 47.75 L4.72 37.25ZM41.09 16.25 L59.28 26.75 L41.09 37.25 L22.91 26.75ZM22.91 26.75 L41.09 37.25 L41.09 58.25 L22.91 47.75ZM59.28 26.75 L41.09 37.25 L41.09 58.25 L59.28 47.75Z" fill="currentColor" stroke="currentColor" stroke-width="4.2" stroke-linejoin="round" stroke-linecap="round"/>
<path d="M37.46 18.35L22.91 26.75L22.91 43.55" fill="none" stroke="#ffffff" stroke-width="3.6" stroke-linejoin="round" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 621 B

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
<title>Faces and edges</title>
<path d="M32 6 L55 19 L32 32 L9 19Z" fill="currentColor" stroke="currentColor" stroke-width="1.2" stroke-linejoin="round" stroke-linecap="round"/>
<path d="M32 6 L55 19 L55 45 L32 58 L9 45 L9 19Z" fill="none" stroke="currentColor" stroke-width="4.6" stroke-linejoin="round" stroke-linecap="round"/>
<path d="M32 32L9 19M32 32L55 19M32 32L32 58" fill="none" stroke="currentColor" stroke-width="3.6" stroke-linejoin="round" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 554 B

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
<title>Features</title>
<path d="M32 6 L55 19 L55 45 L32 58 L9 45 L9 19Z" fill="none" stroke="currentColor" stroke-width="4.6" stroke-linejoin="round" stroke-linecap="round"/>
<path d="M9 19L32 32M32 32L55 19M32 32L32 58" fill="none" stroke="currentColor" stroke-width="3.6" stroke-linejoin="round" stroke-linecap="round"/>
<path d="M42 19C42 22.2 37.52 24.8 32 24.8C26.48 24.8 22 22.2 22 19C22 15.8 26.48 13.2 32 13.2C37.52 13.2 42 15.8 42 19Z" fill="currentColor" stroke="currentColor" stroke-width="0.6" stroke-linejoin="round" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 632 B

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
<title>Parts</title>
<path d="M22.91 5.75 L41.09 16.25 L22.91 26.75 L4.72 16.25ZM4.72 16.25 L22.91 26.75 L22.91 47.75 L4.72 37.25Z" fill="none" stroke="currentColor" stroke-width="4.2" stroke-linejoin="round" stroke-linecap="round"/>
<path d="M41.09 16.25 L59.28 26.75 L41.09 37.25 L22.91 26.75ZM22.91 26.75 L41.09 37.25 L41.09 58.25 L22.91 47.75ZM59.28 26.75 L41.09 37.25 L41.09 58.25 L59.28 47.75Z" fill="currentColor" stroke="currentColor" stroke-width="4.2" stroke-linejoin="round" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 585 B

@@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
<title>Sketch features</title>
<path d="M10 46C18 14 46 14 54 46" fill="none" stroke="currentColor" stroke-width="5" stroke-linejoin="round" stroke-linecap="round"/>
<circle cx="10" cy="46" r="8.6" fill="#ffffff"/>
<circle cx="54" cy="46" r="8.6" fill="#ffffff"/>
<circle cx="32" cy="22.5" r="8.6" fill="#ffffff"/>
<circle cx="10" cy="46" r="5.8" fill="currentColor"/>
<circle cx="54" cy="46" r="5.8" fill="currentColor"/>
<circle cx="32" cy="22.5" r="5.8" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 563 B

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
<title>Shaded with hidden edges</title>
<path d="M32 6 L55 19 L55 45 L32 58 L9 45 L9 19Z" fill="currentColor" stroke="currentColor" stroke-width="1.2" stroke-linejoin="round" stroke-linecap="round"/>
<path d="M32 32L15.44 22.64M32 32L48.56 22.64M32 32L32 50.72" fill="none" stroke="#ffffff" stroke-width="3.6" stroke-linejoin="round" stroke-linecap="round"/>
<path d="M32 32L32 13.28M32 32L48.56 41.36M32 32L15.44 41.36" fill="none" stroke="#ffffff" stroke-width="3.2" stroke-linejoin="round" stroke-linecap="round" stroke-dasharray="4.5 4"/>
</svg>

After

Width:  |  Height:  |  Size: 619 B

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
<title>Shaded</title>
<g opacity="0.5"><path d="M32 6 L55 19 L32 32 L9 19Z" fill="currentColor" stroke="currentColor" stroke-width="0.8" stroke-linejoin="round" stroke-linecap="round"/></g>
<g opacity="0.8"><path d="M9 19 L32 32 L32 58 L9 45Z" fill="currentColor" stroke="currentColor" stroke-width="0.8" stroke-linejoin="round" stroke-linecap="round"/></g>
<path d="M32 32 L55 19 L55 45 L32 58Z" fill="currentColor" stroke="currentColor" stroke-width="0.8" stroke-linejoin="round" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 583 B

@@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
<title>Translucent</title>
<defs>
<clipPath id="tr-clip"><path d="M32 8.6 L52.7 20.3 L52.7 43.7 L32 55.4 L11.3 43.7 L11.3 20.3Z"/></clipPath>
</defs>
<g clip-path="url(#tr-clip)"><path d="M-71 72L9 -8M-60.5 72L19.5 -8M-50 72L30 -8M-39.5 72L40.5 -8M-29 72L51 -8M-18.5 72L61.5 -8M-8 72L72 -8M2.5 72L82.5 -8M13 72L93 -8M23.5 72L103.5 -8M34 72L114 -8M44.5 72L124.5 -8M55 72L135 -8" fill="none" stroke="currentColor" stroke-width="2.8" stroke-linejoin="round" stroke-linecap="round"/></g>
<path d="M32 6 L55 19 L55 45 L32 58 L9 45 L9 19Z" fill="none" stroke="currentColor" stroke-width="5.2" stroke-linejoin="round" stroke-linecap="round"/>
<path d="M32 32L11.76 20.56M32 32L52.24 20.56M32 32L32 54.88" fill="none" stroke="#ffffff" stroke-width="6.4" stroke-linejoin="round" stroke-linecap="round"/>
<path d="M32 32L11.3 20.3M32 32L52.7 20.3M32 32L32 55.4" fill="none" stroke="currentColor" stroke-width="3.6" stroke-linejoin="round" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
<title>Wireframe</title>
<path d="M32 6 L55 19 L55 45 L32 58 L9 45 L9 19Z" fill="none" stroke="currentColor" stroke-width="5.2" stroke-linejoin="round" stroke-linecap="round"/>
<path d="M32 32L32 6M32 32L55 19M32 32L55 45M32 32L32 58M32 32L9 45M32 32L9 19" fill="none" stroke="currentColor" stroke-width="3.6" stroke-linejoin="round" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 433 B

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
<title>Finish Edit</title>
<path d="M50 32L14 32M25 21L14 32L25 43" fill="none" stroke="#236ead" stroke-width="5.6" stroke-linejoin="round" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 237 B

File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+879 -2
View File
File diff suppressed because it is too large Load Diff
+23 -1
View File
@@ -33,6 +33,7 @@
"All open designs": "Alle åbne designs",
"Allowed expressions, separated by semicolons": "Tilladte udtryk adskilt af semikolon",
"Also deletes": "Sletter også",
"Also place them from the origin (fully constrained)": "Placer dem også fra origo (fuldt fastlåst)",
"Anchor": "Forankring",
"Angle 2": "Vinkel 2",
"Animate": "Animér",
@@ -158,6 +159,7 @@
"Designs you open or save appear here.": "Designs, du åbner eller gemmer, vises her.",
"Determined by To Object. Choose Angle to edit the angular extent.": "Bestemmes af Til objekt. Vælg Vinkel for at ændre vinkeludstrækningen.",
"Diameter": "Diameter",
"Dimension new shapes": "Mål nye figurer",
"Direction": "Retning",
"Discard": "Kassér",
"Distance": "Afstand",
@@ -169,6 +171,8 @@
"Drag to move the hole; click to remove it": "Træk for at flytte hullet; klik for at fjerne det",
"Drive Joint": "Bevæg led",
"Duration": "Varighed",
"Each new shape is also dimensioned from the sketch origin until nothing of it is left free. A shape already attached to the origin or to placed geometry gets none.": "Hver ny figur får også mål fra skitsens origo, indtil intet af den er frit. En figur, der allerede er knyttet til origo eller til placeret geometri, får ingen.",
"Each shape you draw gets all its dimensions, at the sizes you drew (typed values win). A size the sketch already sets is left out.": "Hver figur, du tegner, får alle sine mål i de størrelser, du tegnede (indtastede værdier vinder). En størrelse, som skitsen allerede fastlægger, udelades.",
"Edges": "Kanter",
"Edit": "Redigér",
"Edit Profile Sketch": "Redigér profilskitse",
@@ -1106,7 +1110,7 @@
"home.new_mm": "Nyt design",
"home.new_mm_hint": "Millimeter · åbner i Design",
"home.open": "Åbn…",
"home.open_hint": "Et .solidcraft-design ({shortcut})",
"home.open_hint": "Et .sc-design ({shortcut})",
"home.open_now": "Åbn nu",
"home.opened_days_ago": "For {count} dage siden",
"home.opened_hours_ago": "For {count} t siden",
@@ -1190,7 +1194,9 @@
"nav.free_orbit.help": "Musen og 3D-musen roterer gennem begge poler og bevarer rulning. Snap til akser med Shift er slået fra.",
"nav.free_orbit.label": "Fri rotation af visningen",
"nav.fusion.help": "Træk med midterste museknap panorerer, Shift+midterste roterer visningen, træk med højre roterer visningen",
"nav.hfss.help": "Alt+træk med venstre museknap panorerer, Shift+Alt+venstre zoomer, Ctrl+træk med venstre fra et tomt område roterer visningen",
"nav.inventor.help": "Træk med midterste museknap panorerer, Shift+midterste roterer visningen, Ctrl+midterste zoomer, træk med højre roterer visningen",
"nav.maya.help": "Alt+træk med venstre museknap roterer visningen, Alt+midterste panorerer, Alt+højre zoomer; træk med midterste museknap panorerer også",
"nav.openscad.help": "Træk med venstre museknap i et tomt område roterer visningen, Shift+venstre markerer med en ramme, træk i skitsegeometri redigerer den; træk med højre eller midterste museknap panorerer, Shift+højre eller Shift+midterste zoomer",
"nav.solidworks.help": "Træk med midterste museknap roterer visningen, Ctrl+midterste panorerer, Shift+midterste zoomer, træk med højre roterer visningen",
"nav.tinkercad.help": "Træk med højre museknap roterer visningen, træk med midterste eller Shift+højre panorerer",
@@ -1209,6 +1215,11 @@
"no picture": "intet billede",
"none": "ingen",
"parts.automatic_name": "automatisk",
"parts.dimension.d": "Nominel diameter",
"parts.dimension.height": "Højde",
"parts.dimension.pitch": "Stigning",
"parts.dimension.thickness": "Tykkelse",
"parts.dimension.width": "Bredde",
"pattern.alignment_2": "Justering 2",
"pattern.alignment_hint": "Antal omfatter originalen. Centrér fordeler kopierne ligeligt; Vend vælger siden med den ekstra kopi ved et lige samlet antal.",
"pattern.direction_1": "Retning 1",
@@ -1388,6 +1399,13 @@
"render.return_design": "Tilbage til Design",
"render.save_setup": "Gem opsætning",
"render.setup_name": "Opsætningsnavn",
"render.shots_camera_changed": "Kameraet er ændret, siden denne optagelse blev gemt",
"render.shots_name_help": "Indtast et unikt navn til den aktuelle optagelse.",
"render.shots_no_result": "Ingen rendering endnu",
"render.shots_result": "Rendering {number} · {width} × {height}",
"render.shots_revert": "Gendan",
"render.shots_save": "Gem optagelse",
"render.shots_update": "Opdater optagelse",
"render.unavailable_preview": "Denne opsætning bruger en type forhåndsvisning, der ikke er tilgængelig.",
"render.unsaved": "Ændringer i forhåndsvisning er ikke gemt",
"render.use_preview": "Brug integreret forhåndsvisning",
@@ -2057,6 +2075,7 @@
"ui.heading_utilities": "VÆRKTØJER",
"ui.heading_utility": "VÆRKTØJ",
"ui.heading_weldments": "SVEJSNING",
"ui.height": "Højde",
"ui.help": "Hjælp",
"ui.hide": "Skjul",
"ui.hideAxes": "Skjul akser",
@@ -2095,6 +2114,7 @@
"ui.language": "Sprog",
"ui.layout_compact": "Kompakt",
"ui.layout_floating": "Flydende",
"ui.length": "Længde",
"ui.length_decimals": "Længdedecimaler",
"ui.light": "Lys",
"ui.line": "Linje",
@@ -2182,6 +2202,7 @@
"ui.pinToShortcuts": "Fastgør til genveje",
"ui.pinToToolbar": "Fastgør til værktøjslinje",
"ui.pipe": "Rør",
"ui.pitch": "Stigning",
"ui.placement": "Placering",
"ui.plane": "Plan",
"ui.plane_at_angle": "Plan i vinkel",
@@ -2365,6 +2386,7 @@
"ui.visual_shaded_with_edges": "Skyggelagt med kanter",
"ui.visual_style": "Visuel stil",
"ui.visual_wireframe": "Trådmodel",
"ui.width": "Bredde",
"ui.workspace": "arbejdsområde",
"ui.workspace_animation_description": "Eksploderede visninger, bevægelsesstudier og storyboards",
"ui.workspace_available": "Tilgængelig",
+631 -3
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -17,6 +17,8 @@
"cmd.sketch_slot_center_point": "Centre Point Slot",
"cmd.sketch_slot_center_to_center": "Centre to Centre Slot",
"pattern.alignment_hint": "Counts include the original. Centre balances copies; Flip chooses the extra side for even totals.",
"prefs.sketch_tracking_guides": "Centre and midpoint alignment guides",
"prefs.sketch_tracking_guides_note": "Hover over a circle centre or straight-edge midpoint, then move horizontally or vertically to show a temporary dotted guide.",
"prefs.theme_follow": "Follow a theme file",
"prefs.theme_follow_error": "Not applied: {error}. The last good theme stays on.",
"prefs.theme_follow_launch": "Followed for this run only (--theme-file); reloaded whenever another tool rewrites it.",
+519 -1
View File
File diff suppressed because it is too large Load Diff
+202 -1
View File
@@ -1,4 +1,5 @@
{
"(active rule)": "(regla activa)",
"0 turns it off": "0 lo desactiva",
"1. Open GitHub draft below, then paste the report copied to your clipboard.": "1. Abre el borrador de GitHub de abajo y pega el informe copiado al portapapeles.",
"1. Open GitHub draft below. Your title and report will be filled in.": "1. Abre el borrador de GitHub de abajo. El título y el informe se rellenarán automáticamente.",
@@ -26,6 +27,7 @@
"All open designs": "Todos los diseños abiertos",
"Allowed expressions, separated by semicolons": "Expresiones permitidas, separadas por punto y coma",
"Also deletes": "También elimina",
"Also place them from the origin (fully constrained)": "Situarlas también desde el origen (totalmente restringidas)",
"Angle 2": "Ángulo 2",
"Animate": "Animar",
"Appearance name": "Nombre de apariencia",
@@ -35,12 +37,16 @@
"Apply your appearance first. Exports assigned appearances and materials created in this design.": "Aplique primero la apariencia. Exporta las apariencias asignadas y los materiales creados en este diseño.",
"Arc length": "Longitud del arco",
"Area": "Área",
"As Picked": "Según la selección",
"As-Built": "Tal como se construyó",
"Assign Rule": "Asignar regla",
"Attachment": "Vinculación",
"BLEND SURFACE": "SUPERFICIE DE TRANSICIÓN",
"BOUNDARY SURFACE": "SUPERFICIE DE CONTORNO",
"BROWSER": "EXPLORADOR",
"Ball": "Rótula",
"Base Height": "Altura de la base",
"Bend Line": "Línea de plegado",
"Bend Line Position": "Posición de la línea de plegado",
"Bend Position": "Posición del pliegue",
"Bend Radius": "Radio de plegado",
@@ -48,6 +54,7 @@
"Bends": "Pliegues",
"Bodies": "Cuerpos",
"Body": "Cuerpo",
"Both": "Ambos",
"Boundary": "Contorno",
"Bounding box": "Caja delimitadora",
"CHECK": "COMPROBAR",
@@ -70,6 +77,7 @@
"Checked": "Comprobado",
"Choose a new plane. Sketch geometry and dimensions stay unchanged in its two-dimensional coordinates.": "Elige un plano nuevo. La geometría y las cotas del boceto se mantienen en sus coordenadas bidimensionales.",
"Choose…": "Elegir…",
"Circle or sphere": "Círculo o esfera",
"Circular": "Circular",
"Circumference": "Circunferencia",
"Clockwise": "Horario",
@@ -81,6 +89,7 @@
"Config Table": "Tabla de config.",
"Configuration": "Configuración",
"Configuration rules": "Reglas de configuración",
"Constant radius": "Radio constante",
"Contact": "Contacto",
"Contact Sets": "Conjuntos de contacto",
"Contact sets": "Conjuntos de contacto",
@@ -105,6 +114,8 @@
"Curvature (G2)": "Curvatura (G2)",
"Curvature change (G3)": "Cambio de curvatura (G3)",
"Customize Toolbar": "Personalizar barra de herramientas",
"Cylindrical": "Cilíndrica",
"Deboss": "Grabado",
"Delete": "Eliminar",
"Delete all": "Eliminar todo",
"Delete rule": "Eliminar regla",
@@ -114,6 +125,7 @@
"Dependents": "Dependientes",
"Designs you open or save appear here.": "Aquí aparecen los diseños que abras o guardes.",
"Determined by To Object. Choose Angle to edit the angular extent.": "Determinado por «Hasta objeto». Elige «Ángulo» para modificar la extensión angular.",
"Dimension new shapes": "Acotar las formas nuevas",
"Direction": "Dirección",
"Discard": "Descartar",
"Do not export hidden edges": "No exportar aristas ocultas",
@@ -122,6 +134,9 @@
"Double-clicking the middle button in the view: Home (the home view, framing what is shown), Fit (frame what is shown, keeping the orientation) or nothing": "Doble clic con el botón central en la vista: Inicio (vista inicial que encuadra lo visible), Ajustar (encuadrar sin cambiar la orientación) o nada",
"Drive Joint": "Accionar unión",
"Duration": "Duración",
"Each new shape is also dimensioned from the sketch origin until nothing of it is left free. A shape already attached to the origin or to placed geometry gets none.": "Cada forma nueva también se acota desde el origen del croquis hasta que no quede nada libre. Una forma ya unida al origen o a geometría situada no recibe ninguna.",
"Each shape you draw gets all its dimensions, at the sizes you drew (typed values win). A size the sketch already sets is left out.": "Cada forma que dibujas recibe todas sus cotas con los tamaños dibujados (los valores escritos tienen prioridad). Se omite un tamaño que el croquis ya fija.",
"Edge": "Arista",
"Edges": "Aristas",
"Edit": "Editar",
"Edit Profile Sketch": "Editar boceto del perfil",
@@ -129,6 +144,7 @@
"Enabled": "Activado",
"End bulge": "Abombamiento final",
"End continuity": "Continuidad final",
"Equal Distance": "Distancia igual",
"Explode": "Explosionar",
"Explode Text": "Descomponer texto",
"Export Animation…": "Exportar animación…",
@@ -148,6 +164,8 @@
"Face attachment lost": "Se ha perdido la vinculación de la cara",
"Faces": "Caras",
"Faces / edges / vertices": "Caras / aristas / vértices",
"Faces/Body": "Caras/Cuerpo",
"Factor must be a positive number": "El factor debe ser un número positivo",
"Fastener": "Sujeción",
"Favorites": "Favoritos",
"Favourite": "Favorito",
@@ -156,20 +174,28 @@
"Filter": "Filtrar",
"Find in Browser": "Buscar en el explorador",
"Finish": "Acabado",
"First edge": "Primera arista",
"First point": "Primer punto",
"Flange Gap": "Separación de pestaña",
"Flat Pattern": "Desarrollo plano",
"Flat size": "Tamaño del desarrollo",
"Follow camera (Look At sketches)": "Seguir cámara (orientar hacia los bocetos)",
"Follow the camera (Look At sketches)": "Seguir la cámara (orientar hacia los bocetos)",
"Font": "Fuente",
"Free Move": "Movimiento libre",
"From Bodies": "Desde cuerpos",
"From Snap": "Desde el enganche",
"From edges": "Aristas de origen",
"Full Length": "Longitud total",
"Gap": "Separación",
"Grid": "Cuadrícula",
"HISTORY": "HISTORIAL",
"Height": "Altura",
"Hem Gap": "Separación de reborde",
"Hidden edges": "Aristas ocultas",
"History layout": "Disposición del historial",
"Hole Depth": "Profundidad del agujero",
"Hole Diameter": "Diámetro del agujero",
"Holes": "Agujeros",
"Holes (edges on them)": "Agujeros (aristas que contienen)",
"Home view": "Vista de inicio",
@@ -185,10 +211,14 @@
"Isocurve": "Isocurva",
"Issue title": "Título de la incidencia",
"JOINTS": "UNIONES",
"Joint 1": "Unión 1",
"Joint 2": "Unión 2",
"Joint Origin1": "Origen de unión1",
"K Factor": "Factor K",
"Keep (points on it)": "Conservar (puntos sobre ella)",
"Keep Tools": "Conservar herramientas",
"Keep of the other surface": "Conservar de la otra superficie",
"Knife Edge": "Borde afilado",
"LIBRARY": "BIBLIOTECA",
"LINKS": "VÍNCULOS",
"Later": "Más tarde",
@@ -199,7 +229,9 @@
"Letter Spacing": "Espaciado entre letras",
"Library": "Biblioteca",
"Library file": "Archivo de biblioteca",
"Library response is missing": "Falta la respuesta de la biblioteca",
"Line Spacing": "Interlineado",
"Line on plane": "Línea en plano",
"Local library": "Biblioteca local",
"Loop": "Bucle",
"MANAGE": "GESTIONAR",
@@ -213,9 +245,12 @@
"Material": "Material",
"Material copied. Existing body assignments are unchanged.": "Material copiado. Se conservan las asignaciones actuales de los cuerpos.",
"Max": "Máx.",
"Max Thickness": "Espesor máx.",
"Mid Radius": "Radio intermedio",
"Middle double-click": "Doble clic central",
"Min": "Mín.",
"Min Draft": "Ángulo de salida mín.",
"Min Thickness": "Espesor mín.",
"Mitre": "Inglete",
"Model Parameters": "Parámetros del modelo",
"Modeled": "Modelado",
@@ -230,6 +265,7 @@
"Name": "Nombre",
"Name on import": "Nombre al importar",
"Nearest": "Más cercano",
"Neutral plane": "Plano neutro",
"New": "Nuevo",
"New Comp.": "Nuevo comp.",
"New Sketch": "Nuevo boceto",
@@ -240,6 +276,7 @@
"No matching appearances": "No hay apariencias coincidentes",
"No matching physical materials.": "No hay materiales físicos coincidentes.",
"No visible bodies or sketches to export.": "No hay cuerpos ni bocetos visibles para exportar.",
"Nominal Radius": "Radio nominal",
"None": "Ninguno",
"Not available yet": "Todavía no disponible",
"Notch": "Muesca",
@@ -255,19 +292,25 @@
"Overall length": "Longitud total",
"Param. Graph": "Gráfico de parám.",
"Parameter": "Parámetro",
"Part length must be greater than zero and at most 2000 mm": "La longitud de la pieza debe ser mayor que cero y como máximo 2000 mm",
"Parts": "Piezas",
"Pass through": "Pasante",
"Path": "Trayectoria",
"Pattern": "Patrón",
"Per Edge": "Por arista",
"Physical material definitions": "Definiciones de materiales físicos",
"Pick a part size": "Elige un tamaño de pieza",
"Pick the tool bodies": "Selecciona los cuerpos herramienta",
"Picked": "Seleccionado",
"Picked point": "Punto seleccionado",
"Pin-slot": "Pasador-ranura",
"Place at the origin instead": "Colocar en el origen",
"Planar": "Plana",
"Plastic Rules": "Reglas de plástico",
"Playback": "Reproducción",
"Plot": "Graficar",
"Point on line": "Punto en línea",
"Point on plane": "Punto en plano",
"Position": "Posición",
"Position (0 to 1)": "Posición (de 0 a 1)",
"Position (G0)": "Posición (G0)",
@@ -277,6 +320,7 @@
"Preview leaves the current design unchanged.": "La vista previa no modifica el diseño actual.",
"Profiles/Curves": "Perfiles/curvas",
"Quantity": "Cantidad",
"Quantity must be at least 2": "La cantidad debe ser al menos 2",
"RECENT": "RECIENTES",
"REFERENCE": "REFERENCIA",
"RULED SURFACE": "SUPERFICIE REGLADA",
@@ -288,6 +332,8 @@
"Recover unsaved design?": "¿Recuperar el diseño sin guardar?",
"Rectangular": "Rectangular",
"Reference face": "Cara de referencia",
"Relief Depth": "Profundidad de alivio",
"Relief Width": "Ancho de alivio",
"Remove Tools": "Eliminar herramientas",
"Remove from list": "Quitar de la lista",
"Remove override": "Quitar anulación",
@@ -304,6 +350,7 @@
"Restore the inherited component or physical material appearance": "Restaurar la apariencia heredada del componente o del material físico",
"Result": "Resultado",
"Retake screenshot": "Repetir captura de pantalla",
"Reveal Height": "Altura del escalón",
"Reverse": "Invertir",
"Reverse Direction": "Invertir dirección",
"Revert": "Revertir",
@@ -311,7 +358,10 @@
"Revert Pos.": "Revertir pos.",
"Revert Position": "Revertir posición",
"Review the report and screenshot before opening GitHub.": "Revisa el informe y la captura antes de abrir GitHub.",
"Revolute": "Revolución",
"Rigid": "Rígida",
"Rim Edge": "Arista del borde",
"Rim face": "Cara del borde",
"Roll History Marker Here": "Desplazar marcador de la línea de tiempo hasta aquí",
"Round": "Redondo",
"Rule": "Regla",
@@ -328,11 +378,22 @@
"Search": "Buscar",
"Search commands": "Buscar comandos",
"Search this library": "Buscar en esta biblioteca",
"Second edge": "Segunda arista",
"Second point": "Segundo punto",
"Section": "Sección",
"Section position": "Posición de la sección",
"Select Other: hold the left button still on the model (or right-click › Select Other…) to list everything under the cursor; click again on the same spot to select the next thing there. Double-click the middle button to go Home (Preferences › Navigation).": "Seleccionar otro: mantén pulsado el botón izquierdo sobre el modelo (o haz clic derecho › Seleccionar otro…) para ver todo lo que hay bajo el cursor; vuelve a pulsar en el mismo lugar para seleccionar el siguiente elemento. Haz doble clic con el botón central para volver a Inicio (Preferencias › Navegación).",
"Select bodies (a face picks its body)": "Selecciona cuerpos (al seleccionar una cara se selecciona su cuerpo)",
"Select bodies or faces instead": "Selecciona cuerpos o caras en su lugar",
"Select points of the sketch being edited": "Selecciona puntos del boceto que se está editando",
"Select the centre the pattern turns around first": "Selecciona primero el centro alrededor del cual gira el patrón",
"Select the curves to offset first": "Selecciona primero las curvas que se van a desfasar",
"Select the mirror line": "Selecciona la línea de simetría",
"Select the sketch curves or points to mirror first": "Selecciona primero las curvas o puntos del boceto que se van a reflejar",
"Select the sketch curves or points to move first": "Selecciona primero las curvas o puntos del boceto que se van a mover",
"Select the sketch curves or points to pattern first": "Selecciona primero las curvas o puntos del boceto para el patrón",
"Select the sketch curves or points to scale first": "Selecciona primero las curvas o puntos del boceto que se van a escalar",
"Select the sketch curves or points to transform first": "Selecciona primero las curvas o puntos del boceto que se van a transformar",
"Selection filter": "Filtro de selección",
"Semantic faces share their appearance across instances.": "Las caras semánticas comparten su apariencia entre instancias.",
"Send your report on GitHub": "Enviar tu informe a GitHub",
@@ -350,8 +411,11 @@
"Sketch geometry and profiles": "Geometría y perfiles del boceto",
"Sketch plane has no body-face attachment.": "El plano del boceto no está vinculado a ninguna cara del cuerpo.",
"Sketch points": "Puntos del boceto",
"Slider": "Deslizante",
"Slot width": "Anchura de la ranura",
"SolidCraft closed before these designs were saved. Their last autosave can be opened.": "SolidCraft se cerró antes de guardar estos diseños. Puedes abrir su último guardado automático.",
"Spacing 2 must be a non-zero number": "El espaciado 2 debe ser un número distinto de cero",
"Spacing must be a non-zero number": "El espaciado debe ser un número distinto de cero",
"Specialise": "Especializar",
"Speed": "Velocidad",
"Square": "Cuadrado",
@@ -361,6 +425,7 @@
"Start angle": "Ángulo inicial",
"Start bulge": "Abombamiento inicial",
"Start continuity": "Continuidad inicial",
"Stationary Side": "Lado fijo",
"Step": "Paso",
"Steps": "Pasos",
"Stitch the kept pieces": "Coser las piezas conservadas",
@@ -369,29 +434,41 @@
"Style": "Estilo",
"Suppressed": "Suprimido",
"Surface": "Superficie",
"Surfaces": "Superficies",
"Swap Ends": "Intercambiar extremos",
"TRIM": "RECORTAR",
"Tangent (G1)": "Tangencia (G1)",
"Tangent Chain": "Cadena tangente",
"Target Face (optional)": "Cara de destino (opcional)",
"Tear": "Desgarro",
"The dashed sketch is a saved plane guide. Select a new face to repair the attachment.": "El boceto discontinuo sirve de guía del plano guardado. Selecciona una cara nueva para reparar la vinculación.",
"The design changed. Reopen Change Part Size for the component.": "El diseño ha cambiado. Vuelve a abrir Cambiar tamaño de pieza para el componente.",
"The direction must be an axis or a straight sketch curve that lies in the sketch plane": "La dirección debe ser un eje o una curva recta del boceto que esté en el plano del boceto",
"The mirror line cannot also be mirrored": "La línea de simetría no puede reflejarse también",
"The mirror line must be a straight curve of this sketch, not an origin axis": "La línea de simetría debe ser una curva recta de este boceto, no un eje del origen",
"The saved author occurrence is missing. Select a valid author placement before rebinding.": "Falta la instancia de autor guardada. Selecciona una posición de autor válida antes de volver a vincular.",
"Then": "Entonces",
"These features will be deleted:": "Se eliminarán estas operaciones:",
"These features will fail:": "Estas operaciones fallarán:",
"Thickness Outside": "Espesor hacia fuera",
"Thickness Variation": "Variación de espesor",
"Thin": "Delgado",
"Thin Extrude": "Extrusión delgada",
"Third plane": "Tercer plano",
"Third point": "Tercer punto",
"This child is shared. Deleting it removes it from every copy of its parent.": "Este elemento secundario es compartido. Si lo eliminas, desaparecerá de todas las copias de su elemento principal.",
"This child is shared. Position changes apply to every copy of its parent.": "Este elemento secundario es compartido. Los cambios de posición se aplican a todas las copias de su elemento principal.",
"This face cannot provide a durable attachment. Choose another face or explicitly use a fixed plane.": "Esta cara no permite una vinculación persistente. Elige otra cara o utiliza expresamente un plano fijo.",
"Through point": "Por un punto",
"To Offset": "Hasta desfase",
"To Snap": "Hasta el enganche",
"To edges": "Aristas de destino",
"Tolerance": "Tolerancia",
"Too close": "Demasiado cerca",
"Trimming tool (plane, face or curves)": "Herramienta de recorte (plano, cara o curvas)",
"Turn off section analysis before exporting the view.": "Desactiva el análisis de sección antes de exportar la vista.",
"Type": "Tipo",
"Type a distance or an angle to move by": "Escribe una distancia o un ángulo para mover",
"UNTRIM": "ANULAR RECORTE",
"Unit": "Unidad",
"Updating the preview": "Actualizando vista previa",
@@ -420,6 +497,17 @@
"Z angle": "Ángulo Z",
"Z distance": "Distancia Z",
"Zebra": "Cebra",
"`joint` must be an id or a name": "`joint` debe ser un id o un nombre",
"`params` must be an object": "`params` debe ser un objeto",
"`values` must be a list": "`values` debe ser una lista",
"a chamfer needs a corner of exactly two lines": "un chaflán necesita una esquina de exactamente dos líneas",
"a file operation is in progress": "hay una operación de archivo en curso",
"a picked curve is no longer in a sketch": "una curva elegida ya no está en un boceto",
"a picked curve's sketch has not been solved": "el boceto de una curva elegida no se ha resuelto",
"a picked edge has no points": "una arista elegida no tiene puntos",
"a picked edge is gone": "una arista elegida ya no existe",
"a picked edge's body is gone": "el cuerpo de una arista elegida ya no existe",
"add a key for a joint first": "añade primero una clave para una unión",
"angle, height": "ángulo, altura",
"appearance.dielectric_ior": "Índice de refracción dieléctrico",
"appearance.metallic": "Metalicidad",
@@ -428,6 +516,7 @@
"appearance.pbr_opaque": "PBR opaco",
"appearance.roughness": "Rugosidad",
"appearance.surface_response": "Respuesta de la superficie",
"bom.group_children": "Subpiezas en la fila de su pieza",
"browser.body_name": "Cuerpo{number}",
"browser.calibrate_title": "Calibrar: {name}",
"browser.capture_many": "Se han movido {count} componentes, pero sus posiciones no se han capturado.",
@@ -438,6 +527,8 @@
"browser.move_title": "Mover: {name}",
"browser.parameters": "Parámetros ({count})",
"browser.precision": "Precisión: {precision}",
"browser.sketch_attachment_lost": "{name} (fijación perdida)",
"browser.sketch_editing": "{name} (en edición)",
"browser.sketch_name": "Boceto{number}",
"browser.units": "Unidades: {units}",
"cam.flat": "Cara plana",
@@ -447,6 +538,11 @@
"cam.roller": "Rodillo",
"cam.roller_pick": "Rodillo (opcional)",
"cam.tip_pick": "Punta (opcional)",
"choose a profile": "elige un perfil",
"choose the cam's and the follower's joints": "elige las uniones de la leva y del seguidor",
"choose the joints to couple": "elige las uniones que acoplar",
"click a plane or planar face": "hacer clic en un plano o una cara plana",
"click sketch curves": "hacer clic en curvas del boceto",
"cmd.appearance_assign": "Apariencia",
"cmd.appearance_library": "Biblioteca de apariencias",
"cmd.appearance_list": "Listar apariencias",
@@ -884,6 +980,8 @@
"dxf.progress.write": "Escribiendo DXF (5/5)",
"dxf.tolerance": "Tolerancia de curva",
"dxf.tolerance_help": "Solo cuerpos visibles y bocetos mostrados. Las curvas usan segmentos rectos. Una tolerancia menor da curvas más finas y consume más tiempo y memoria.",
"each rail's curves must be in one sketch": "las curvas de cada guía deben estar en un solo boceto",
"feature computation ended without a result": "el cálculo de la operación terminó sin resultado",
"file_load.built": "Construido hasta ahora: {built} de {total} operaciones.",
"file_load.converting": "Convirtiendo sólido {done} de {total}",
"file_load.inserting": "Insertando geometría",
@@ -944,7 +1042,7 @@
"home.new_mm": "Nuevo diseño",
"home.new_mm_hint": "Milímetros · se abre en Diseño",
"home.open": "Abrir…",
"home.open_hint": "Un diseño .solidcraft ({shortcut})",
"home.open_hint": "Un diseño .sc ({shortcut})",
"home.open_now": "Abrir ahora",
"home.opened_days_ago": "Hace {count} días",
"home.opened_hours_ago": "Hace {count} h",
@@ -1078,16 +1176,55 @@
"no hole": "sin agujero",
"no interference": "sin interferencias",
"no joint that moves yet": "todavía no hay ninguna unión móvil",
"no motion study yet": "todavía no hay ningún estudio de movimiento",
"no picture": "sin imagen",
"no such joint": "no existe esa unión",
"none": "ninguno",
"not a move": "no es un movimiento",
"not a number": "no es un número",
"open a sketch first": "abre primero un boceto",
"parts.automatic_name": "automático",
"parts.dimension.across_flats": "Entrecaras",
"parts.dimension.bore": "Diámetro interior",
"parts.dimension.head_diameter": "Diámetro cabeza",
"parts.dimension.head_height": "Altura cabeza",
"parts.dimension.height": "Altura",
"parts.dimension.inner": "Diámetro interior",
"parts.dimension.outer": "Diámetro exterior",
"parts.dimension.socket": "Hexágono interior",
"parts.dimension.socket_depth": "Profundidad hexágono",
"parts.dimension.thickness": "Espesor",
"parts.dimension.width": "Anchura",
"parts.family.bearing": "Rodamiento rígido de bolas (envolvente)",
"parts.family.dowel_pin": "Pasador cilíndrico",
"parts.family.hex_bolt": "Tornillo de cabeza hexagonal",
"parts.family.hex_nut": "Tuerca hexagonal",
"parts.family.set_screw": "Prisionero con hexágono interior, punta plana",
"parts.family.socket_head_cap_screw": "Tornillo cilíndrico con hexágono interior",
"parts.family.washer": "Arandela plana",
"pattern.alignment_2": "Alineación 2",
"pattern.alignment_hint": "Los recuentos incluyen el original. Centrar equilibra las copias; Invertir elige el lado adicional cuando el total es par.",
"pattern.direction_1": "Dirección 1",
"pattern.direction_2": "Dirección 2",
"pattern.flip_direction": "Invertir dirección",
"pick a body or some of its faces": "elige un cuerpo o algunas de sus caras",
"pick a hole to seat it, or OK places it at the origin": "selecciona un agujero para colocarlo o pulsa Aceptar para situarlo en el origen",
"pick a planar face": "elige una cara plana",
"pick a plane or a face as the tool": "elige un plano o una cara como herramienta",
"pick a size": "elige un tamaño",
"pick edges of a body": "elige aristas de un cuerpo",
"pick edges of one body": "elige aristas de un solo cuerpo",
"pick edges of the holes to remove": "elige las aristas de los agujeros que quitar",
"pick faces of one body": "elige caras de un solo cuerpo",
"pick faces to offset": "elige las caras que desfasar",
"pick lines of one sketch": "elige líneas de un solo boceto",
"pick one or two vertices, edges or faces": "selecciona uno o dos vértices, aristas o caras",
"pick one plane or face as the tool, or sketch curves": "elige un plano o una cara como herramienta, o curvas de boceto",
"pick sections in two or more sketches": "elige secciones en dos o más bocetos",
"pick sketch curves or edges": "elige curvas de boceto o aristas",
"pick the face to untrim": "elige la cara a la que quitar el recorte",
"pick what to keep": "elige qué conservar",
"pick what to keep of the other surface": "elige qué conservar de la otra superficie",
"prefs.cpu": "CPU (software)",
"prefs.minutes_suffix": " min",
"prefs.theme_follow": "Seguir un archivo de tema",
@@ -1720,6 +1857,26 @@
"search.suggest": "¿Quisiste decir {label}?",
"search.try": "Escribe el nombre de un comando, una operación de este diseño o un parámetro. Para ejecutar un comando con valores, escribe su id y un objeto JSON: {example}",
"search.valid": "Válido",
"select a direction (an axis, a sketch line or a straight edge) first": "selecciona primero una dirección (un eje, una línea de boceto o una arista recta)",
"select a direction (an axis, a sketch line or a straight edge) for the profile to follow": "selecciona una dirección (un eje, una línea de boceto o una arista recta) que seguirá el perfil",
"select a point on a component": "selecciona un punto en un componente",
"select a profile, edges or sketch lines first": "selecciona primero un perfil, aristas o líneas de boceto",
"select an axis": "selecciona un eje",
"select an axis, a straight or circular edge, or a cylinder, cone or torus face first": "selecciona primero un eje, una arista recta o circular, o una cara cilíndrica, cónica o toroidal",
"select bodies first": "selecciona primero cuerpos",
"select corner points, or the two lines of one corner": "selecciona puntos de esquina, o las dos líneas de una esquina",
"select one corner point, or the two lines of one corner": "selecciona un punto de esquina, o las dos líneas de una esquina",
"select sheet edges first": "selecciona primero aristas de chapa",
"select the bend line (a sketch line) first": "selecciona primero la línea de plegado (una línea de boceto)",
"select the cam's profile (a sketch profile or the cam's edges)": "selecciona el perfil de la leva (un perfil de boceto o las aristas de la leva)",
"select the corner to cut first": "selecciona primero la esquina que cortar",
"select the corners to round first": "selecciona primero las esquinas que redondear",
"select the fixed face first (a plate's large face)": "selecciona primero la cara fija (la cara grande de una placa)",
"select the frame sketch's lines first": "selecciona primero las líneas del boceto del marco",
"select the path (sketch lines across the edge)": "selecciona la trayectoria (líneas de boceto a lo largo de la arista)",
"select the rim face first": "selecciona primero la cara del borde",
"select the sheet edge first": "selecciona primero la arista de la chapa",
"select two components": "selecciona dos componentes",
"settings.display_quality_note": "Los niveles más finos muestran las caras y aristas curvas con mayor suavidad, pero tardan más en generar la malla. Solo cambia el visor, nunca el diseño ni las exportaciones.",
"settings.frame_rate_note": "Muestra los fotogramas por segundo en la esquina inferior derecha de la vista.",
"settings.measure_axis_distances": "Mostrar distancias X/Y/Z",
@@ -1732,16 +1889,22 @@
"settings.reset_intro": "Estos ajustes no funcionan en este ordenador e impedirían iniciar SolidCraft, por lo que se han cambiado:",
"settings.reset_title": "Se han cambiado los ajustes",
"settings.supersampling_note": "Dibuja la vista a mayor resolución y después la reduce: bordes, líneas y cuadrícula más suaves en pantallas inferiores a 4K. Consume recursos de GPU: unos 2,25× píxeles a 1,5× y 4× a 2×.",
"sheet.flange_type_base": "Base",
"sheet.flange_type_contour": "Contorno",
"sheet.flange_type_edge": "Arista",
"shortcut.json_error": "los parámetros deben estar en formato JSON: {error}",
"shortcut.no_command": "no existe el comando `{id}`; el texto anterior al JSON debe ser un ID de comando",
"shortcut.pin": "Fijar en la parte superior del cuadro S",
"shortcut.unpin": "Desfijar",
"sketch is missing": "falta el boceto",
"sketch.degrees_of_freedom": "{count} grados de libertad",
"sketch.dof_left": "Quedan {count} grados de libertad",
"sketch.dof_left_one": "Queda {count} grado de libertad",
"sketch.draw_curves": "Dibujar como {linetype}",
"sketch.make_selection": "Convertir la selección a {linetype}",
"sketch.open_ends": "Abiertos {count}",
"sketch.status_conflict": "restricciones en conflicto",
"sketch.status_fully_constrained": "totalmente restringido",
"sketch.untied_ends": "Sin vincular {count}",
"sketch_panel.attached": "Vinculado a {body} / {path}",
"sketch_panel.author": "Ubicación de autoría: {path}",
@@ -1763,7 +1926,24 @@
"sketch_text.path_hint": "Curva del boceto que seguirá el texto: haz clic aquí y después en la curva",
"sketch_text.use_font_file": "Usar el archivo de fuente {path}",
"solid": "sólido",
"the angle must be a number": "el ángulo debe ser un número",
"the curves must be in one sketch": "las curvas deben estar en un solo boceto",
"the direction must be an axis, a sketch line or a straight edge": "la dirección debe ser un eje, una línea de boceto o una arista recta",
"the duration must be a number of seconds, 0.001 or more": "la duración debe ser un número de segundos, 0.001 o más",
"the line's sketch is gone": "el boceto de la línea ya no existe",
"the lines must be in one sketch": "las líneas deben estar en un solo boceto",
"the lines must be in one sketch, not the section's": "las líneas deben estar en un solo boceto, no en el de la sección",
"the parts library is empty": "la biblioteca de piezas está vacía",
"the parts library is not available": "la biblioteca de piezas no está disponible",
"the path curves must be in one other sketch": "las curvas de la trayectoria deben estar en un solo boceto distinto",
"the path's sketch is gone": "el boceto de la trayectoria ya no existe",
"the position must be a number": "la posición debe ser un número",
"the preview failed": "falló la vista previa",
"the profiles and curves must be in one sketch": "los perfiles y las curvas deben estar en un solo boceto",
"the reference face must be on the edges' body": "la cara de referencia debe estar en el cuerpo de las aristas",
"the scale must be above 0": "la escala debe ser mayor que 0",
"the section's profiles must be in one sketch": "los perfiles de la sección deben estar en un solo boceto",
"the two origins are on the same component": "los dos orígenes están en el mismo componente",
"thread.automatic_size": "Tamaño automático",
"thread.designation": "Designación",
"thread.iso_metric": "Métrica ISO",
@@ -1790,6 +1970,7 @@
"trace.points": "{count} puntos a lo largo de la trayectoria",
"trace.stopped_by_contact": "Termina en la muestra {sample}: {a} atravesaría {b}",
"trace.stopped_by_loop": "Termina en la muestra {sample}: el bucle que pasa por {joint} no puede cerrarse más",
"trim by sketch curves, or by one plane or face": "recorta con curvas de boceto, o con un plano o una cara",
"ui.1_degree_of_freedom": "1 grado de libertad",
"ui.3d_mouse_axes_reassigned": "Los ejes están reasignados en Preferencias, y eso sigue aplicándose sobre esta calibración.",
"ui.3d_mouse_button": "Botón {number}",
@@ -2216,6 +2397,8 @@
"ui.design_properties.revision": "Revisión",
"ui.diameter": "Diámetro",
"ui.dimension": "Cota",
"ui.direct_interaction": "Interacción directa",
"ui.direct_interaction_note": "Trabaja directamente sobre el modelo en la vista. Pulsa una cara plana o un perfil y tira: hacia arriba extruye, hacia abajo dentro de un cuerpo corta, y el movimiento lateral fija el paso",
"ui.direction": "Dirección",
"ui.display_quality": "Calidad de visualización",
"ui.display_quality_coarse": "Baja",
@@ -2239,6 +2422,7 @@
"ui.editJointLimits": "Editar límites de unión",
"ui.edit_section_analysis": "Editar análisis de sección",
"ui.ellipse": "Elipse",
"ui.emboss_wrap_note": "Los perfiles de líneas ortogonales tangentes a un cilindro compatible se envuelven automáticamente. Elegir una pared para definir el destino.",
"ui.end_radius": "Radio final",
"ui.end_scale": "Escala final",
"ui.entities": "Entidades",
@@ -2304,6 +2488,7 @@
"ui.heading_extrude": "EXTRUIR",
"ui.heading_fillet": "REDONDEO",
"ui.heading_finish_sketch": "FINALIZAR BOCETO",
"ui.heading_form": "FORMA",
"ui.heading_front": "FRONTAL",
"ui.heading_hole": "AGUJERO",
"ui.heading_home": "INICIO",
@@ -2352,6 +2537,7 @@
"ui.heading_utilities": "UTILIDADES",
"ui.heading_utility": "UTILIDAD",
"ui.heading_weldments": "SOLDADURA",
"ui.height": "Altura",
"ui.help": "Ayuda",
"ui.hide": "Ocultar",
"ui.hideAxes": "Ocultar ejes",
@@ -2379,11 +2565,14 @@
"ui.intersect": "Intersecar",
"ui.isolate": "Aislar",
"ui.join": "Unir",
"ui.joint_play": "▶ Reproducir",
"ui.joint_stop": "■ Detener",
"ui.joints": "Uniones",
"ui.keyboard_shortcuts": "Atajos de teclado",
"ui.language": "Idioma",
"ui.layout_compact": "Compacta",
"ui.layout_floating": "Flotante",
"ui.length": "Longitud",
"ui.length_decimals": "Decimales de longitud",
"ui.light": "Claro",
"ui.line": "Línea",
@@ -2391,6 +2580,7 @@
"ui.loft": "Solevación",
"ui.look_at": "Mirar hacia",
"ui.look_at_anim_desc": "Vista de eje, Mirar hacia, Inicio y Ajustar",
"ui.major_radius": "Radio mayor",
"ui.manipulator_free_alt": "Arrastre libre del manipulador también con Alt/Option",
"ui.manipulator_free_alt_tip": "Activado: Alt/Option o Ctrl/Cmd sobre las flechas de extrusión / manipulador desactiva el ajuste de valores. Desactivado: solo Ctrl/Cmd.",
"ui.manufacture": "Fabricación",
@@ -2420,8 +2610,10 @@
"ui.mesh_format_3mf": "3MF",
"ui.mesh_format_3mf_tagged": "3MF con etiquetas de cara",
"ui.mesh_format_stl": "STL",
"ui.minor_radius": "Radio menor",
"ui.mirror": "Simetría",
"ui.mirror_line": "Línea de simetría",
"ui.modifiers_either": "{first} o {second}",
"ui.move": "Mover",
"ui.multiple": "Múltiple",
"ui.named_views": "Vistas guardadas",
@@ -2520,6 +2712,7 @@
"ui.reverse_horizontal_pan_direction": "Invertir dirección del desplazamiento horizontal",
"ui.reverse_horizontal_pan_tip": "El desplazamiento horizontal con dos dedos y la rueda de pulgar desplazan en sentido contrario",
"ui.reverse_zoom_direction": "Invertir dirección del zoom",
"ui.revolutions": "Vueltas",
"ui.revolve": "Revolución",
"ui.ribbon_exit": "Salir",
"ui.ribbon_labels": "Mostrar texto bajo los iconos de la cinta",
@@ -2535,6 +2728,7 @@
"ui.scale": "Escala",
"ui.second_rail": "Segunda línea guía",
"ui.section_analysis": "Análisis de sección",
"ui.section_size": "Tamaño de la sección",
"ui.select": "Seleccionar",
"ui.selectOther": "Seleccionar otro…",
"ui.selectTangentChain": "Seleccionar cadena tangente",
@@ -2585,6 +2779,7 @@
"ui.start": "Iniciar",
"ui.start_over": "Volver a empezar",
"ui.start_page": "Página de inicio",
"ui.stitch_tolerance_hint": "estricta",
"ui.stretch": "Estirar",
"ui.supersampling": "Supermuestreo (SSAA)",
"ui.supersampling_adaptive": "Solo cuando la vista está inmóvil",
@@ -2615,6 +2810,8 @@
"ui.to_object": "Hasta objeto",
"ui.tool_direction": "Dirección de herramienta",
"ui.top": "Superior",
"ui.top_diameter": "Diámetro superior",
"ui.top_radius": "Radio superior",
"ui.torus": "Toro",
"ui.total_angle": "Ángulo total",
"ui.trackpad_pan_tip": "Los gestos del panel táctil desplazan la vista (desactivado: hacen zoom como la rueda); la rueda del ratón hace zoom, la rueda lateral desplaza horizontalmente y el gesto de pellizco siempre hace zoom",
@@ -2640,6 +2837,7 @@
"ui.visual_shaded_with_edges": "Sombreado con aristas",
"ui.visual_style": "Estilo visual",
"ui.visual_wireframe": "Estructura alámbrica",
"ui.width": "Anchura",
"ui.workspace": "espacio de trabajo",
"ui.workspace_animation_description": "Vistas explosionadas, estudios de movimiento y guiones gráficos",
"ui.workspace_available": "Disponible",
@@ -2695,5 +2893,8 @@
"update.up_to_date": "SolidCraft está actualizado.",
"update.update_now": "Actualizar ahora",
"update.you_have": "Tienes la versión {version}.",
"use a positive nominal diameter and a pitch smaller than it": "usa un diámetro nominal positivo y un paso menor que él",
"values must be finite numbers": "los valores deben ser números finitos",
"values must be numbers or expressions": "los valores deben ser números o expresiones",
"↑ ↓ choose · Enter / Tab complete · Esc dismiss": "↑ ↓ elegir · Intro / Tab completar · Esc cerrar"
}
+223 -1
View File
@@ -1,4 +1,5 @@
{
"(active rule)": "(règle active)",
"0 turns it off": "0 le désactive",
"1. Open GitHub draft below, then paste the report copied to your clipboard.": "1. Ouvrir le brouillon GitHub ci-dessous, puis coller le rapport copié dans le presse-papiers.",
"1. Open GitHub draft below. Your title and report will be filled in.": "1. Ouvrir le brouillon GitHub ci-dessous. Votre titre et votre rapport y seront déjà remplis.",
@@ -35,6 +36,7 @@
"All open designs": "Toutes les conceptions ouvertes",
"Allowed expressions, separated by semicolons": "Expressions autorisées, séparées par des points-virgules",
"Also deletes": "Supprime aussi",
"Also place them from the origin (fully constrained)": "Les placer aussi depuis l'origine (entièrement contraintes)",
"Anchor": "Ancrage",
"Angle 2": "Angle 2",
"Angle Display": "Affichage de l'angle",
@@ -49,15 +51,19 @@
"Apply your appearance first. Exports assigned appearances and materials created in this design.": "Appliquez d’abord votre apparence. Exporte les apparences attribuées et les matériaux créés dans cette conception.",
"Arc length": "Longueur d'arc",
"Area": "Aire",
"As Picked": "Tel que sélectionné",
"As-Built": "Tel que construit",
"Assign Rule": "Attribuer une règle",
"Attachment": "Rattachement",
"BLEND SURFACE": "SURFACE DE RACCORD",
"BOUNDARY SURFACE": "SURFACE FRONTIÈRE",
"BROWSER": "NAVIGATEUR",
"Ball": "Rotule",
"Bar": "Plat",
"Base Height": "Hauteur de la base",
"Bend": "Angle de pli",
"Bend Edges": "Arêtes de pli",
"Bend Line": "Ligne de pli",
"Bend Line Position": "Position de la ligne de pli",
"Bend Position": "Position du pli",
"Bend Radius": "Rayon de pliage",
@@ -69,6 +75,7 @@
"Body (last if none)": "Corps (le dernier si aucun)",
"Body to split": "Corps à scinder",
"Body, or faces to take out": "Corps, ou faces à retirer",
"Both": "Les deux",
"Bottom Left": "Bas gauche",
"Bottom Middle": "Bas centre",
"Bottom Right": "Bas droite",
@@ -100,6 +107,7 @@
"Choose a new plane. Sketch geometry and dimensions stay unchanged in its two-dimensional coordinates.": "Choisir un nouveau plan. La géométrie et les cotes de l'esquisse restent inchangées dans ses coordonnées bidimensionnelles.",
"Choose…": "Choisir…",
"Circle center": "Centre du cercle",
"Circle or sphere": "Cercle ou sphère",
"Circular": "Circulaire",
"Circumference": "Circonférence",
"Clockwise": "Horaire",
@@ -116,6 +124,7 @@
"Config Table": "Table de config.",
"Configuration": "Configuration",
"Configuration rules": "Règles de configuration",
"Constant radius": "Rayon constant",
"Contact": "Contact",
"Contact Sets": "Jeux de contacts",
"Contact sets": "Jeux de contact",
@@ -150,7 +159,9 @@
"Custom": "Personnalisé",
"Customize Toolbar": "Personnaliser la barre d'outils",
"Customize…": "Personnaliser…",
"Cylindrical": "Pivot glissant",
"Cylindrical face": "Face cylindrique",
"Deboss": "Embossage en creux",
"Delete": "Supprimer",
"Delete Selected Features…": "Supprimer les fonctions sélectionnées…",
"Delete Selected Folders": "Supprimer les dossiers sélectionnés",
@@ -165,6 +176,7 @@
"Designs you open or save appear here.": "Les conceptions que vous ouvrez ou enregistrez apparaissent ici.",
"Determined by To Object. Choose Angle to edit the angular extent.": "Déterminé par Jusqu'à l'objet. Choisir Angle pour modifier l'étendue angulaire.",
"Diameter": "Diamètre",
"Dimension new shapes": "Coter les nouvelles formes",
"Direction": "Direction",
"Discard": "Abandonner",
"Distance": "Distance",
@@ -176,6 +188,9 @@
"Drag to move the hole; click to remove it": "Faire glisser pour déplacer le perçage ; cliquer pour le retirer",
"Drive Joint": "Piloter la liaison",
"Duration": "Durée",
"Each new shape is also dimensioned from the sketch origin until nothing of it is left free. A shape already attached to the origin or to placed geometry gets none.": "Chaque nouvelle forme est aussi cotée depuis l'origine de l'esquisse jusqu'à ce que rien ne reste libre. Une forme déjà liée à l'origine ou à une géométrie placée n'en reçoit aucune.",
"Each shape you draw gets all its dimensions, at the sizes you drew (typed values win). A size the sketch already sets is left out.": "Chaque forme dessinée reçoit toutes ses cotes aux tailles dessinées (les valeurs saisies l'emportent). Une taille déjà fixée par l'esquisse est omise.",
"Edge": "Arête",
"Edges": "Arêtes",
"Edit": "Modifier",
"Edit Profile Sketch": "Modifier l'esquisse du profil",
@@ -184,6 +199,7 @@
"End Radius": "Rayon final",
"End bulge": "Renflement de fin",
"End continuity": "Continuité de fin",
"Equal Distance": "Distance égale",
"Expand": "Développer",
"Expected result (optional)": "Résultat attendu (facultatif)",
"Explode": "Éclater",
@@ -211,6 +227,8 @@
"Faces": "Faces",
"Faces / edges / vertices": "Faces / arêtes / sommets",
"Faces to split": "Faces à scinder",
"Faces/Body": "Faces/Corps",
"Factor must be a positive number": "Le facteur doit être un nombre strictement positif",
"Fastener": "Fixation",
"Favorites": "Favoris",
"Favourite": "Favori",
@@ -220,9 +238,12 @@
"Filter…": "Filtrer…",
"Find in Browser": "Trouver dans le navigateur",
"Finish": "Terminer",
"First edge": "Première arête",
"First plane": "Premier plan",
"First point": "Premier point",
"Fit and G2 corners require Constant radius.": "L'ajustement et les angles G2 nécessitent un rayon constant.",
"Fixed Face": "Face fixe",
"Flange Gap": "Jeu de bord tombé",
"Flange thickness": "Épaisseur d'aile",
"Flanges": "Bords tombés",
"Flat Pattern": "Dépliage",
@@ -230,8 +251,10 @@
"Follow camera (Look At sketches)": "Suivre la caméra (vue normale aux esquisses)",
"Follow the camera (Look At sketches)": "Suivre la caméra (vue normale aux esquisses)",
"Font": "Police",
"Free Move": "Déplacement libre",
"From": "De",
"From Bodies": "À partir de corps",
"From Snap": "Depuis l'accrochage",
"From edges": "Arêtes de départ",
"Full Length": "Longueur totale",
"Full thread depth": "Profondeur de filetage complète",
@@ -243,10 +266,13 @@
"Halo under sketch curves": "Halo sous les courbes d'esquisse",
"Height": "Hauteur",
"Height From": "Hauteur depuis",
"Hem Gap": "Jeu d'ourlet",
"Hidden edges": "Arêtes cachées",
"History layout": "Disposition de l’historique",
"History names": "Noms dans l'historique",
"Hole (optional)": "Perçage (facultatif)",
"Hole Depth": "Profondeur du trou",
"Hole Diameter": "Diamètre du trou",
"Holes": "Trous",
"Holes (edges on them)": "Trous (par leurs arêtes)",
"Home view": "Vue d'accueil",
@@ -269,12 +295,16 @@
"Issue title": "Titre du ticket",
"Items": "Éléments",
"JOINTS": "LIAISONS",
"Joint 1": "Liaison 1",
"Joint 2": "Liaison 2",
"Joint Origin1": "Origine de liaison1",
"K Factor": "Facteur K",
"Keep (points on it)": "À conserver (points dessus)",
"Keep Tools": "Conserver les outils",
"Keep of the other surface": "À conserver de l'autre surface",
"Key a joint's value at this step": "Placer une image clé de la valeur d'une liaison à cette étape",
"Keys": "Images clés",
"Knife Edge": "Arête vive",
"L-Angle": "Cornière",
"LIBRARY": "BIBLIOTHÈQUE",
"LINKS": "LIENS",
@@ -287,9 +317,11 @@
"Letter Spacing": "Espacement des lettres",
"Library": "Bibliothèque",
"Library file": "Fichier de bibliothèque",
"Library response is missing": "La réponse de la bibliothèque est manquante",
"Limits": "Limites",
"Line Spacing": "Interligne",
"Line Type": "Type de ligne",
"Line on plane": "Ligne sur plan",
"Lines": "Lignes",
"Listing the installed fonts…": "Liste des polices installées…",
"Load library": "Charger la bibliothèque",
@@ -309,11 +341,14 @@
"Material Outside": "Matière à l'extérieur",
"Material copied. Existing body assignments are unchanged.": "Matériau copié. Les affectations existantes des corps sont inchangées.",
"Max": "Max",
"Max Thickness": "Épaisseur max.",
"Maximum": "Maximum",
"Mesh body": "Corps maillé",
"Mid Radius": "Rayon intermédiaire",
"Middle double-click": "Double-clic milieu",
"Min": "Min",
"Min Draft": "Dépouille min.",
"Min Thickness": "Épaisseur min.",
"Minimum": "Minimum",
"Mirror Plane": "Plan de symétrie",
"Mitre": "Onglet",
@@ -333,6 +368,7 @@
"Name": "Nom",
"Name on import": "Nom à l'importation",
"Nearest": "Corps le plus proche",
"Neutral plane": "Plan neutre",
"New": "Nouveau",
"New Comp.": "Nouv. comp.",
"New Sketch": "Nouvelle esquisse",
@@ -343,6 +379,7 @@
"No matching appearances": "Aucune apparence correspondante",
"No matching physical materials.": "Aucun matériau physique correspondant.",
"No visible bodies or sketches to export.": "Aucun corps ni esquisse visible à exporter.",
"Nominal Radius": "Rayon nominal",
"Nominal diameter": "Diamètre nominal",
"None": "Aucun",
"Not available yet": "Pas encore disponible",
@@ -371,22 +408,28 @@
"Overall length": "Longueur hors tout",
"Param. Graph": "Graphe param.",
"Parameter": "Paramètre",
"Part length must be greater than zero and at most 2000 mm": "La longueur de la pièce doit être supérieure à zéro et d'au plus 2000 mm",
"Parts": "Pièces",
"Pass through": "Passer par",
"Path": "Trajectoire",
"Pattern": "Répétition",
"Per Edge": "Par arête",
"Physical material definitions": "Définitions de matériaux physiques",
"Pick a part size": "Choisir une taille de pièce",
"Pick the tool bodies": "Choisir les corps outils",
"Picked": "Sélectionnés",
"Picked point": "Point choisi",
"Pin-slot": "Axe-rainure",
"Pitch": "Pas",
"Pivot": "Pivot",
"Place at the origin instead": "Placer plutôt à l'origine",
"Planar": "Plan",
"Plastic Rules": "Règles plastique",
"Play the joint's motion in the view": "Lire le mouvement de la liaison dans la vue",
"Playback": "Lecture",
"Plot": "Graphique",
"Point on line": "Point sur ligne",
"Point on plane": "Point sur plan",
"Position": "Position",
"Position (0 to 1)": "Position (0 à 1)",
"Position (G0)": "Position (G0)",
@@ -399,6 +442,7 @@
"Profiles or curves": "Profils ou courbes",
"Profiles/Curves": "Profils/Courbes",
"Quantity": "Quantité",
"Quantity must be at least 2": "La quantité doit être d'au moins 2",
"RECENT": "RÉCENTS",
"REFERENCE": "RÉFÉRENCE",
"RULED SURFACE": "SURFACE RÉGLÉE",
@@ -412,6 +456,8 @@
"Rectangular": "Rectangulaire",
"Rectangular Tube": "Tube rectangulaire",
"Reference face": "Face de référence",
"Relief Depth": "Profondeur de dégagement",
"Relief Width": "Largeur de dégagement",
"Remove Tools": "Retirer les outils",
"Remove condition": "Supprimer la condition",
"Remove from Folder": "Retirer du dossier",
@@ -437,6 +483,7 @@
"Restore this studio's tools": "Restaurer les outils de ce studio",
"Result": "Résultat",
"Retake screenshot": "Reprendre la capture d'écran",
"Reveal Height": "Hauteur de décroché",
"Reverse": "Inverser",
"Reverse Direction": "Inverser la direction",
"Revert": "Rétablir",
@@ -445,12 +492,15 @@
"Revert Position": "Rétablir la position",
"Review the report and screenshot before opening GitHub.": "Relisez le rapport et la capture d'écran avant d'ouvrir GitHub.",
"Review your report on GitHub and click Submit new issue to publish it.": "Vérifiez votre rapport sur GitHub et cliquez sur Submit new issue pour le publier.",
"Revolute": "Pivot",
"Rib Length": "Longueur de nervure",
"Rib Offset": "Décalage de nervure",
"Rib Thickness": "Épaisseur de nervure",
"Ribs": "Nervures",
"Right Middle": "Milieu droite",
"Rigid": "Rigide",
"Rim Edge": "Arête du bord",
"Rim face": "Face de bord",
"Ring of tools on the right button": "Anneau d'outils sur le bouton droit",
"Roll Back Here": "Revenir ici dans l'historique",
"Roll History Marker Here": "Placer le marqueur d'historique ici",
@@ -475,7 +525,9 @@
"Search": "Rechercher",
"Search commands": "Rechercher des commandes",
"Search this library": "Rechercher dans cette bibliothèque",
"Second edge": "Deuxième arête",
"Second plane": "Second plan",
"Second point": "Deuxième point",
"Section": "Coupe",
"Section (optional)": "Section (facultative)",
"Section position": "Position de la section",
@@ -485,6 +537,15 @@
"Select bodies (a face picks its body)": "Sélectionner des corps (une face sélectionne son corps)",
"Select bodies or faces instead": "Sélectionner plutôt des corps ou des faces",
"Select edges": "Sélectionner des arêtes",
"Select points of the sketch being edited": "Sélectionner des points de l'esquisse en cours de modification",
"Select the centre the pattern turns around first": "Sélectionner d'abord le centre autour duquel la répétition pivote",
"Select the curves to offset first": "Sélectionner d'abord les courbes à décaler",
"Select the mirror line": "Sélectionner la ligne de symétrie",
"Select the sketch curves or points to mirror first": "Sélectionner d'abord les courbes ou points d'esquisse à symétriser",
"Select the sketch curves or points to move first": "Sélectionner d'abord les courbes ou points d'esquisse à déplacer",
"Select the sketch curves or points to pattern first": "Sélectionner d'abord les courbes ou points d'esquisse à répéter",
"Select the sketch curves or points to scale first": "Sélectionner d'abord les courbes ou points d'esquisse à mettre à l'échelle",
"Select the sketch curves or points to transform first": "Sélectionner d'abord les courbes ou points d'esquisse à transformer",
"Selection filter": "Filtre de sélection",
"Semantic faces share their appearance across instances.": "Les faces sémantiques partagent leur apparence entre les instances.",
"Send your report on GitHub": "Envoyer votre rapport sur GitHub",
@@ -504,9 +565,12 @@
"Sketch geometry and profiles": "Géométrie et profils d'esquisse",
"Sketch plane has no body-face attachment.": "Le plan d'esquisse n'est rattaché à aucune face de corps.",
"Sketch points": "Points d'esquisse",
"Slider": "Glissière",
"Slot width": "Largeur de rainure",
"Snap to face and edge centres": "Accrocher aux centres des faces et des arêtes",
"SolidCraft closed before these designs were saved. Their last autosave can be opened.": "SolidCraft s'est fermé avant l'enregistrement de ces conceptions. Leur dernier enregistrement automatique peut être ouvert.",
"Spacing 2 must be a non-zero number": "L'espacement 2 doit être un nombre non nul",
"Spacing must be a non-zero number": "L'espacement doit être un nombre non nul",
"Specialise": "Spécialiser",
"Speed": "Vitesse",
"Splitting tool": "Outil de scission",
@@ -517,6 +581,7 @@
"Start angle": "Angle de départ",
"Start bulge": "Renflement de début",
"Start continuity": "Continuité de début",
"Stationary Side": "Côté fixe",
"Step": "Étape",
"Steps": "Étapes",
"Steps to reproduce (optional)": "Étapes pour reproduire le problème (facultatives)",
@@ -530,6 +595,7 @@
"Suppressed": "Désactivé",
"Surface": "Surface",
"Surface, or faces to turn over": "Surface, ou faces à retourner",
"Surfaces": "Surfaces",
"Swap Ends": "Permuter les extrémités",
"TRIM": "AJUSTER",
"Tangent": "Tangence",
@@ -540,24 +606,34 @@
"Tap drill diameter": "Diamètre de l'avant-trou",
"Target": "Cible",
"Target Body": "Corps cible",
"Target Face (optional)": "Face cible (facultatif)",
"Tear": "Déchirure",
"Technical details": "Détails techniques",
"The dashed sketch is a saved plane guide. Select a new face to repair the attachment.": "L'esquisse en pointillés est un guide de plan enregistré. Sélectionnez une nouvelle face pour réparer le rattachement.",
"The design changed. Reopen Change Part Size for the component.": "La conception a changé. Rouvrir Changer la taille de la pièce pour le composant.",
"The direction must be an axis or a straight sketch curve that lies in the sketch plane": "La direction doit être un axe ou une courbe d'esquisse droite située dans le plan de l'esquisse",
"The mirror line cannot also be mirrored": "La ligne de symétrie ne peut pas être elle-même symétrisée",
"The mirror line must be a straight curve of this sketch, not an origin axis": "La ligne de symétrie doit être une courbe droite de cette esquisse, et non un axe de l'origine",
"The saved author occurrence is missing. Select a valid author placement before rebinding.": "L'occurrence d'auteur enregistrée est introuvable. Sélectionnez un placement d'auteur valide avant de relier.",
"Then": "Alors",
"These features will be deleted:": "Ces fonctions seront supprimées :",
"These features will fail:": "Ces fonctions échoueront :",
"Thickness Outside": "Épaisseur extérieure",
"Thickness Variation": "Variation d'épaisseur",
"Thin": "Mince",
"Thin Extrude": "Extrusion mince",
"Third plane": "Troisième plan",
"Third point": "Troisième point",
"This child is shared. Deleting it removes it from every copy of its parent.": "Cet enfant est partagé. Le supprimer le retire de toutes les copies de son parent.",
"This child is shared. Position changes apply to every copy of its parent.": "Cet enfant est partagé. Les changements de position s'appliquent à toutes les copies de son parent.",
"This face cannot provide a durable attachment. Choose another face or explicitly use a fixed plane.": "Cette face ne peut pas fournir de rattachement durable. Choisissez une autre face ou utilisez explicitement un plan fixe.",
"This image is not attached to GitHub yet. Copy or save it, then attach it on GitHub.": "Cette image n'est pas encore jointe sur GitHub. Copiez-la ou enregistrez-la, puis joignez-la sur GitHub.",
"Thread depth": "Profondeur de filetage",
"Thread diameter": "Diamètre de filetage",
"Through point": "Par un point",
"To": "À",
"To Offset": "Jusqu'au décalage",
"To Snap": "Vers l'accrochage",
"To edges": "Arêtes d'arrivée",
"Toe radius": "Rayon d'extrémité",
"Tolerance": "Tolérance",
@@ -571,6 +647,7 @@
"Trimming tool (plane, face or curves)": "Outil d'ajustement (plan, face ou courbes)",
"Turn off section analysis before exporting the view.": "Désactivez l'analyse de coupe avant d'exporter la vue.",
"Type": "Type",
"Type a distance or an angle to move by": "Saisir une distance ou un angle de déplacement",
"UNTRIM": "ANNULER L'AJUSTEMENT",
"Unit": "Unité",
"Unsuppress": "Réactiver",
@@ -614,6 +691,17 @@
"Z angle": "Angle Z",
"Z distance": "Distance Z",
"Zebra": "Zébrures",
"`joint` must be an id or a name": "`joint` doit être un identifiant ou un nom",
"`params` must be an object": "`params` doit être un objet",
"`values` must be a list": "`values` doit être une liste",
"a chamfer needs a corner of exactly two lines": "un chanfrein nécessite un coin formé d'exactement deux lignes",
"a file operation is in progress": "une opération sur un fichier est en cours",
"a picked curve is no longer in a sketch": "une courbe sélectionnée ne se trouve plus dans une esquisse",
"a picked curve's sketch has not been solved": "l'esquisse d'une courbe sélectionnée n'a pas été résolue",
"a picked edge has no points": "une arête sélectionnée n'a aucun point",
"a picked edge is gone": "une arête sélectionnée n'existe plus",
"a picked edge's body is gone": "le corps d'une arête sélectionnée n'existe plus",
"add a key for a joint first": "ajouter d'abord une clé pour une liaison",
"ai.connected_toast": "SolidCraft est maintenant disponible dans {clients}. Redémarrez-les pour l'utiliser (Paramètres > Assistant).",
"ai.prefs.allow_control": "Autoriser la connexion des agents IA (canal de contrôle / MCP)",
"ai.prefs.allow_control_note": "Ouvre un canal de contrôle limité à cet ordinateur (127.0.0.1, port 27878 ou le suivant disponible). Un programme qui se connecte doit aussi présenter un jeton secret lisible uniquement par votre compte utilisateur, régénéré à chaque démarrage. Prend effet au prochain démarrage de SolidCraft. Désactivé : rien n'écoute, sauf si vous lancez SolidCraft avec --control.",
@@ -650,6 +738,7 @@
"appearance.pbr_opaque": "PBR opaque",
"appearance.roughness": "Rugosité",
"appearance.surface_response": "Réponse de la surface",
"bom.group_children": "Sous-pièces dans la ligne de leur pièce",
"browser.body_name": "Corps{number}",
"browser.calibrate_title": "Calibrer : {name}",
"browser.capture_many": "{count} composants ont été déplacés, mais leurs positions ne sont pas capturées.",
@@ -660,6 +749,8 @@
"browser.move_title": "Déplacer : {name}",
"browser.parameters": "Paramètres ({count})",
"browser.precision": "Précision : {precision}",
"browser.sketch_attachment_lost": "{name} (attache perdue)",
"browser.sketch_editing": "{name} (en cours de modification)",
"browser.sketch_name": "Esquisse{number}",
"browser.units": "Unités : {units}",
"cam.flat": "Plateau",
@@ -669,6 +760,11 @@
"cam.roller": "Galet",
"cam.roller_pick": "Galet (facultatif)",
"cam.tip_pick": "Pointe (facultatif)",
"choose a profile": "choisir un profilé",
"choose the cam's and the follower's joints": "choisir les liaisons de la came et du suiveur",
"choose the joints to couple": "choisir les liaisons à coupler",
"click a plane or planar face": "cliquer sur un plan ou une face plane",
"click sketch curves": "cliquer sur des courbes d'esquisse",
"cmd.appearance_assign": "Apparence",
"cmd.appearance_library": "Bibliothèque d'apparences",
"cmd.appearance_list": "Lister les apparences",
@@ -1139,6 +1235,8 @@
"dxf.progress.write": "Écriture du DXF (5/5)",
"dxf.tolerance": "Tolérance des courbes",
"dxf.tolerance_help": "Corps visibles et esquisses affichées uniquement. Les courbes sont approchées par des segments de droite. Une tolérance plus faible donne des courbes plus fines, au prix de plus de temps et de mémoire.",
"each rail's curves must be in one sketch": "les courbes de chaque rail de guidage doivent être dans une seule esquisse",
"feature computation ended without a result": "le calcul de la fonction s'est terminé sans résultat",
"file.open.drawing_filter": "Conceptions, fichiers CAO, maillages et dessins",
"file_load.built": "Construit jusqu’ici : {built} entités sur {total}.",
"file_load.converting": "Conversion du solide {done} sur {total}",
@@ -1159,28 +1257,44 @@
"from the profile": "depuis le profil",
"from the rule": "selon la règle",
"help.apache": "Licence Apache 2.0",
"help.appearance.assign": "Donne aux corps, faces ou composants sélectionnés une couleur ou l'apparence d'un matériau, sans changer leur poids. À utiliser pour distinguer des pièces ou prévisualiser une finition.",
"help.attributions": "Attributions (ATTRIBUTION.md)",
"help.build": "Version {version} · commit {commit} · compilée le {date}",
"help.connect_note": "Redémarrez chaque assistant pour charger le serveur SolidCraft. Chaque fichier a été sauvegardé en .bak avant d'être modifié.",
"help.connect_title": "Connecter les assistants IA",
"help.face.delete": "Supprime les faces sélectionnées et laisse les faces voisines refermer le vide, ou laisse le trou ouvert. À utiliser pour retirer un arrondi, un trou ou un bossage qui gêne.",
"help.font_details": "L’interface utilise les polices intégrées d’egui (Ubuntu Light et Hack, sous les licences Ubuntu Font Licence et MIT/Bitstream Vera ; Noto Emoji et la police d’icônes emoji, sous OFL et MIT). Le texte des esquisses utilise Liberation Sans (SIL OFL 1.1). Le pack de polices facultatif de The Crafting Apps, craft-fonts (BIZ UDPGothic, Shippori Mincho, BIZ UDMincho, Noto Sans CJK SC, Noto Sans Arabic ; SIL OFL 1.1), n’est pas inclus dans les versions de SolidCraft.",
"help.fonts": "Polices",
"help.licences": "Licences",
"help.material.assign": "Applique le matériau choisi aux corps sélectionnés, par exemple acier, aluminium ou ABS. À utiliser pour que la masse et le poids correspondent à la pièce réelle.",
"help.mit": "Licence MIT",
"help.notice": "NOTICE",
"help.parameters.change": "Ouvre le tableau des valeurs nommées et des expressions qui pilotent les cotes de la conception. À utiliser pour changer une dimension à un seul endroit et faire suivre toutes les fonctions qui l'utilisent.",
"help.solid.align": "Déplace les corps sélectionnés pour qu'un de leurs points, faces ou plans rejoigne un point, une face ou un plan ailleurs. À utiliser pour poser une pièce contre une autre sans mesurer le décalage.",
"help.solid.chamfer": "Coupe les arêtes sélectionnées par un biseau plat de la distance indiquée. À utiliser pour casser des arêtes vives ou faciliter l'entrée d'une goupille ou d'une vis.",
"help.solid.combine": "Joint des corps, les retire d'un corps cible ou ne garde que le volume qu'ils ont en commun, et peut conserver les corps outils. À utiliser pour fusionner des pièces, tailler une forme avec une autre ou repérer où deux corps se recouvrent.",
"help.solid.draft": "Incline les faces sélectionnées de l'angle indiqué, mesuré depuis un plan neutre. À utiliser sur les pièces moulées ou coulées pour qu'elles sortent du moule.",
"help.solid.extrude": "Pousse le profil d'une esquisse en 3D sur une distance, en ajoutant ou en retirant de la matière. À utiliser pour transformer un contour plat en bloc, en bossage ou en poche.",
"help.solid.fillet": "Arrondit les arêtes sélectionnées par un raccord circulaire lisse du rayon indiqué. À utiliser pour adoucir des arêtes vives par souci de solidité, de confort ou d'aspect.",
"help.solid.hole": "Perce un trou rond du diamètre indiqué en un point choisi d'une face. À utiliser pour les passages de vis, les goupilles et autres ouvertures rondes simples.",
"help.solid.loft": "Raccorde en douceur deux profils d'esquisse ou plus, ou un profil et un point, par un solide lissé. À utiliser pour les transitions, entonnoirs, poignées et toute forme dont la section change sur sa longueur.",
"help.solid.mirror": "Crée une copie symétrique des corps ou fonctions sélectionnés par rapport à un plan, et peut la fusionner avec l'original. À utiliser pour les pièces symétriques : on modélise une moitié et on obtient les deux.",
"help.solid.move": "Déplace ou fait tourner les corps sélectionnés, ou une copie, selon la distance et l'angle indiqués. À utiliser pour repositionner un corps ou en créer un second ailleurs.",
"help.solid.offset_face": "Pousse les faces sélectionnées vers l'intérieur ou l'extérieur de la distance indiquée, et les faces voisines suivent. À utiliser pour épaissir une paroi, creuser une poche ou rehausser un bossage sans modifier l'esquisse.",
"help.solid.pattern.circular": "Répète les objets sélectionnés autour d'un axe, selon le nombre et l'angle total indiqués. À utiliser pour les cercles de perçages, rayons, ailettes et dents.",
"help.solid.pattern.rectangular": "Répète les objets sélectionnés dans une ou deux directions, selon le nombre et l'espacement indiqués. À utiliser pour les rangées et grilles de trous, nervures, goupilles ou pieds.",
"help.solid.press_pull": "Ajoute ou retire de la matière quand on fait glisser une face, ou arrondit des arêtes quand on les fait glisser. À utiliser pour des modifications rapides directement sur le modèle.",
"help.solid.remove": "Retire les corps sélectionnés de la conception à partir de ce point de la chronologie ; les étapes précédentes les gardent. À utiliser pour écarter un corps d'aide, comme un outil de découpe devenu inutile.",
"help.solid.replace_face": "Amène les faces planes sélectionnées sur un plan ou une face parallèle, et le corps s'allonge ou se raccourcit pour la rejoindre. À utiliser pour mettre une face au ras d'une autre pièce ou d'un plan de construction.",
"help.solid.revolve": "Fait tourner le profil d'une esquisse autour d'un axe pour obtenir un solide de révolution. À utiliser pour les arbres, boutons, bols et toute pièce ronde autour d'une ligne centrale.",
"help.solid.scale": "Agrandit ou réduit les corps sélectionnés d'un facteur, identique dans toutes les directions ou propre à chaque axe. À utiliser pour redimensionner une forme importée ou compenser un retrait.",
"help.solid.shell": "Évide un solide en laissant des parois de l'épaisseur indiquée, et peut ouvrir les faces choisies. À utiliser pour les boîtes, couvercles et autres pièces à parois minces.",
"help.solid.split_body": "Scinde un corps en corps séparés avec un plan, la face d'un autre corps ou une ligne d'esquisse. À utiliser pour obtenir des pièces imprimées, usinées ou colorées séparément.",
"help.solid.split_face": "Scinde les faces sélectionnées le long d'un plan, de la face d'un autre corps ou de courbes d'esquisse, sans scinder le corps. À utiliser pour donner à une partie de face sa propre dépouille, couleur ou décalage.",
"help.solid.sweep": "Entraîne le profil d'une esquisse le long d'une trajectoire pour obtenir un solide. À utiliser pour les tuyaux, rails, poignées et toute pièce de section constante qui suit une courbe.",
"help.third_party": "Licences tierces",
"help.timeline.compute_all": "Recalcule toutes les fonctions de la chronologie depuis le début. À utiliser pour rafraîchir le modèle et voir quelles fonctions échouent.",
"help.timeline.delete": "Supprime les fonctions sélectionnées de la chronologie ; supprimer une esquisse supprime aussi les fonctions construites à partir d'elle. À utiliser pour retirer une étape devenue inutile.",
"home.back": "Revenir à {name}",
"home.crashes": "Rapports de plantage",
"home.design_workspace": "Conception",
@@ -1211,7 +1325,7 @@
"home.new_mm": "Nouvelle conception",
"home.new_mm_hint": "Millimètres · ouvre l’espace Conception",
"home.open": "Ouvrir…",
"home.open_hint": "Une conception .solidcraft ({shortcut})",
"home.open_hint": "Une conception .sc ({shortcut})",
"home.open_now": "Ouvrir maintenant",
"home.opened_days_ago": "Il y a {count} j",
"home.opened_hours_ago": "Il y a {count} h",
@@ -1340,7 +1454,9 @@
"nav.free_orbit.help": "La souris et la souris 3D tournent en passant par les deux pôles et conservent le roulis. L'alignement des axes avec Maj est désactivé.",
"nav.free_orbit.label": "Orbite libre",
"nav.fusion.help": "Glisser avec le milieu fait un panoramique, Maj+milieu fait orbiter, glisser avec le droit fait orbiter",
"nav.hfss.help": "Alt+glisser gauche fait un panoramique, Maj+Alt+gauche zoome, Ctrl+glisser gauche sur un espace vide fait orbiter",
"nav.inventor.help": "Glisser avec le milieu fait un panoramique, Maj+milieu fait orbiter, Ctrl+milieu zoome, glisser avec le droit fait orbiter",
"nav.maya.help": "Alt+glisser gauche fait orbiter, Alt+milieu fait un panoramique, Alt+droit zoome ; glisser avec le milieu fait aussi un panoramique",
"nav.openscad.help": "Glisser avec le gauche dans le vide fait orbiter, Maj+glisser gauche sélectionne par rectangle, glisser la géométrie d'esquisse la modifie ; glisser avec le droit ou le milieu fait un panoramique, Maj+droit ou Maj+milieu zoome",
"nav.solidworks.help": "Glisser avec le milieu fait orbiter, Ctrl+milieu fait un panoramique, Maj+milieu zoome, glisser avec le droit fait orbiter",
"nav.tinkercad.help": "Glisser avec le droit fait orbiter, glisser avec le milieu ou Maj+droit fait un panoramique",
@@ -1356,9 +1472,34 @@
"no hole": "sans perçage",
"no interference": "aucune interférence",
"no joint that moves yet": "aucune liaison mobile pour l'instant",
"no motion study yet": "pas encore d'étude de mouvement",
"no picture": "aucune image",
"no such joint": "liaison introuvable",
"none": "aucun",
"not a move": "pas un déplacement",
"not a number": "pas un nombre",
"open a sketch first": "ouvrir d'abord une esquisse",
"parts.automatic_name": "automatique",
"parts.dimension.across_flats": "Sur plats",
"parts.dimension.bore": "Alésage",
"parts.dimension.d": "Diamètre nominal",
"parts.dimension.head_diameter": "Diamètre de tête",
"parts.dimension.head_height": "Hauteur de tête",
"parts.dimension.height": "Hauteur",
"parts.dimension.inner": "Diamètre intérieur",
"parts.dimension.outer": "Diamètre extérieur",
"parts.dimension.pitch": "Pas",
"parts.dimension.socket": "Empreinte",
"parts.dimension.socket_depth": "Profondeur empreinte",
"parts.dimension.thickness": "Épaisseur",
"parts.dimension.width": "Largeur",
"parts.family.bearing": "Roulement à billes à gorge profonde (enveloppe)",
"parts.family.dowel_pin": "Goupille cylindrique",
"parts.family.hex_bolt": "Vis à tête hexagonale",
"parts.family.hex_nut": "Écrou hexagonal",
"parts.family.set_screw": "Vis sans tête à six pans creux, bout plat",
"parts.family.socket_head_cap_screw": "Vis à tête cylindrique à six pans creux",
"parts.family.washer": "Rondelle plate",
"pattern.alignment_2": "Alignement 2",
"pattern.alignment_hint": "La quantité inclut l’original. Le centrage répartit les copies de chaque côté ; si la quantité est paire, l’inversion choisit le côté qui reçoit la copie supplémentaire.",
"pattern.direction_1": "Direction 1",
@@ -1374,9 +1515,25 @@
"perf.ui_time": "Temps de l'interface",
"perf.viewport": "Vue 3D",
"perf.worst": "pire",
"pick a body or some of its faces": "choisir un corps ou certaines de ses faces",
"pick a hole to seat it, or OK places it at the origin": "choisir un trou pour la loger, ou OK la place à l'origine",
"pick a planar face": "choisir une face plane",
"pick a plane or a face as the tool": "choisir un plan ou une face comme outil",
"pick a size": "choisir une taille",
"pick edges of a body": "choisir des arêtes d'un corps",
"pick edges of one body": "choisir des arêtes d'un seul corps",
"pick edges of the holes to remove": "choisir les arêtes des perçages à supprimer",
"pick faces of one body": "choisir des faces d'un seul corps",
"pick faces to offset": "choisir les faces à décaler",
"pick lines of one sketch": "choisir des lignes d'une seule esquisse",
"pick one or two vertices, edges or faces": "choisir un ou deux sommets, arêtes ou faces",
"pick one plane or face as the tool, or sketch curves": "choisir un plan ou une face comme outil, ou des courbes d'esquisse",
"pick sections in two or more sketches": "choisir des sections dans au moins deux esquisses",
"pick sketch curves or edges": "choisir des courbes d'esquisse ou des arêtes",
"pick the face to untrim": "choisir la face dont l'ajustement doit être annulé",
"pick the path": "choisir la trajectoire",
"pick what to keep": "choisir ce qu'il faut conserver",
"pick what to keep of the other surface": "choisir ce qu'il faut conserver de l'autre surface",
"prefs.add_item": "Ajouter l'élément",
"prefs.alt_frees_manipulators": "Alt / Option libère aussi les flèches du manipulateur",
"prefs.anti_aliasing_amd_dx12": "L'anticrénelage est à 1× car la vérification au démarrage n'a rien dessiné avec le multiéchantillonnage et a réussi à 1×. Vous pouvez choisir un autre réglage ci-dessus ; redémarrez pour l'appliquer si la vérification réussit.",
@@ -2140,6 +2297,26 @@
"search.try": "Saisissez un nom de commande, une entité de cette conception ou un paramètre. Pour exécuter une commande avec des valeurs, saisissez son id et un objet JSON : {example}",
"search.valid": "Valide",
"section.off_hint": "Aucun plan choisi : OK désactive la coupe.",
"select a direction (an axis, a sketch line or a straight edge) first": "sélectionner d'abord une direction (un axe, une ligne d'esquisse ou une arête droite)",
"select a direction (an axis, a sketch line or a straight edge) for the profile to follow": "sélectionner une direction (un axe, une ligne d'esquisse ou une arête droite) que le profil doit suivre",
"select a point on a component": "sélectionner un point sur un composant",
"select a profile, edges or sketch lines first": "sélectionner d'abord un profil, des arêtes ou des lignes d'esquisse",
"select an axis": "sélectionner un axe",
"select an axis, a straight or circular edge, or a cylinder, cone or torus face first": "sélectionner d'abord un axe, une arête droite ou circulaire, ou une face cylindrique, conique ou torique",
"select bodies first": "sélectionner d'abord des corps",
"select corner points, or the two lines of one corner": "sélectionner des points de coin, ou les deux lignes d'un coin",
"select one corner point, or the two lines of one corner": "sélectionner un point de coin, ou les deux lignes d'un coin",
"select sheet edges first": "sélectionner d'abord des arêtes de tôle",
"select the bend line (a sketch line) first": "sélectionner d'abord la ligne de pli (une ligne d'esquisse)",
"select the cam's profile (a sketch profile or the cam's edges)": "sélectionner le profil de la came (un profil d'esquisse ou les arêtes de la came)",
"select the corner to cut first": "sélectionner d'abord le coin à chanfreiner",
"select the corners to round first": "sélectionner d'abord les coins à arrondir",
"select the fixed face first (a plate's large face)": "sélectionner d'abord la face fixe (la grande face d'une plaque)",
"select the frame sketch's lines first": "sélectionner d'abord les lignes de l'esquisse de la structure",
"select the path (sketch lines across the edge)": "sélectionner la trajectoire (lignes d'esquisse qui traversent l'arête)",
"select the rim face first": "sélectionner d'abord la face du bord",
"select the sheet edge first": "sélectionner d'abord l'arête de la tôle",
"select two components": "sélectionner deux composants",
"set by the sketch's lines": "défini par les lignes de l'esquisse",
"settings.display_quality_note": "Les niveaux plus fins affichent plus lisses les faces et arêtes courbes, mais leur maillage prend plus de temps. Seule la vue change, jamais la conception ni les exports.",
"settings.frame_rate_details_note": "Ajoute un graphe des temps des dernières images avec les triangles dessinés superposés, un histogramme des temps d'image et ce que le GPU a dessiné. Cliquez sur la fréquence d'images dans la vue pour les afficher ou les masquer.",
@@ -2157,17 +2334,23 @@
"settings.window_system_details": "Détails",
"settings.window_system_note_now": "S'applique après un redémarrage. Actuellement : {now}.",
"settings.window_system_wayland_limited": "Certaines fonctionnalités sont limitées sous Wayland natif.",
"sheet.flange_type_base": "Base",
"sheet.flange_type_contour": "Contour",
"sheet.flange_type_edge": "Arête",
"sheet.no_body": "il n'y a pas de corps de tôlerie : commencez-en un avec Bord tombé > Base, ou transformez une plaque en tôlerie avec Convertir en tôlerie (choisissez sa grande face plane)",
"shortcut.json_error": "les paramètres doivent être au format JSON : {error}",
"shortcut.no_command": "la commande `{id}` n’existe pas ; le texte avant le JSON doit être un ID de commande",
"shortcut.pin": "Épingler en haut de la boîte S",
"shortcut.unpin": "Désépingler",
"sketch is missing": "l'esquisse est manquante",
"sketch.degrees_of_freedom": "{count} degrés de liberté",
"sketch.dof_left": "{count} degrés de liberté restants",
"sketch.dof_left_one": "{count} degré de liberté restant",
"sketch.draw_curves": "Dessiner en {linetype}",
"sketch.make_selection": "Convertir la sélection en {linetype}",
"sketch.open_ends": "{count} ouvertes",
"sketch.status_conflict": "contraintes en conflit",
"sketch.status_fully_constrained": "entièrement contrainte",
"sketch.untied_ends": "{count} sans coïncidence",
"sketch_panel.attached": "Attaché à {body} / {path}",
"sketch_panel.author": "Placement d’origine : {path}",
@@ -2194,7 +2377,24 @@
"sketch_text.path_hint": "Une courbe de l'esquisse que le texte suit : cliquer ici, puis sur la courbe",
"sketch_text.use_font_file": "Utiliser le fichier de police {path}",
"solid": "plein (sans paroi)",
"the angle must be a number": "l'angle doit être un nombre",
"the curves must be in one sketch": "les courbes doivent être dans une seule esquisse",
"the direction must be an axis, a sketch line or a straight edge": "la direction doit être un axe, une ligne d'esquisse ou une arête droite",
"the duration must be a number of seconds, 0.001 or more": "la durée doit être un nombre de secondes, d'au moins 0.001",
"the line's sketch is gone": "l'esquisse de la ligne n'existe plus",
"the lines must be in one sketch": "les lignes doivent être dans une seule esquisse",
"the lines must be in one sketch, not the section's": "les lignes doivent être dans une seule esquisse, pas celle de la section",
"the parts library is empty": "la bibliothèque de pièces est vide",
"the parts library is not available": "la bibliothèque de pièces n'est pas disponible",
"the path curves must be in one other sketch": "les courbes de la trajectoire doivent être dans une seule autre esquisse",
"the path's sketch is gone": "l'esquisse de la trajectoire n'existe plus",
"the position must be a number": "la position doit être un nombre",
"the preview failed": "l'aperçu a échoué",
"the profiles and curves must be in one sketch": "les profils et les courbes doivent être dans une seule esquisse",
"the reference face must be on the edges' body": "la face de référence doit appartenir au corps des arêtes",
"the scale must be above 0": "l'échelle doit être supérieure à 0",
"the section's profiles must be in one sketch": "les profils de la section doivent être dans une seule esquisse",
"the two origins are on the same component": "les deux origines se trouvent sur le même composant",
"thread.automatic_size": "Taille automatique",
"thread.designation": "Désignation",
"thread.iso_metric": "Métrique ISO",
@@ -2222,6 +2422,7 @@
"trace.points": "{count} points le long de la trajectoire",
"trace.stopped_by_contact": "Se termine à l'échantillon {sample} : {a} traverserait {b}",
"trace.stopped_by_loop": "Se termine à l'échantillon {sample} : la boucle passant par {joint} ne peut plus se fermer",
"trim by sketch curves, or by one plane or face": "ajuster avec des courbes d'esquisse, ou avec un plan ou une face",
"ui.1_degree_of_freedom": "1 degré de liberté",
"ui.3d_mouse_axes_reassigned": "Les axes sont réattribués dans les Préférences, et cela s'applique toujours en plus de ce calibrage.",
"ui.3d_mouse_button": "Bouton {number}",
@@ -2676,6 +2877,8 @@
"ui.design_properties.revision": "Indice",
"ui.diameter": "Diamètre",
"ui.dimension": "Cote",
"ui.direct_interaction": "Interaction directe",
"ui.direct_interaction_note": "Travailler directement sur le modèle dans la vue. Appuyer sur une face plane ou un profil et tirer : vers le haut extrude, vers le bas dans un corps découpe, et un mouvement latéral règle le pas",
"ui.direction": "Direction",
"ui.display_quality": "Qualité d'affichage",
"ui.display_quality_coarse": "Grossière",
@@ -2699,6 +2902,7 @@
"ui.editJointLimits": "Modifier les limites de liaison",
"ui.edit_section_analysis": "Modifier l'analyse de coupe",
"ui.ellipse": "Ellipse",
"ui.emboss_wrap_note": "Les profils de lignes orthogonales tangents à un cylindre pris en charge s'enroulent automatiquement. Choisir une paroi pour définir une cible.",
"ui.end_radius": "Rayon final",
"ui.end_scale": "Échelle finale",
"ui.entities": "Entités",
@@ -2770,6 +2974,7 @@
"ui.heading_extrude": "EXTRUSION",
"ui.heading_fillet": "CONGÉ",
"ui.heading_finish_sketch": "TERMINER L'ESQUISSE",
"ui.heading_form": "FORME",
"ui.heading_front": "AVANT",
"ui.heading_hole": "PERÇAGE",
"ui.heading_home": "ACCUEIL",
@@ -2818,6 +3023,7 @@
"ui.heading_utilities": "UTILITAIRES",
"ui.heading_utility": "UTILITAIRE",
"ui.heading_weldments": "MÉCANO-SOUDURE",
"ui.height": "Hauteur",
"ui.help": "Aide",
"ui.hide": "Masquer",
"ui.hideAxes": "Masquer les axes",
@@ -2854,11 +3060,14 @@
"ui.intersect": "Intersection",
"ui.isolate": "Isoler",
"ui.join": "Joindre",
"ui.joint_play": "▶ Lire",
"ui.joint_stop": "■ Arrêter",
"ui.joints": "Liaisons",
"ui.keyboard_shortcuts": "Raccourcis clavier",
"ui.language": "Langue",
"ui.layout_compact": "Compacte",
"ui.layout_floating": "Flottante",
"ui.length": "Longueur",
"ui.length_decimals": "Décimales des longueurs",
"ui.light": "Clair",
"ui.line": "Ligne",
@@ -2870,6 +3079,7 @@
"ui.loft": "Lissage",
"ui.look_at": "Vue normale",
"ui.look_at_anim_desc": "Vue d'axe, Vue normale, Accueil et Cadrer",
"ui.major_radius": "Grand rayon",
"ui.manipulator_free_alt": "Glissement libre du manipulateur aussi avec Alt/Option",
"ui.manipulator_free_alt_tip": "Activé : Alt/Option ou Ctrl/Cmd sur les flèches d’extrusion / du manipulateur désactive l’accrochage aux valeurs. Désactivé : Ctrl/Cmd uniquement.",
"ui.manufacture": "Fabrication",
@@ -2899,8 +3109,10 @@
"ui.mesh_format_3mf": "3MF",
"ui.mesh_format_3mf_tagged": "3MF avec étiquettes de faces",
"ui.mesh_format_stl": "STL",
"ui.minor_radius": "Petit rayon",
"ui.mirror": "Symétrie",
"ui.mirror_line": "Ligne de symétrie",
"ui.modifiers_either": "{first} ou {second}",
"ui.move": "Déplacer",
"ui.multiple": "Multiple",
"ui.named_views": "Vues nommées",
@@ -2952,6 +3164,7 @@
"ui.pinToShortcuts": "Épingler aux raccourcis",
"ui.pinToToolbar": "Épingler à la barre d'outils",
"ui.pipe": "Tuyau",
"ui.pitch": "Pas",
"ui.placement": "Placement",
"ui.plane": "Plan",
"ui.plane_at_angle": "Plan incliné",
@@ -3011,6 +3224,7 @@
"ui.reverse_horizontal_pan_direction": "Inverser le sens du panoramique horizontal",
"ui.reverse_horizontal_pan_tip": "Le défilement horizontal à deux doigts et la molette latérale font le panoramique dans l'autre sens",
"ui.reverse_zoom_direction": "Inverser le sens du zoom",
"ui.revolutions": "Tours",
"ui.revolve": "Révolution",
"ui.ribbon_exit": "Quitter",
"ui.ribbon_labels": "Afficher le texte sous les icônes du ruban",
@@ -3026,6 +3240,7 @@
"ui.scale": "Échelle",
"ui.second_rail": "Second rail",
"ui.section_analysis": "Analyse de coupe",
"ui.section_size": "Taille de la section",
"ui.select": "Sélectionner",
"ui.selectOther": "Sélectionner un autre…",
"ui.selectTangentChain": "Sélectionner la chaîne tangente",
@@ -3086,6 +3301,7 @@
"ui.start_page": "Page d’accueil",
"ui.step_values": "Incrémenter les valeurs avec les flèches et la molette",
"ui.step_values_tip": "Dans un champ de valeur en cours de saisie, Haut/Bas modifient un nombre simple de 1 (Maj : 10, Alt : 0,1), de même que la molette de la souris au-dessus du champ. Les expressions restent telles que saisies.",
"ui.stitch_tolerance_hint": "serrée",
"ui.stretch": "Étirer",
"ui.supersampling": "Suréchantillonnage (SSAA)",
"ui.supersampling_adaptive": "Seulement quand la vue est immobile",
@@ -3116,6 +3332,8 @@
"ui.to_object": "Jusqu'à l'objet",
"ui.tool_direction": "Direction de l'outil",
"ui.top": "Dessus",
"ui.top_diameter": "Diamètre supérieur",
"ui.top_radius": "Rayon supérieur",
"ui.torus": "Tore",
"ui.total_angle": "Angle total",
"ui.trackpad_pan_tip": "Les gestes du pavé tactile font un panoramique (désactivé : ils zooment comme la molette) ; la molette zoome, la molette latérale fait un panoramique horizontal, le pincement zoome toujours",
@@ -3144,6 +3362,7 @@
"ui.visual_shaded_with_edges": "Ombré avec arêtes",
"ui.visual_style": "Style visuel",
"ui.visual_wireframe": "Filaire",
"ui.width": "Largeur",
"ui.window_system": "Système de fenêtrage",
"ui.window_system_auto": "Automatique",
"ui.window_system_wayland": "Wayland",
@@ -3204,6 +3423,9 @@
"update.up_to_date": "SolidCraft est à jour.",
"update.update_now": "Mettre à jour maintenant",
"update.you_have": "Vous avez la version {version}.",
"use a positive nominal diameter and a pitch smaller than it": "utiliser un diamètre nominal positif et un pas inférieur à ce diamètre",
"values must be finite numbers": "les valeurs doivent être des nombres finis",
"values must be numbers or expressions": "les valeurs doivent être des nombres ou des expressions",
"web.files.insert_drawings_hint": "Fichiers CAO, maillages, DXF ou SVG dans la conception ouverte",
"web.files.insert_stored_drawings_hint": "Dans la conception ouverte (fichiers CAO, maillages, DXF, SVG)",
"web.open_full": "Ouvrir dans SolidCraft",
+1606 -2
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+1664 -2
View File
File diff suppressed because it is too large Load Diff
+1616 -2
View File
File diff suppressed because it is too large Load Diff
+1631 -2
View File
File diff suppressed because it is too large Load Diff
+519 -1
View File
File diff suppressed because it is too large Load Diff
+493 -1
View File
File diff suppressed because it is too large Load Diff
+1606 -2
View File
File diff suppressed because it is too large Load Diff
+1416 -2
View File
File diff suppressed because it is too large Load Diff
+1662 -2
View File
File diff suppressed because it is too large Load Diff
+14 -1
View File
@@ -26,6 +26,7 @@
"All open designs": "Wszystkie otwarte projekty",
"Allowed expressions, separated by semicolons": "Dozwolone wyrażenia, rozdzielone średnikami",
"Also deletes": "Usuwa również",
"Also place them from the origin (fully constrained)": "Umieść je też względem początku (w pełni związane)",
"Angle 2": "Kąt 2",
"Animate": "Animuj",
"App/system information and command settings are included. Review private details before sharing.": "Dołączone są informacje o aplikacji i systemie oraz ustawienia poleceń. Przed udostępnieniem sprawdź, czy nie ma tam prywatnych danych.",
@@ -118,6 +119,7 @@
"Describe what happened before continuing.": "Zanim przejdziesz dalej, opisz, co się stało.",
"Designs you open or save appear here.": "Tutaj pojawiają się otwierane lub zapisywane projekty.",
"Determined by To Object. Choose Angle to edit the angular extent.": "Wynika z opcji Do obiektu. Wybierz Kąt, aby edytować zakres kątowy.",
"Dimension new shapes": "Wymiaruj nowe kształty",
"Direction": "Kierunek",
"Discard": "Odrzuć",
"Do not export hidden edges": "Nie eksportuj krawędzi niewidocznych",
@@ -131,6 +133,8 @@
"Drag to turn the rest in 5° steps. Hold Alt or Ctrl to turn it freely.": "Przeciągnij, aby obrócić podparcie co 5°. Przytrzymaj Alt lub Ctrl, aby obracać swobodnie.",
"Drive Joint": "Steruj złączem",
"Duration": "Czas trwania",
"Each new shape is also dimensioned from the sketch origin until nothing of it is left free. A shape already attached to the origin or to placed geometry gets none.": "Każdy nowy kształt otrzymuje też wymiary od początku szkicu, aż nic nie pozostanie swobodne. Kształt już połączony z początkiem lub z umieszczoną geometrią nie otrzymuje żadnych.",
"Each shape you draw gets all its dimensions, at the sizes you drew (typed values win). A size the sketch already sets is left out.": "Każdy narysowany kształt otrzymuje wszystkie swoje wymiary w narysowanych rozmiarach (wpisane wartości mają pierwszeństwo). Rozmiar, który szkic już określa, jest pomijany.",
"Edges": "Krawędzie",
"Edit": "Edytuj",
"Edit Profile Sketch": "Edytuj szkic profilu",
@@ -961,7 +965,7 @@
"home.new_mm": "Nowy projekt",
"home.new_mm_hint": "Milimetry · otwiera w obszarze Projektowanie",
"home.open": "Otwórz…",
"home.open_hint": "Projekt .solidcraft ({shortcut})",
"home.open_hint": "Projekt .sc ({shortcut})",
"home.open_now": "Otwórz teraz",
"home.opened_days_ago": "{count} dni temu",
"home.opened_hours_ago": "{count} godz. temu",
@@ -1057,6 +1061,11 @@
"no picture": "brak obrazu",
"none": "brak",
"parts.automatic_name": "automatycznie",
"parts.dimension.d": "Średnica nominalna",
"parts.dimension.height": "Wysokość",
"parts.dimension.pitch": "Skok",
"parts.dimension.thickness": "Grubość",
"parts.dimension.width": "Szerokość",
"pattern.alignment_2": "Wyrównanie 2",
"pattern.alignment_hint": "Liczba obejmuje oryginał. Wyśrodkuj rozkłada kopie po obu stronach; Odwróć wybiera stronę z dodatkową kopią przy parzystej liczbie.",
"pattern.direction_1": "Kierunek 1",
@@ -1893,6 +1902,7 @@
"ui.heading_utilities": "NARZĘDZIA",
"ui.heading_utility": "NARZĘDZIE",
"ui.heading_weldments": "SPAWANIE",
"ui.height": "Wysokość",
"ui.help": "Pomoc",
"ui.hide": "Ukryj",
"ui.hideAxes": "Ukryj osie",
@@ -1931,6 +1941,7 @@
"ui.language": "Język",
"ui.layout_compact": "Kompaktowy",
"ui.layout_floating": "Pływający",
"ui.length": "Długość",
"ui.length_decimals": "Miejsca dziesiętne długości",
"ui.light": "Jasny",
"ui.line": "Linia",
@@ -2019,6 +2030,7 @@
"ui.pinToShortcuts": "Przypnij do skrótów",
"ui.pinToToolbar": "Przypnij do paska narzędzi",
"ui.pipe": "Rura",
"ui.pitch": "Skok",
"ui.placement": "Umiejscowienie",
"ui.placement_handles": "Uchwyty umieszczania",
"ui.placement_handles_tip": "Uchwyty na podglądzie podparcia, występu lub zatrzasku: przeciągnij znacznik, aby przesunąć element po modelu, obróć go pierścieniem",
@@ -2194,6 +2206,7 @@
"ui.visual_shaded_with_edges": "Cieniowany z krawędziami",
"ui.visual_style": "Styl wizualny",
"ui.visual_wireframe": "Model krawędziowy",
"ui.width": "Szerokość",
"ui.workspace": "środowisko pracy",
"ui.workspace_animation_description": "Widoki rozstrzelone, badania ruchu i scenorysy",
"ui.workspace_available": "Dostępne",
+16 -1
View File
@@ -30,6 +30,7 @@
"All open designs": "Todos os projetos abertos",
"Allowed expressions, separated by semicolons": "Expressões permitidas, separadas por ponto e vírgula",
"Also deletes": "Também exclui",
"Also place them from the origin (fully constrained)": "Posicioná-las também a partir da origem (totalmente restritas)",
"Angle 2": "Ângulo 2",
"Animate": "Animar",
"App/system information and command settings are included. Review private details before sharing.": "Informações do aplicativo/sistema e configurações estão incluídas. Revise detalhes privados antes de compartilhar.",
@@ -145,6 +146,7 @@
"Designs you open or save appear here.": "Os projetos que você abrir ou salvar aparecem aqui.",
"Determined by To Object. Choose Angle to edit the angular extent.": "Determinado por Até o objeto. Escolha Ângulo para editar a extensão angular.",
"Diameter": "Diâmetro",
"Dimension new shapes": "Cotar novas formas",
"Direction": "Direção",
"Discard": "Descartar",
"Distance": "Distância",
@@ -155,6 +157,8 @@
"Double-clicking the middle button in the view: Home (the home view, framing what is shown), Fit (frame what is shown, keeping the orientation) or nothing": "Clique duplo com o botão do meio na vista: Início (a vista inicial, enquadrando o que é mostrado), Ajustar (enquadra o que é mostrado, mantendo a orientação) ou nada",
"Drive Joint": "Acionar junta",
"Duration": "Duração",
"Each new shape is also dimensioned from the sketch origin until nothing of it is left free. A shape already attached to the origin or to placed geometry gets none.": "Cada nova forma também recebe cotas a partir da origem do esboço até nada ficar livre. Uma forma já ligada à origem ou a uma geometria posicionada não recebe nenhuma.",
"Each shape you draw gets all its dimensions, at the sizes you drew (typed values win). A size the sketch already sets is left out.": "Cada forma que você desenha recebe todas as suas cotas nos tamanhos desenhados (valores digitados têm prioridade). Um tamanho que o esboço já define é omitido.",
"Edges": "Arestas",
"Edit": "Editar",
"Edit Profile Sketch": "Editar esboço do perfil",
@@ -1074,7 +1078,7 @@
"home.new_mm": "Novo projeto",
"home.new_mm_hint": "Milímetros · abre em Projeto",
"home.open": "Abrir…",
"home.open_hint": "Um projeto .solidcraft ({shortcut})",
"home.open_hint": "Um projeto .sc ({shortcut})",
"home.open_now": "Abrir agora",
"home.opened_days_ago": "Há {count} dias",
"home.opened_hours_ago": "Há {count} h",
@@ -1159,7 +1163,9 @@
"nav.free_orbit.label": "Órbita livre",
"nav.free_orbit.snap_help": "Mouse e mouse 3D giram através dos dois polos e preservam a rotação da imagem. Mantenha Shift pressionado durante uma órbita por arraste para alinhar a direção da vista e a rotação da imagem.",
"nav.fusion.help": "Arrastar com o meio desloca, Shift+meio orbita, arrastar com o direito orbita",
"nav.hfss.help": "Alt+arrastar com o esquerdo desloca, Shift+Alt+esquerdo aplica zoom, Ctrl+arrastar com o esquerdo em área vazia orbita",
"nav.inventor.help": "Arrastar com o meio desloca, Shift+meio orbita, Ctrl+meio aplica zoom, arrastar com o direito orbita",
"nav.maya.help": "Alt+arrastar com o esquerdo orbita, Alt+meio desloca, Alt+direito aplica zoom; arrastar com o meio também desloca",
"nav.openscad.help": "Arrastar com o esquerdo no espaço vazio orbita, Shift+arrastar com o esquerdo seleciona por caixa, arrastar a geometria do esboço a edita; arrastar com o direito ou o meio desloca, Shift+arrastar com o direito ou o meio aplica zoom",
"nav.solidworks.help": "Arrastar com o meio orbita, Ctrl+meio desloca, Shift+meio aplica zoom, arrastar com o direito orbita",
"nav.tinkercad.help": "Arrastar com o direito orbita, arrastar com o meio ou Shift+direito desloca",
@@ -1178,6 +1184,11 @@
"no picture": "sem imagem",
"none": "nenhum",
"parts.automatic_name": "automático",
"parts.dimension.d": "Diâmetro nominal",
"parts.dimension.height": "Altura",
"parts.dimension.pitch": "Passo",
"parts.dimension.thickness": "Espessura",
"parts.dimension.width": "Largura",
"pattern.alignment_2": "Alinhamento 2",
"pattern.alignment_hint": "As contagens incluem o original. Centralizar equilibra as cópias; Inverter escolhe o lado extra para totais pares.",
"pattern.direction_1": "Direção 1",
@@ -2023,6 +2034,7 @@
"ui.heading_utilities": "UTILITÁRIOS",
"ui.heading_utility": "UTILITÁRIO",
"ui.heading_weldments": "SOLDAGEM",
"ui.height": "Altura",
"ui.help": "Ajuda",
"ui.hide": "Ocultar",
"ui.hideAxes": "Ocultar eixos",
@@ -2061,6 +2073,7 @@
"ui.language": "Idioma",
"ui.layout_compact": "Compacto",
"ui.layout_floating": "Flutuante",
"ui.length": "Comprimento",
"ui.length_decimals": "Casas decimais de comprimento",
"ui.light": "Claro",
"ui.line": "Linha",
@@ -2148,6 +2161,7 @@
"ui.pinToShortcuts": "Fixar nos atalhos",
"ui.pinToToolbar": "Fixar na barra de ferramentas",
"ui.pipe": "Tubo",
"ui.pitch": "Passo",
"ui.placement": "Posicionamento",
"ui.plane": "Plano",
"ui.plane_at_angle": "Plano em ângulo",
@@ -2322,6 +2336,7 @@
"ui.visual_shaded_with_edges": "Sombreado com arestas",
"ui.visual_style": "Estilo visual",
"ui.visual_wireframe": "Aramado",
"ui.width": "Largura",
"ui.workspace": "espaço de trabalho",
"ui.workspace_animation_description": "Vistas explodidas, estudos de movimento e storyboards",
"ui.workspace_available": "Disponível",
+958 -2
View File
File diff suppressed because it is too large Load Diff
+853 -2
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+958 -2
View File
File diff suppressed because it is too large Load Diff
+217 -2
View File
@@ -22,10 +22,12 @@
"Add Mid Radius": "Ara yarıçap ekle",
"Add Row": "Satır ekle",
"Add a tool": "Araç ekle",
"Add all bodies": "Tüm gövdeleri ekle",
"Add bend": "Büküm ekle",
"Add condition": "Koşul ekle",
"Add or edit rule": "Kural ekle veya düzenle",
"Add to New Folder": "Yeni Klasöre Ekle",
"Add visible bodies": "Görünür gövdeleri ekle",
"Advanced": "Gelişmiş",
"Against": "Karşı",
"Alignment": "Hizalama",
@@ -35,6 +37,7 @@
"All open designs": "Tüm açık tasarımlar",
"Allowed expressions, separated by semicolons": "Noktalı virgülle ayrılmış izin verilen ifadeler",
"Also deletes": "Bunları da siler",
"Also place them from the origin (fully constrained)": "Orijinden de konumlandır (tam kısıtlı)",
"Anchor": "Çapa",
"Angle 2": "Açı 2",
"Angle Display": "Açı görünümü",
@@ -56,6 +59,7 @@
"BOUNDARY SURFACE": "SINIR YÜZEYİ",
"BROWSER": "TARAYICI",
"Bar": "Çubuk",
"Base Center": "Taban Merkezi",
"Bend": "Büküm",
"Bend Edges": "Büküm kenarları",
"Bend Line Position": "Büküm çizgisi konumu",
@@ -140,6 +144,7 @@
"Create Issue — review draft": "Sorun oluştur — taslağı gözden geçirin",
"Create Issue…": "Sorun Oluştur…",
"Cross curves": "Çapraz eğriler",
"Ctrl+Enter continues on GitHub.": "Ctrl+Enter ile GitHub'da devam edilir.",
"Cube": "Küp",
"Current orthographic view (1:1 mm)": "Geçerli ortografik görünüm (1:1 mm)",
"Current perspective view": "Geçerli perspektif görünüm",
@@ -152,6 +157,7 @@
"Customize…": "Özelleştir…",
"Cylindrical face": "Silindirik yüz",
"Delete": "Sil",
"Delete Folders and Features…": "Klasörleri ve Özellikleri Sil…",
"Delete Selected Features…": "Seçili Özellikleri Sil…",
"Delete Selected Folders": "Seçili Klasörleri Sil",
"Delete all": "Tümünü sil",
@@ -165,6 +171,7 @@
"Designs you open or save appear here.": "Açtığınız veya kaydettiğiniz tasarımlar burada görünür.",
"Determined by To Object. Choose Angle to edit the angular extent.": "Nesneye kadar seçeneğiyle belirlenir. Açısal kapsamı düzenlemek için Açı seçeneğini seçin.",
"Diameter": "Çap",
"Dimension new shapes": "Yeni şekillere ölçü ver",
"Direction": "Yön",
"Discard": "At",
"Distance": "Mesafe",
@@ -181,6 +188,8 @@
"Drag to turn the rest in 5° steps. Hold Alt or Ctrl to turn it freely.": "Dayamayı 5° adımlarla çevirmek için sürükleyin. Serbestçe çevirmek için Alt veya Ctrl tuşunu basılı tutun.",
"Drive Joint": "Bağlantıyı tahrik et",
"Duration": "Süre",
"Each new shape is also dimensioned from the sketch origin until nothing of it is left free. A shape already attached to the origin or to placed geometry gets none.": "Her yeni şekle, serbest bir şey kalmayana kadar çizim orijininden de ölçü verilir. Orijine veya yerleştirilmiş geometriye zaten bağlı bir şekle verilmez.",
"Each shape you draw gets all its dimensions, at the sizes you drew (typed values win). A size the sketch already sets is left out.": "Çizdiğiniz her şekil, çizdiğiniz boyutlarda tüm ölçülerini alır (yazılan değerler önceliklidir). Çizimin zaten belirlediği bir boyut atlanır.",
"Edges": "Kenarlar",
"Edit": "Düzenle",
"Edit Profile Sketch": "Profil eskizini düzenle",
@@ -430,6 +439,7 @@
"Remove this point": "Bu noktayı kaldır",
"Rename Feature": "Özelliği Yeniden Adlandır",
"Rename Folder": "Klasörü Yeniden Adlandır",
"Render Stage": "Render Platosu",
"Reopen designs": "Tasarımları yeniden aç",
"Reopen the designs that were open when SolidCraft was last closed": "SolidCraft son kapatıldığında açık olan tasarımları yeniden aç",
"Replace existing library file": "Mevcut kitaplık dosyasının üzerine yaz",
@@ -534,6 +544,7 @@
"Style": "Stil",
"Summary": "Özet",
"Suppress": "Bastır",
"Suppress Selected Folders": "Seçili Klasörleri Bastır",
"Suppressed": "Bastırılmış",
"Surface": "Yüzey",
"Surface, or faces to turn over": "Yüzey veya çevrilecek yüzler",
@@ -581,6 +592,7 @@
"UNTRIM": "KIRPMAYI KALDIR",
"Unit": "Birim",
"Unsuppress": "Bastırmayı kaldır",
"Unsuppress Selected Folders": "Seçili Klasörlerin Bastırmasını Kaldır",
"Updating the preview": "Önizleme güncelleniyor",
"Use active author placement": "Etkin kaynak yerleşimini kullan",
"Use fixed plane": "Sabit düzlem kullan",
@@ -628,6 +640,8 @@
"ai.prefs.background_commands": "Ajan komutlarını arka planda çalıştır",
"ai.prefs.connect_apps": "SolidCraft'ı bu bilgisayardaki AI uygulamalarına aç",
"ai.prefs.connect_apps_note": "SolidCraft başladığında, bu bilgisayarda bulduğu AI uygulamalarına (OpenCode, Claude Desktop, Claude Code, Cursor, Codex, Gemini CLI, Copilot CLI, Windsurf, Zed, VS Code) onu bir MCP sunucusu olarak ekler; böylece bir ajan kurulum yapmadan kullanabilir. Yalnızca solidcraft girdisi eklenir veya yolu yenilenir; değiştirdiğiniz bir girdiye dokunulmaz ve dosya önce yedeklenir. Kapalı: eklediği girdiler kaldırılır. Yardım > AI asistanlarını bağla… bunu elle yapar.",
"ai.prefs.connect_at_start": "SolidCraft başladığında en son kullanılan ajana bağlan",
"ai.prefs.connect_at_start_note": "SolidCraft her başladığında, en son bağlandığınız ajanı (veya varsayılanı) arka planda başlatır; böylece sohbete hazır olur. SolidCraft --control ile başlatıldığında çalışmaz. Bağlanamazsa Asistan, Bağlantı başarısız mesajını ve bir Yeniden dene düğmesini gösterir.",
"ai.prefs.follow_camera": "Kamerayı eskizlere çevir",
"ai.prefs.follow_camera_off": "Otomatik kamera takibi kapalı.",
"ai.prefs.follow_camera_on": "Kamera, ajanın oluşturduğu eskizleri görecek şekilde döner.",
@@ -635,6 +649,8 @@
"ai.prefs.make_default": "Varsayılan olarak kullan",
"ai.prefs.no_agents": "Henüz ajan yok. Ajan ekleyin veya yüklü ajanları bulmak için yenileyin.",
"ai.prefs.no_saved_approvals": "Kaydedilmiş onay yok.",
"ai.prefs.open_at_start": "SolidCraft başladığında Asistan panelini aç",
"ai.prefs.open_at_start_note": "SolidCraft her başladığında Asistan panelini (veya kendi penceresini) gösterir. SolidCraft --control ile başlatıldığında gösterilmez.",
"ai.prefs.override_all_warning": "Bu ajan, sormadan tasarımı kaydedebilir, üzerine yazabilir, dışa aktarabilir veya değiştirebilir.",
"ai.prefs.permission_all": "Her şeye izin ver",
"ai.prefs.permission_all_summary": "Kullanılabilir SolidCraft araçları sormadan çalışır.",
@@ -679,6 +695,9 @@
"cmd.appearance_assign": "Görünüm",
"cmd.appearance_library": "Görünüm kitaplığı",
"cmd.appearance_list": "Görünümleri listele",
"cmd.appearance_paint": "Görünümü Boya",
"cmd.appearance_pick_up": "Görünümü Al",
"cmd.appearance_replace": "Görünümü Değiştir",
"cmd.assembly_bom": "Malzeme listesi",
"cmd.body_rename": "Gövdeyi yeniden adlandır",
"cmd.browser_collapse_all": "Tümünü Daralt",
@@ -766,6 +785,7 @@
"cmd.document_revision": "Tasarım Revizyonu",
"cmd.document_units": "Tasarımın birimlerini değiştir",
"cmd.edit_checkpoint": "Kontrol noktası",
"cmd.edit_repeat": "Son Komutu Tekrarla",
"cmd.edit_restore_checkpoint": "Kontrol noktasını geri yükle",
"cmd.engine_commands": "Komutları listele",
"cmd.engine_describe": "Komutu açıkla",
@@ -879,9 +899,11 @@
"cmd.plastic_snap_fit": "Geçmeli bağlantı",
"cmd.render_aging_describe": "Katmanlı Yüzey Yaşlanması",
"cmd.render_backends": "Render arka uçları",
"cmd.render_batch": "Tüm Çekimleri Render Et",
"cmd.render_camera_fit": "Render Konusunu Çerçevele",
"cmd.render_camera_get": "Render Kamerasını İncele",
"cmd.render_cancel": "Render'ı iptal et",
"cmd.render_compare": "Görüntüleri Karşılaştır",
"cmd.render_effects_describe": "Mercek ve Yaratıcı Efektler",
"cmd.render_export": "PNG dışa aktar",
"cmd.render_hdr_inspect": "HDR Kaynağını İncele",
@@ -897,6 +919,7 @@
"cmd.render_library_surface_prepare": "Oluşturulmuş Yüzey Haritalarını Hazırla",
"cmd.render_library_surface_unbind": "Yüzey Bağlamını Kaldır",
"cmd.render_library_targets": "Render Kitaplık Hedeflerini Bul",
"cmd.render_lights_solo": "Işığı Solo Yap",
"cmd.render_optics_bind": "Optik Bağlamı Kaydet",
"cmd.render_optics_unbind": "Optik Bağlamı Kaldır",
"cmd.render_preflight": "Render isteğini kontrol et",
@@ -1006,7 +1029,9 @@
"cmd.sketch_spline_control_point": "Kontrol noktalı spline",
"cmd.sketch_spline_control_point_5": "Kontrol noktalı spline (derece 5)",
"cmd.sketch_spline_fit_point": "Uydurma noktalı spline",
"cmd.sketch_spline_insert_point": "Spline Noktası Ekle",
"cmd.sketch_spun_profile": "Döndürülmüş profil",
"cmd.sketch_toggle_diameter": "Yarıçap / Çap Arasında Geçiş Yap",
"cmd.sketch_toggle_driven": "Türetilmiş ölçüyü aç/kapat",
"cmd.sketch_transform": "Dönüşüm",
"cmd.sketch_trim_path": "Yol boyunca buda",
@@ -1072,6 +1097,7 @@
"cmd.view_rename": "Adlandırılmış görünümü yeniden adlandır",
"cmd.view_right": "Sağ Görünüm",
"cmd.view_save": "Yeni adlandırılmış görünüm",
"cmd.view_shots_strip": "Çekim Şeridi",
"cmd.view_spin": "Sürekli döndürme",
"cmd.view_tool": "Gezinme aracı",
"cmd.view_top": "Üst Görünüm",
@@ -1145,6 +1171,7 @@
"document.save_changes": "{name} içindeki değişiklikler kaydedilsin mi?",
"document.save_copy": "Bir Kopya Kaydet…",
"document.unsaved_changes": "{name} kaydedilmemiş değişiklikler içeriyor. Kaydetmezseniz bunlar kaybolur.",
"drive.rigid": "{joint} rijit bir bağlantıdır: parçalarını sabit tutar, bu yüzden tahrik edilecek bir şey yoktur. Hareket etmelerini sağlamak için türünü Bağlantıyı düzenle içinde değiştirin: dönmek için Döner, kaymak için Kayar, ikisi için Silindirik.",
"drive.stopped_by_contact": "{value} değerinde durdu: {a} ile {b} iç içe geçerdi",
"drive.stopped_by_loop": "{value} değerinde durdu: {joint} üzerinden geçen döngü daha fazla kapatılamıyor",
"drive.unconnected": "Hiçbir şey hareket etmiyor: {part} sabitlenmiş hiçbir parçaya bağlı değil",
@@ -1180,28 +1207,44 @@
"from the profile": "profilden",
"from the rule": "kuraldan",
"help.apache": "Apache lisansı 2.0",
"help.appearance.assign": "Seçili gövdelere, yüzlere veya bileşenlere ağırlıklarını değiştirmeden bir renk veya malzeme görünümü verir. Parçaları ayırt etmek veya bir kaplamayı önizlemek için kullanın.",
"help.attributions": "Atıflar (ATTRIBUTION.md)",
"help.build": "Sürüm {version} · commit {commit} · derleme tarihi {date}",
"help.connect_note": "SolidCraft sunucusunu yüklemek için her asistanı yeniden başlatın. Değişmeden önce her dosya .bak olarak yedeklendi.",
"help.connect_title": "AI asistanlarını bağla",
"help.face.delete": "Seçili yüzleri kaldırır ve komşu yüzlerin boşluğu kapatmasını sağlar ya da boşluğu yüzey olarak açık bırakır. Yuvarlatılmış bir kenarı, bir deliği veya yolda duran bir çıkıntıyı gidermek için kullanın.",
"help.font_details": "Arayüz, egui'nin yerleşik yazı tiplerini kullanır (Ubuntu Font Licence ve MIT/Bitstream Vera lisansları altında Ubuntu Light ve Hack; OFL ve MIT altında Noto Emoji ve emoji simge yazı tipi). Eskiz metni Liberation Sans (SIL OFL 1.1) kullanır. The Crafting Apps'in isteğe bağlı yazı tipi paketi craft-fonts (BIZ UDPGothic, Shippori Mincho, BIZ UDMincho, Noto Sans CJK SC, Noto Sans Arabic; SIL OFL 1.1), SolidCraft derlemelerine dahil değildir.",
"help.fonts": "Yazı tipleri",
"help.licences": "Lisanslar",
"help.material.assign": "Seçili gövdelerin neyden yapıldığını belirler: çelik, alüminyum veya ABS gibi. Kütle ve ağırlığın gerçek parçayla uyuşması için kullanın.",
"help.mit": "MIT lisansı",
"help.notice": "NOTICE",
"help.parameters.change": "Tasarımın ölçülerini yöneten adlandırılmış değerlerin ve ifadelerin tablosunu açar. Bir ölçüyü tek yerden değiştirip onu kullanan her özelliğin buna uymasını sağlamak için kullanın.",
"help.solid.align": "Seçili gövdeleri, üzerlerindeki bir nokta, yüz veya düzlem başka bir yerdeki nokta, yüz veya düzlemle buluşacak şekilde taşır. Ofseti ölçmeden bir parçayı diğerinin yanına yerleştirmek için kullanın.",
"help.solid.chamfer": "Seçili kenarları, belirlediğiniz mesafede düz bir pahla keser. Keskin kenarları kırmak veya bir pim ya da vidanın girişini kolaylaştırmak için kullanın.",
"help.solid.combine": "Gövdeleri birleştirir, bir hedef gövdeden çıkarır veya yalnızca paylaştıkları hacmi tutar ve araç gövdelerini tutabilir. Parçaları kaynaştırmak, bir şekli diğeriyle kesmek veya iki gövdenin örtüştüğü yeri bulmak için kullanın.",
"help.solid.draft": "Seçili yüzleri, nötr bir düzlemden ölçülen belirlediğiniz açı kadar eğerek koniklik verir. Kalıplanan veya dökülen parçaların kalıptan kolayca çıkması için kullanın.",
"help.solid.extrude": "Bir eskiz profilini, malzeme ekleyerek veya kaldırarak bir mesafe boyunca 3B'ye taşır. Düz bir konturu blok, kabarıklık veya cep haline getirmek için kullanın.",
"help.solid.fillet": "Seçili kenarları, belirlediğiniz yarıçapta pürüzsüz dairesel bir uyumla yuvarlatır. Keskin kenarları sağlamlık, konfor veya görünüm için yumuşatmak amacıyla kullanın.",
"help.solid.hole": "Bir yüzeyde seçtiğiniz noktada, belirlediğiniz çapta yuvarlak bir delik deler. Vida boşlukları, pimleri ve diğer basit yuvarlak açıklıklar için kullanın.",
"help.solid.loft": "İki veya daha fazla eskiz profili arasında, ya da bir profille bir nokta arasında pürüzsüz bir katı karıştırır. Geçişler, huniler, saplar ve uzunluğu boyunca kesiti değişen şekiller için kullanın.",
"help.solid.mirror": "Seçili gövdelerin veya özelliklerin bir düzlem boyunca ayna görüntüsünü kopyasını oluşturur ve orijinalle birleştirebilir. Simetrik parçalar için kullanın; yarısını modelleyip ikisini de alın.",
"help.solid.move": "Seçili gövdeleri ya da kopyalarını, belirlediğiniz mesafe ve açıyla taşır veya döndürür. Bir gövdenin yerini değiştirmek ya da başka bir yerde ikincisini oluşturmak için kullanın.",
"help.solid.offset_face": "Seçili yüzleri belirlediğiniz mesafe kadar içeri veya dışarı iter, çevrelerindeki yüzler de buna uyar. Eskizi düzenlemeden bir duvarı kalınlaştırmak, bir cebi derinleştirmek veya bir çıkıntıyı yükseltmek için kullanın.",
"help.solid.pattern.circular": "Seçili nesneleri, belirlediğiniz adet ve toplam açı boyunca bir eksen etrafında yineler. Cıvata daireleri, jant kolları, kanatçıklar ve dişler için kullanın.",
"help.solid.pattern.rectangular": "Seçili nesneleri, belirlediğiniz adet ve aralıkla bir veya iki yönde yineler. Delik, nervür, pim veya ayak dizileri ve ızgaraları için kullanın.",
"help.solid.press_pull": "Bir yüzü sürüklerken malzeme ekler veya kaldırır, kenarları sürüklerken yuvarlatır. Doğrudan model üzerinde hızlı değişiklikler için kullanın.",
"help.solid.remove": "Seçili gövdeleri tasarımdan, zaman çizelgesindeki bu noktadan itibaren çıkarır; önceki adımlar onları korur. Artık gerekmeyen bir kesici araç gibi yardımcı bir gövdeyi atmak için kullanın.",
"help.solid.replace_face": "Seçili düz yüzleri bir düzleme veya paralel bir yüze taşır, gövde de onunla buluşmak için büyür veya küçülür. Bir yüzü başka bir parçayla ya da bir yapı düzlemiyle aynı hizaya getirmek için kullanın.",
"help.solid.revolve": "Bir eskiz profilini bir eksen etrafında döndürerek yuvarlak bir katı oluşturur. Miller, topuzlar, kaseler ve bir merkez çizgisi etrafında yuvarlak olan parçalar için kullanın.",
"help.solid.scale": "Seçili gövdeleri bir çarpanla büyütür veya küçültür; her yönde aynı ya da eksen başına ayrı olabilir. İçe aktarılan bir şekli yeniden boyutlandırmak veya büzülme payı bırakmak için kullanın.",
"help.solid.shell": "Bir katıyı içini oyarak boşaltır, belirlediğiniz kalınlıkta duvarlar bırakır ve seçtiğiniz yüzleri açabilir. Kutular, kapaklar ve diğer ince cidarlı parçalar için kullanın.",
"help.solid.split_body": "Bir gövdeyi bir düzlemle, başka bir gövdenin yüzüyle veya bir eskiz çizgisiyle ayrı gövdelere keser. Ayrı ayrı basılan, işlenen veya renklendirilen parçalar elde etmek için kullanın.",
"help.solid.split_face": "Seçili yüzleri, gövdeyi kesmeden bir düzlem, başka bir gövdenin yüzü veya eskiz eğrileri boyunca böler. Bir yüzün bir kısmına kendi koniklik, renk veya ofsetini vermek için kullanın.",
"help.solid.sweep": "Bir eskiz profilini bir yol boyunca sürükleyerek katı oluşturur. Borular, raylar, saplar ve bir eğriyi izleyen sabit kesitli parçalar için kullanın.",
"help.third_party": "Üçüncü taraf lisansları",
"help.timeline.compute_all": "Zaman çizelgesindeki her özelliği baştan yeniden oluşturur. Modeli tazelemek ve hangi özelliklerin başarısız olduğunu görmek için kullanın.",
"help.timeline.delete": "Seçili özellikleri zaman çizelgesinden siler; bir eskizi silmek ondan oluşturulan özellikleri de siler. Artık istenmeyen bir adımı kaldırmak için kullanın.",
"hole_presets.confirm_delete": "Silmeyi onayla",
"hole_presets.delete": "Sil",
"hole_presets.delete_prompt": "Bu kişisel ön ayar silinsin mi? Mevcut delikler değişmez.",
@@ -1252,7 +1295,7 @@
"home.new_mm": "Yeni tasarım",
"home.new_mm_hint": "Milimetre · Tasarım alanında açılır",
"home.open": "Aç…",
"home.open_hint": "Bir .solidcraft tasarımı ({shortcut})",
"home.open_hint": "Bir .sc tasarımı ({shortcut})",
"home.open_now": "Şimdi aç",
"home.opened_days_ago": "{count} gün önce",
"home.opened_hours_ago": "{count} sa. önce",
@@ -1286,6 +1329,9 @@
"install.steps_intro": "Safari web uygulamalarını kendi menüleri üzerinden yükler:",
"install.title": "SolidCraft'ı yükle",
"issue.body_label": "Rapor metni",
"issue.note_changed_while_waiting": "Önizleme beklenirken ayarlar veya model değişti. Teknik ayrıntıları geçerli görünüme göre güncellemek için ekran görüntüsünü yeniden alın.",
"issue.note_details_kept": "Ekran görüntüsü yerel olarak alındı. Düzenlediğiniz teknik ayrıntılar korundu: hâlâ geçerli görünümle uyuştuklarını kontrol edin.",
"issue.note_details_updated": "Teknik ayrıntılar geçerli görünümle uyuşacak şekilde güncellendi. Ekran görüntüsü yerel olarak alındı. GitHub'a eklemeden önce gözden geçirin.",
"issue.note_image_copied": "Görseli GitHub taslağına yapıştırın; görsel kopyalama kullanılamıyorsa PNG'yi kaydedin.",
"issue.note_opened": "GitHub taslağını gözden geçirin ve ekran görüntüsünü ekleyin. GitHub'daki Submit new issue düğmesi raporu yayımlar.",
"issue.note_opened_copied": "Rapor kopyalandı. GitHub taslağına yapıştırın, ekran görüntüsünü ekleyin, ardından GitHub'da Submit new issue düğmesine tıklayın.",
@@ -1352,6 +1398,8 @@
"material.editor.unknown_card": "Mühendislik özellikleri bilinmiyor. Kaydetme yalnızca atanan yoğunluğu ve mevcut görünümü koruyabilir.",
"material.editor.user_supplied": "Kullanıcı tarafından sağlanan",
"material.editor.wood": "Ahşap",
"material.selection.choose": "Bir malzeme seçin",
"material.selection.mixed": "Farklı malzemeler",
"measure.at": "Konum",
"measure.item": "Öğe {number}",
"messages.ago_h": "{n} sa. önce",
@@ -1381,8 +1429,12 @@
"nav.free_orbit.help": "Fare ve 3B fare, her iki kutuptan geçerek döndürür ve yuvarlanmayı korur. Shift eksen hizalama devre dışı.",
"nav.free_orbit.label": "Serbest döndürme",
"nav.free_orbit.snap_help": "Fare ve 3B fare, her iki kutuptan geçerek döndürür ve yuvarlanmayı korur. Görünüm yönünü ve yuvarlanmayı hizalamak için döndürme sürüklemesi sırasında Shift tuşunu basılı tutun.",
"nav.free_orbit_upright.help": "Fareyle yana sürüklemek modeli dünyanın dikey ekseni etrafında döndürür; yukarı ve aşağı sürüklemek tepe noktasını da aşarak sınırsız eğim verir.",
"nav.free_orbit_upright.label": "Dikey eksen etrafında döndür",
"nav.fusion.help": "Orta sürükleme kaydırır, Shift+orta döndürür, sağ sürükleme döndürür",
"nav.hfss.help": "Alt+sol sürükleme kaydırır, Shift+Alt+sol yakınlaştırır, boş alanda Ctrl+sol sürükleme döndürür",
"nav.inventor.help": "Orta sürükleme kaydırır, Shift+orta döndürür, Ctrl+orta yakınlaştırır, sağ sürükleme döndürür",
"nav.maya.help": "Alt+sol sürükleme döndürür, Alt+orta kaydırır, Alt+sağ yakınlaştırır; orta sürükleme ayrıca kaydırır",
"nav.openscad.help": "Boşlukta sol sürükleme döndürür, Shift+sol sürükleme kutu seçimi yapar, eskiz geometrisi sürükleyerek düzenlenir; sağ veya orta sürükleme kaydırır, Shift+sağ veya Shift+orta sürükleme yakınlaştırır",
"nav.perspective.sketch": "Eskiz düzenleme dik görünüm kullanır. Perspektife geçmek için eskizi bitirin.",
"nav.solidworks.help": "Orta sürükleme döndürür, Ctrl+orta kaydırır, Shift+orta yakınlaştırır, sağ sürükleme döndürür",
@@ -1393,6 +1445,93 @@
"nav.touchpad.pan": "Kaydır (Shift tuşunu basılı tutup hareket ettirin; fare tuşu olmadan)",
"nav.touchpad.scroll": "Dokunmatik yüzey yakınlaştırmak için dikey kaydırmayı kullanır. İki parmakla kaydırma diğer ön ayarlar için kayıtlı kalır.",
"nav.touchpad.zoom": "Yakınlaştır (dikey kaydırın veya parmaklarınızı açıp kapatın)",
"navbar.agent_chat": "Asistan sohbet paneli",
"navbar.agent_cursor": "Ajan imlecini göster",
"navbar.ambient_occlusion": "Ortam oklüzyonu",
"navbar.assistant": "Asistan",
"navbar.custom.add_slot": "{slot} ekle",
"navbar.custom.always": "Her zaman görünür",
"navbar.custom.available": "{available} · çubuğa sürükleyin veya Ekle'ye basın",
"navbar.custom.buttons": "Düğmeler",
"navbar.custom.compact": "Kompakt",
"navbar.custom.count": "16 yuvadan {count} tanesi",
"navbar.custom.customise": "Gezinme çubuğunu özelleştir…",
"navbar.custom.design": "Tasarım",
"navbar.custom.duplicate": "Bu yuva zaten çubukta.",
"navbar.custom.fade": "Soldur",
"navbar.custom.full": "Başka bir yuva eklemek için bir yuvayı kaldırın.",
"navbar.custom.hidden_design": "Tasarımda gizli",
"navbar.custom.hidden_render": "Render'da gizli",
"navbar.custom.hide": "Gezinme çubuğunu gizle",
"navbar.custom.hide_idle": "Üzerine gelinceye kadar gizle",
"navbar.custom.icon_only": "Yalnızca simge",
"navbar.custom.icon_value": "Simge ve değer",
"navbar.custom.icons": "Simgeler",
"navbar.custom.idle": "Boştayken",
"navbar.custom.intro": "3B görünümün altındaki çubukta hangi denetimlerin ve hangi sırayla olacağını seçin. Bir yuvayı taşımak için sürükleyin, kaldırmak için çubuğun dışına sürükleyin.",
"navbar.custom.labels": "Simgeler ve etiketler",
"navbar.custom.left": "Sola taşı",
"navbar.custom.position": "Konum",
"navbar.custom.position_centre": "Orta",
"navbar.custom.position_left": "Sol",
"navbar.custom.position_right": "Sağ",
"navbar.custom.preview_as": "Şu şekilde önizle",
"navbar.custom.regular": "Normal",
"navbar.custom.remove": "Kaldır",
"navbar.custom.remove_bar": "Çubuktan kaldır",
"navbar.custom.render": "Render",
"navbar.custom.reset": "Gezinme çubuğunu sıfırla",
"navbar.custom.reset_default": "Varsayılana sıfırla",
"navbar.custom.right": "Sağa taşı",
"navbar.custom.select": "Yuva seçilmedi. Taşımak, kaldırmak veya görünümünü değiştirmek için çubukta bir yuva seçin.",
"navbar.custom.separators_full": "Çubukta zaten dört ayırıcı var.",
"navbar.custom.show": "Gezinme çubuğunu göster",
"navbar.custom.shows": "Gösterim",
"navbar.custom.size": "Boyut",
"navbar.custom.stale": "Çubuk değişti. Yuvayı yeniden seçin.",
"navbar.custom.title": "Gezinme çubuğu",
"navbar.custom.unknown": "Bu yuva kullanılamıyor.",
"navbar.description.ambient_occlusion": "Derinlik katmak için kıvrımları ve köşeleri koyulaştırır.",
"navbar.description.display": "Görünüm ayarlarını barındırır: grafik hazır ayarı, ızgara, zemin gölgesi, ortam oklüzyonu ve projeksiyon.",
"navbar.description.fit": "Seçimi çerçeveler; hiçbir şey seçili değilse tüm modeli.",
"navbar.description.grid": "Zemin ızgarasını gösterir veya gizler.",
"navbar.description.ground_shadow": "Modelin altındaki gölgeyi gösterir veya gizler.",
"navbar.description.home": "Tüm modelin izometrik görünümüne döner.",
"navbar.description.look_at": "Görünümü seçili yüze, düzleme veya açık eskize doğru çevirir.",
"navbar.description.orbit": "Görünümü modelin etrafında döndürür.",
"navbar.description.pan": "Görünümü yana, yukarı veya aşağı kaydırır.",
"navbar.description.projection": "Ortografik ve perspektif görünümler arasında geçiş yapar.",
"navbar.description.separator": "Komşu yuvaları gruplayan ince bir çizgi.",
"navbar.description.spin": "Siz tıklayana veya bir tuşa basana kadar görünümü döndürmeye devam eder.",
"navbar.description.visual_style": "Modelin nasıl çizileceğini değiştirir: gölgeli, tel kafes veya gizli kenarlarla.",
"navbar.description.zoom": "Görünümü modele yaklaştırır veya uzaklaştırır.",
"navbar.display": "Görüntü",
"navbar.fit": "Sığdır",
"navbar.graphics": "Grafik",
"navbar.grid": "Izgara",
"navbar.ground_shadow": "Zemin gölgesi",
"navbar.home": "Ana görünüm",
"navbar.later": "Sonra",
"navbar.look_at": "Bak",
"navbar.more": "Daha fazla",
"navbar.orbit": "Yörünge",
"navbar.orthographic": "Ortografik",
"navbar.pan": "Kaydır",
"navbar.perspective": "Perspektif",
"navbar.preset": "Hazır ayar",
"navbar.projection": "Projeksiyon",
"navbar.projection_heading": "Projeksiyon",
"navbar.separator": "Ayırıcı",
"navbar.show": "Göster",
"navbar.spin": "Sürekli döndür",
"navbar.style.shaded": "Gölgeli",
"navbar.style.shaded_with_edges": "Kenarlı gölgeli",
"navbar.style.shaded_with_hidden_edges": "Gizli kenarlı gölgeli",
"navbar.style.wireframe": "Tel kafes",
"navbar.translucent": "Yarı saydam",
"navbar.value_tip": "{name} · {value}",
"navbar.visual_style": "Görsel stil",
"navbar.zoom": "Yakınlaştır",
"needs two joints": "iki bağlantı gerektirir",
"network.allow_once": "Bir kez izin ver",
"network.always_allow": "Bu sunucuya her zaman izin ver",
@@ -1406,6 +1545,11 @@
"no picture": "resim yok",
"none": "yok",
"parts.automatic_name": "otomatik",
"parts.dimension.d": "Nominal çap",
"parts.dimension.height": "Yükseklik",
"parts.dimension.pitch": "Adım",
"parts.dimension.thickness": "Kalınlık",
"parts.dimension.width": "Genişlik",
"pattern.alignment_2": "Hizalama 2",
"pattern.alignment_hint": "Adet, orijinali içerir. Ortala, kopyaları iki yana dağıtır; çift adetlerde yönü ters çevirme, fazladan kopyanın hangi tarafta olacağını belirler.",
"pattern.direction_1": "Yön 1",
@@ -1432,6 +1576,10 @@
"prefs.assistant": "Asistan",
"prefs.axes": "Eksenler",
"prefs.axis": "Eksen",
"prefs.bodies_folders": "Gövde klasörleri",
"prefs.bodies_folders_always": "Her zaman",
"prefs.bodies_folders_never": "Hiçbir zaman",
"prefs.bodies_folders_several": "Yalnızca birden çok gövde",
"prefs.bottom": "Alt",
"prefs.browser": "Tarayıcı",
"prefs.built_in": "Yerleşik",
@@ -1456,6 +1604,10 @@
"prefs.design_note": "Yeni tasarımların neyle başladığı. Açık tasarımlar kendi ayarlarını korur.",
"prefs.devices": "3B fare",
"prefs.dialog_buttons": "Diyalog düğmeleri",
"prefs.dialogs": "Diyaloglar",
"prefs.dialogs_edge": "Görünümün kenarında",
"prefs.dialogs_left_column": "Sol sütunda",
"prefs.dialogs_note": "Komut diyaloglarının açılacağı yer: görünümün kenarına yerleşik veya tarayıcının ve Geçmiş'in yerine sol sütunda; bunlar diyalog kapanınca eskisi gibi geri gelir.",
"prefs.display": "Görüntü",
"prefs.edges": "Kenarlar ve gölgeleme",
"prefs.extend": "Uzat",
@@ -1515,6 +1667,8 @@
"prefs.opaque": "Opak",
"prefs.orbit_snap": "Bir eksene hizalamak için döndürme sırasında Shift tuşunu basılı tutun.",
"prefs.orientation": "Yönelim",
"prefs.origin_plane_names": "Orijin düzlemi adları",
"prefs.origin_plane_names_note": "Tarayıcıda, diyaloglarda ve listelerde gösterilen adlar. Z yukarı olmak üzere {top} XY, {front} XZ ve {right} YZ'dir. Komutlar, betikler ve kayıtlı tasarımlar XY, XZ ve YZ adlarını korur.",
"prefs.overall_speed": "Genel hız",
"prefs.placement": "Yerleşim",
"prefs.prefer_free_sketch_points": "Noktalar örtüştüğünde hareketli eskiz noktalarını tercih et",
@@ -1528,6 +1682,8 @@
"prefs.saving": "Otomatik kayıt ve kurtarma",
"prefs.scale_note": "Pencerede ayrıca Ctrl + / Ctrl −. Düğmeler %100'de 28 px.",
"prefs.scale_text": "Ölçek ve metin",
"prefs.search": "Ayarlarda ara",
"prefs.search_empty": "Eşleşen ayar yok",
"prefs.select": "Seçim",
"prefs.select_one_item": "Bir öğe seçin",
"prefs.selecting": "Seçme",
@@ -1625,6 +1781,7 @@
"render.aging_target_search": "Gövde adlarını filtrele",
"render.aging_upward": "Yukarı bakan birikim",
"render.all_controls_help": "Tüm geçerli kontrollerin yoğun incelemesi. Bölüm sayfaları, temel isteği değiştirmeden odaklı düzenleme sağlar.",
"render.all_shots_label": "Tüm Çekimler",
"render.appearance_physics_separate": "Görsel görünüm yoğunluk, termal veri veya diğer mühendislik özelliklerini atamaz.",
"render.availability_native": "Yerli kompozisyon; uygulamadan önce inceleyin",
"render.availability_projection": "Desteklenen yansıtma; kapsama ve atlamalara bakın",
@@ -1779,10 +1936,13 @@
"render.effects_reset_lens": "Mercek efektlerini sıfırla",
"render.effects_seed": "Desen tohumu",
"render.export_display": "Dışa aktar: görüntü PNG",
"render.export_image_label": "Görüntüyü Dışa Aktar",
"render.export_linear": "Dışa aktar: ham doğrusal EXR",
"render.exr_pending": "GPU ham doğrusal EXR'ı saklayabilir. Sıkıştırma, çok katmanlı görüntüler ve yardımcı render geçişleri kullanılamamaya devam ediyor.",
"render.film_grain": "Fotoğrafik gren",
"render.fit": "Ürünü sığdır",
"render.fixed_camera": "Kamera",
"render.fixed_world": "Dünya",
"render.flare_ghosts": "Kaynak başına hayalet halka",
"render.flare_halo": "Flare halesi",
"render.flare_streak": "Anamorfik tarzı çizgi",
@@ -1809,6 +1969,12 @@
"render.hdr_primaries_srgb": "Renk alanı: sRGB/D65",
"render.hdr_primaries_undeclared": "Kaynak renk alanını beyan etmiyor; işleyici renk gereksinimlerini inceleyin.",
"render.hdr_resource_missing": "Bu tasarımda kaydedilen HDR kaynağı eksik.",
"render.heading_batch": "TOPLU",
"render.heading_frame": "ÇERÇEVE",
"render.heading_lens": "MERCEK",
"render.heading_results": "SONUÇLAR",
"render.heading_shots": "ÇEKİMLER",
"render.hide_shots_label": "Çekim şeridini gizle",
"render.image_advanced": "Gelişmiş GPU kontrolleri",
"render.image_cancelled": "Render iptal edildi",
"render.image_cancelling": "İptal ediliyor",
@@ -1840,6 +2006,7 @@
"render.image_width": "Genişlik",
"render.include_rig_cards": "Pasif kartları ve bayrakları dahil et",
"render.inspect_scene": "Yakalanan sahne özetini yenile",
"render.inspector": "Denetçi",
"render.keep_editing": "Düzenlemeye devam et",
"render.layer_down": "Aşağı taşı",
"render.layer_enabled": "Katman etkin",
@@ -1908,6 +2075,8 @@
"render.library_unfavorite": "Sık kullanılanlardan kaldır",
"render.library_uniform_ack": "Uzamsal veya gelişmiş efektler olmadan tek biçimli yaklaşımı kullan",
"render.library_usable": "Çalıştırılabilir yansıtmalar",
"render.light_anchor_pending": "Işık koordinat çerçevesini değiştirmek henüz desteklenmiyor.",
"render.lights_fixed_to": "Işıklar şuna sabit",
"render.linear_help": "Giderme, pozlama, ton eşleme, filtreler ve arka plandan önce 32 bit float RGBA ana görüntüyü saklar. Doğrusal sRGB/D65; kapsama ile ön çarpımlı. Ek bellek açıkça kabul edilir. Sıkıştırma veya ek geçiş yoktur.",
"render.linear_retain": "Ham doğrusal EXR'ı sakla",
"render.linear_unavailable": "Seçilen tamamlanmış karede saklanmış EXR yok. Render'dan önce saklamayı etkinleştirin; eski bir PNG ham ışınımı geri getiremez.",
@@ -1993,6 +2162,7 @@
"render.output_over_budget": "İstenen görüntü, seçilen kaynak sınırını aşıyor. Uygun bir boyut veya profil açıkça seçin; otomatik düşürme yapılmaz.",
"render.output_ratio_refused": "Bağlı boyut, bu yöntemin boyut sınırını aşıyor. Önceki boyut korunur; oranı kilitten çıkarın veya daha küçük bir değer seçin.",
"render.output_swap_orientation": "Genişlik ve yüksekliği değiştir",
"render.output_tools_inspector": "Boyutu ve biçimi Çıktı denetçisinde düzenleyin.",
"render.page_aging": "Yaşlanma ve kirlenme",
"render.page_all": "Tüm kontroller",
"render.page_appearance": "Görünüm",
@@ -2004,6 +2174,7 @@
"render.page_lighting": "Aydınlatma",
"render.page_output": "Çıktı",
"render.page_scene": "Sahne",
"render.paint_label": "Boya",
"render.passive_stage": "Zemin ve pasif sahne",
"render.passive_stage_help": "Sonlu pasif paneller yalnızca render görüntülerine aittir. CAD gövdesi veya kütle eklemezler. Uygulamadan sonra yerleşim sabittir; ürün sınırlarıyla kesişen reddedilir. CPU dağınık sekme aydınlatması sağlamaz.",
"render.perspective": "Perspektif kamera",
@@ -2019,6 +2190,13 @@
"render.physical_prepare_plan": "Oluşturma planını hazırla (uygulamaz)",
"render.physical_separate": "Görünüm, malzeme kimliği değildir. Bunlar kaynaklı referanslardır, sertifikalı etkin özellikler değildir. Mevcut kütle, mühendislik malzemeleri ve optikler değişmez.",
"render.physical_unknown": "Sayısal aday belirlenmemiş. Kademe, formülasyon veya yapı belirtilmelidir; bilinmez, sıfır değildir.",
"render.pick_body": "Gövde",
"render.pick_component": "Bileşen",
"render.pick_face": "Yüz",
"render.pick_help": "Gövde, Yüz veya Bileşen seçin. Temizlemek için boş alana tıklayın; Shift veya Ctrl ekler ya da seçimi tersine çevirir. Vurgular yalnızca canlı ürün görünümünde görünür.",
"render.pick_label": "Seç",
"render.pick_up_label": "Al",
"render.pick_waiting": "Ürün seçimi henüz desteklenmiyor.",
"render.post_contrast": "Kontrast",
"render.post_gain_b": "Mavi kazancı",
"render.post_gain_g": "Yeşil kazancı",
@@ -2031,6 +2209,7 @@
"render.preview": "Yerleşik önizleme",
"render.preview_help": "Harmanlanmış saydamlıkla raster görüntü. Kırılma, HDRI ve son render henüz kullanılamıyor.",
"render.preview_image_settings_help": "Canlı Önizleme, sabit stüdyo aydınlatmasını korur. Pozlama ve görüntü aydınlatması, Kontrol veya Başlat sırasında görüntü işine uygulanır.",
"render.preview_lighting_help": "Canlı önizleme yalnızca doğrudan ışığı gösterir, gölge göstermez.",
"render.preview_retry": "Canlı önizlemeyi yeniden dene",
"render.preview_unavailable_help": "Canlı önizleme kullanılamıyor. Kaydedilmiş kurulumlar ve görüntü işi kontrolleri erişilebilir kalır. Sahneyi değiştirin veya açıkça yeniden deneyin; reddedilen sahne her karede yeniden kurulmaz.",
"render.preview_upload": "Canlı önizleme tepe noktası yükü",
@@ -2044,8 +2223,10 @@
"render.radial_distortion": "Radyal bozulma",
"render.regrade_action": "Ham ana görüntüyü yeniden derecelendir (giderme yok)",
"render.regrade_help": "Bu sunum kontrollerini kullanarak seçilen tamamlanmış ham ana görüntüden ayrı bir PNG oluşturur. Işın izlemez, yakalanan boyutu/kamerayı/ışıkları değiştirmez veya EXR'ın üzerine yazmaz. Giderme yeniden uygulanmaz: ham ana görüntüler onun kılavuzlarını saklamaz. Türev, aynı iş kontrollerinden dışa aktarılabilir kalır.",
"render.regrade_label": "Yeniden derecelendir",
"render.reload_settings": "Kaydedilmiş ayarları yükle",
"render.replace_ground": "Mevcut sahnenin değiştirilmesini onayla",
"render.replace_label": "Değiştir",
"render.replace_saved_surface": "Bu hedef için mevcut kaydedilmiş bağlamın yerini al",
"render.restore_camera": "Kaydedilmiş kamerayı yükle",
"render.result_actual_help": "Ekran pikseli başına bir görüntü pikseli.",
@@ -2091,6 +2272,7 @@
"render.sampling_title": "Uyarlanabilir ve geçiş örnekleme",
"render.save_continue": "Kaydet ve devam et",
"render.save_setup": "Kurulumu kaydet",
"render.save_shot": "Çekimi Kaydet",
"render.saved_maps_runtime_conflict": "Kaydedilmiş yüzey bağlamları, geçici optik geçersiz kılmalar veya kaydedilmemiş HDR ile karıştırılamaz. HDR'ı kaydedin veya geçici girdileri açıkça kaldırın.",
"render.saved_surface_remove": "Kaydedilmiş bağlamı kaldır",
"render.saved_surfaces": "Kaydedilmiş yüzey bağlamları",
@@ -2110,6 +2292,9 @@
"render.setup_runtime_unsupported": "Bu tam iş henüz kaydedilemez: haritalar veya sahne-gövde bağlamları içeriyor. Taşınabilir bir kurulum kaydetmeden önce o geçici girdileri kaldırın.",
"render.setup_save_missing": "Komut tamamlandıktan sonra kaydedilmiş render yapılandırması bulunamadı.",
"render.sharpening": "Detay keskinleştirme",
"render.shell_tab_appearance": "RENDER GÖRÜNÜMÜ",
"render.shell_tab_camera": "RENDER KAMERASI",
"render.shell_tab_scene": "RENDER SAHNESİ",
"render.shot_duplicate": "Kaydedilmiş çekimi çoğalt",
"render.shot_manager": "Kaydedilmiş çekimler",
"render.shot_new_name": "Yeni çekim adı",
@@ -2118,11 +2303,19 @@
"render.shot_remove_title": "Kaydedilmiş çekim kaldırılsın mı?",
"render.shot_rename": "Kaydedilmiş çekimi yeniden adlandır",
"render.shot_saved_only": "Önce geçerli taslağı kaydedin. Çoğalt ve yeniden adlandır, tam kaydedilmiş seçenekleri ve kaynak referanslarını korur.",
"render.show_shots_label": "Çekim şeridini göster",
"render.sky_ground": "Zemin · doğrusal RGB",
"render.sky_horizon": "Ufuk · doğrusal RGB",
"render.sky_zenith": "Tepe · doğrusal RGB",
"render.soft_focus": "Yumuşak odak",
"render.stage_frame": "Çerçeve",
"render.stage_light": "Işık",
"render.stage_look": "Görünüm",
"render.stage_orthographic": "Ortografik",
"render.stage_output": "Çıktı",
"render.stage_panel_count": "Kaydedilmiş paneller",
"render.stage_preview_note": "Entegre önizleme · doğrudan ışık",
"render.strip_label": "Şerit",
"render.studio_add_area": "Alan ışığı ekle",
"render.studio_ambient": "Sabit ortam ışınımı",
"render.studio_ambient_rgb": "Sabit ortam ışınımı (doğrusal RGB)",
@@ -2179,6 +2372,12 @@
"render.volume_max": "En fazla sınırlar · dünya mm",
"render.volume_min": "En az sınırlar · dünya mm",
"render.volume_title": "Sınırlı homojen hacim",
"render.wait_batch": "henüz desteklenmiyor: kayıtlı çekimlerin render kuyruğu",
"render.wait_compare": "henüz desteklenmiyor: saklanan görüntü karşılaştırması",
"render.wait_paint": "henüz desteklenmiyor: ürün seçimi ve görünüm boyama",
"render.wait_pick_up": "henüz desteklenmiyor: ürün seçimi ve görünüm örnekleme",
"render.wait_replace": "henüz desteklenmiyor: bir görünümün tüm kullanımlarını değiştirme",
"render.wait_solo": "henüz desteklenmiyor: ışık görünürlüğü ve solo denetimleri",
"sample.bracket.about": "2 mm sac metal kuralına göre kenar flanşları ve bir kenet içeren taban flanşı",
"sample.bracket.name": "Sac metal köşebent",
"sample.enclosure.about": "Dudak, vida göbekleri, dayanak ve geçmeli bağlantı içeren, içi boşaltılmış blok",
@@ -2270,6 +2469,7 @@
"timeline.delete_after_marker_one": "Geçmiş İşaretçisinden Sonra 1 Özelliği Sil",
"timeline.delete_after_marker_other": "Geçmiş İşaretçisinden Sonra {count} Özelliği Sil",
"timeline.delete_folders_tip": "Özelliklerini ve iç içe klasörlerini geçmişte tut",
"timeline.delete_folders_with_features_tip": "Klasörleri, içlerindeki her özellikle ve iç içe klasörleriyle birlikte sil",
"timeline.delete_many": "{count} Seçili Özelliği Sil",
"timeline.feature_error": "Hata: {message}",
"timeline.feature_hint": "Düzenlemek için çift tıklayın · sıralamak için sürükleyin · daha fazlası için sağ tıklayın",
@@ -2279,6 +2479,7 @@
"timeline.move_to_group": "Özellikleri klasöre taşı",
"timeline.rename_group": "Özellik klasörünü yeniden adlandır",
"timeline.reorder_many": "Özellikleri yeniden sırala",
"timeline.suppress_folders_tip": "Klasörlerdeki ve iç içe klasörlerindeki her özelliği bastır veya bastırmayı kaldır",
"timeline.ungroup": "Özellik klasörünü kaldır",
"to the face": "yüze kadar",
"to the next face": "sonraki yüze kadar",
@@ -2289,7 +2490,11 @@
"toolbar.render_camera": "KAMERA",
"toolbar.render_environment": "ORTAM",
"toolbar.render_lighting": "AYDINLATMA",
"toolbar.render_lights": "IŞIKLAR",
"toolbar.render_result": "SONUÇ",
"toolbar.render_scene": "SAHNE",
"toolbar.render_stage": "PLATO",
"toolbar.render_studio": "STÜDYO",
"trace.points": "Yol boyunca {count} nokta",
"trace.stopped_by_contact": "Örnek {sample} noktasında biter: {a}, {b} içinden geçecek",
"trace.stopped_by_loop": "Örnek {sample} noktasında biter: {joint} üzerinden geçen döngü daha fazla kapanamaz",
@@ -2468,6 +2673,7 @@
"ui.agent_chat_import_failed": "{name}: içe aktarma başarısız oldu: {error}",
"ui.agent_chat_intro": "Zaten kullandığınız bir kodlama ajanıyla veya seçtiğiniz bir model uç noktasıyla sohbet edin. Ajan, SolidCraft'ın araçlarıyla açık tasarım üzerinde çalışır: Değişiklikleri hemen görünür ve mesaj başına tek adımda geri alınabilir. Sormadan neleri yapabileceğini Ayarlar > AI altında belirlersiniz.",
"ui.agent_chat_key_in_env": "anahtar ayarlı",
"ui.agent_chat_last_missing": "En son kullanılan ajan ({agent}) artık kullanılamıyor. Bir ajan seçin, ardından Yeniden dene'ye basın.",
"ui.agent_chat_left": "Sol",
"ui.agent_chat_limit": "Ajan, bir mesaj için {limit} değişiklik sınırına ulaştı. Devam etmesi için başka bir mesaj gönderin.",
"ui.agent_chat_login_found": "oturum bulundu",
@@ -2514,6 +2720,7 @@
"ui.agent_chat_remove": "Sıradan kaldır",
"ui.agent_chat_remove_file": "Bu iletiden çıkar",
"ui.agent_chat_remove_imported": "Bu iletiden çıkar; parça tasarımda kalır (Geri al onu kaldırır)",
"ui.agent_chat_retry": "Yeniden dene",
"ui.agent_chat_right": "Sağ",
"ui.agent_chat_save": "Kaydet",
"ui.agent_chat_send": "Gönder",
@@ -2526,6 +2733,7 @@
"ui.agent_chat_state_auth": "Oturum açılması gerekiyor",
"ui.agent_chat_state_busy": "Çalışıyor…",
"ui.agent_chat_state_exited": "Ajan sonlandı",
"ui.agent_chat_state_failed": "Bağlantı başarısız",
"ui.agent_chat_state_off": "Bağlı değil",
"ui.agent_chat_state_ready": "Hazır",
"ui.agent_chat_state_starting": "Başlatılıyor…",
@@ -2829,6 +3037,7 @@
"ui.fully_constrained": "Tam kısıtlı",
"ui.function": "Fonksiyon",
"ui.general": "Genel",
"ui.gpu_memory_lowered": "Ekran kartının belleği doldu: görünüm daha düşük kalitede çiziliyor.",
"ui.graphics": "Grafik",
"ui.graphics_custom": "Özel",
"ui.graphics_performance": "Performans",
@@ -2908,6 +3117,7 @@
"ui.heading_utilities": "ARAÇLAR",
"ui.heading_utility": "YARDIMCI ARAÇLAR",
"ui.heading_weldments": "KAYNAK",
"ui.height": "Yükseklik",
"ui.help": "Yardım",
"ui.hide": "Gizle",
"ui.hideAxes": "Eksenleri gizle",
@@ -2950,6 +3160,7 @@
"ui.language": "Dil",
"ui.layout_compact": "Kompakt",
"ui.layout_floating": "Kayan",
"ui.length": "Uzunluk",
"ui.length_decimals": "Uzunluk ondalık basamakları",
"ui.light": "Açık",
"ui.line": "Çizgi",
@@ -3048,6 +3259,7 @@
"ui.pinToShortcuts": "Kısayollara sabitle",
"ui.pinToToolbar": "Araç çubuğuna sabitle",
"ui.pipe": "Boru",
"ui.pitch": "Adım",
"ui.placement": "Yerleşim",
"ui.placement_handles": "Yerleşim tutamaçları",
"ui.placement_handles_tip": "Bir Dayama, Kabarıklık veya Kilit Geçme önizlemesindeki tutamaçlar: işaretçiyi model üzerinde hareket ettirmek için sürükleyin, halkasıyla döndürün",
@@ -3099,6 +3311,7 @@
"ui.render": "Render",
"ui.renderer": "Çizim motoru",
"ui.repeat": "Tekrarla",
"ui.repeat_nothing": "Henüz tekrarlanacak bir şey yok: önce bir araç veya diyalog başlatın.",
"ui.replace_with_link_done": "Kopyalar artık bağlı tasarımın yerleşimleri.",
"ui.report_a_bug": "Hata bildir",
"ui.reset": "Sıfırla",
@@ -3254,6 +3467,7 @@
"ui.visual_shaded_with_edges": "Kenarlarla gölgeli",
"ui.visual_style": "Görsel stil",
"ui.visual_wireframe": "Tel kafes",
"ui.width": "Genişlik",
"ui.window_system": "Pencere sistemi",
"ui.window_system_auto": "Otomatik",
"ui.window_system_wayland": "Wayland",
@@ -3321,5 +3535,6 @@
"web.open_link": "Bağlı tasarım açılsın mı?",
"web.open_link_confirm": "Kaydedilmemiş değişiklikler var. Bağlı tasarım yeni bir sekmede açılsın mı?",
"↑ ↓ choose · Enter / Tab complete · Esc dismiss": "↑ ↓ seç · Enter / Tab tamamla · Esc kapat",
"↑ ↓ choose · Enter applies what you typed · Esc dismiss": "↑ ↓ seçin · Enter yazdığınızı uygular · Esc kapatır"
"↑ ↓ choose · Enter applies what you typed · Esc dismiss": "↑ ↓ seçin · Enter yazdığınızı uygular · Esc kapatır",
"⌘Enter continues on GitHub.": "⌘Enter ile GitHub'da devam edilir."
}
+1139 -922
View File
File diff suppressed because it is too large Load Diff
+519 -1
View File
File diff suppressed because it is too large Load Diff
+1806 -2
View File
File diff suppressed because it is too large Load Diff
+519 -1
View File
File diff suppressed because it is too large Load Diff
@@ -6,8 +6,11 @@
<comment>SolidCraft design</comment>
<icon name="io.tangencylabs.solidcraft"/>
<sub-class-of type="application/json"/>
<!-- shared-mime-info also gives *.sc to Scala scripts (text/x-scala, weight 50); with
SolidCraft installed its designs win. -->
<glob pattern="*.sc" weight="60"/>
<!-- Compatibility shim (docs/compatibility.md): designs saved before .sc, and before the rename. -->
<glob pattern="*.solidcraft"/>
<!-- Compatibility shim (docs/compatibility.md): designs saved before the rename. -->
<glob pattern="*.solvecraft"/>
<alias type="application/x-solvecraft"/>
</mime-type>
+24 -2
View File
@@ -45,8 +45,11 @@
<key>CFBundleTypeName</key>
<string>SolidCraft design</string>
<key>CFBundleTypeExtensions</key>
<!-- solvecraft: designs saved before the rename (compatibility shim, docs/compatibility.md). -->
<array><string>solidcraft</string><string>solvecraft</string></array>
<!-- solidcraft: designs saved before .sc; solvecraft: before the rename (compatibility
shims, docs/compatibility.md). -->
<array><string>sc</string><string>solidcraft</string><string>solvecraft</string></array>
<key>LSItemContentTypes</key>
<array><string>io.tangencylabs.solidcraft.design</string></array>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSHandlerRank</key>
@@ -63,5 +66,24 @@
<string>Alternate</string>
</dict>
</array>
<!-- The design type: .sc, and the older .solidcraft and .solvecraft (docs/compatibility.md). -->
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeIdentifier</key>
<string>io.tangencylabs.solidcraft.design</string>
<key>UTTypeDescription</key>
<string>SolidCraft design</string>
<key>UTTypeConformsTo</key>
<array><string>public.data</string><string>public.content</string></array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array><string>sc</string><string>solidcraft</string><string>solvecraft</string></array>
<key>public.mime-type</key>
<array><string>application/x-solidcraft</string></array>
</dict>
</dict>
</array>
</dict>
</plist>
+3 -3
View File
@@ -11,6 +11,6 @@ Some earlier releases were installed as SolveCraft.app. Move that one to the Tra
once SolidCraft.app is in Applications, and replace any Dock shortcut with the
old name (open SolidCraft.app, then choose Options > Keep in Dock).
Designs saved as .solvecraft still open, and SolidCraft copies your settings
and recovery files from the old SolveCraft folder on its first launch.
New designs are saved as .solidcraft.
Designs saved as .solidcraft or .solvecraft still open, and SolidCraft copies
your settings and recovery files from the old SolveCraft folder on its first
launch. New designs are saved as .sc.
+9 -6
View File
@@ -9,7 +9,7 @@
Per-machine install with a setup wizard: Welcome, install folder (Program Files\SolidCraft by
default, remembered for upgrades), Ready, progress, and a Finish page with a ticked "Launch
SolidCraft" box. Installs a Start Menu shortcut, solidcraft-cli (and adds its folder to the system PATH), the licence files (including
THIRD-PARTY-LICENSES.txt), makes SolidCraft the owner of `.solidcraft` (and of the pre-rename `.solvecraft`), and offers it under
THIRD-PARTY-LICENSES.txt), makes SolidCraft the owner of `.sc` (and of the older `.solidcraft` and pre-rename `.solvecraft`), and offers it under
"Open with" for STEP, IGES, 3MF and STL. `msiexec /qn` installs silently.
Adapted from PhotoCraft's (storytold/photocraft, Apache-2.0; see ATTRIBUTION.md).
-->
@@ -84,15 +84,17 @@
Icon="SolidcraftIcon.exe" IconIndex="0" />
</File>
<!-- .solidcraft: SolidCraft's own format; SolidCraft is its default app. -->
<!-- .sc: SolidCraft's own format; SolidCraft is its default app. -->
<ProgId Id="Solidcraft.Design" Description="SolidCraft Design" Icon="SolidcraftExe" IconIndex="0">
<Extension Id="solidcraft" ContentType="application/x-solidcraft">
<Extension Id="sc" ContentType="application/x-solidcraft">
<Verb Id="open" Command="Open" TargetFile="SolidcraftExe" Argument="&quot;%1&quot;" />
</Extension>
</ProgId>
<!-- Compatibility shim (docs/compatibility.md): designs saved before the rename open as
the same ProgId. Registered by hand: a second Extension under one ProgId would write
its open verb twice (WIX0091). -->
<!-- Compatibility shim (docs/compatibility.md): designs saved as .solidcraft (before .sc)
and as .solvecraft (before the rename) open as the same ProgId. Registered by hand: a
second Extension under one ProgId would write its open verb twice (WIX0091). -->
<RegistryValue Root="HKLM" Key="Software\Classes\.solidcraft" Value="Solidcraft.Design" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\.solidcraft" Name="Content Type" Value="application/x-solidcraft" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\.solvecraft" Value="Solidcraft.Design" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\.solvecraft" Name="Content Type" Value="application/x-solvecraft" Type="string" />
<!-- STEP, IGES and meshes: offered under "Open with", never forced as the default. -->
@@ -108,6 +110,7 @@
<!-- "Open with" app list and the Run dialog (Win+R "solidcraft"). -->
<RegistryValue Root="HKLM" Key="Software\Classes\Applications\solidcraft.exe" Name="FriendlyAppName" Value="SolidCraft" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\Applications\solidcraft.exe\shell\open\command" Value="&quot;[#SolidcraftExe]&quot; &quot;%1&quot;" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\Applications\solidcraft.exe\SupportedTypes" Name=".sc" Value="" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\Applications\solidcraft.exe\SupportedTypes" Name=".solidcraft" Value="" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\Applications\solidcraft.exe\SupportedTypes" Name=".solvecraft" Value="" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\Applications\solidcraft.exe\SupportedTypes" Name=".step" Value="" Type="string" />
+7 -4
View File
@@ -10,7 +10,7 @@ struct U {
acc_u: vec4<f32>, // accessibility map axes (xyz, offset)
acc_v: vec4<f32>,
eye: vec4<f32>, // eye position, w = 1 for perspective (0: orthographic, looking along -back)
ao: vec4<f32>, // radius in world units (zero: disabled)
ao: vec4<f32>, // x: radius in world units (zero: disabled), y: samples per pixel
// analysis colours (`theme::AnalysisColors`): draft positive, between, negative; reachable,
// blocked; curvature flat, middle, tight
ana_c: array<vec4<f32>, 8>,
@@ -333,9 +333,12 @@ fn occlusion(i: TOut) -> f32 {
// the buffer runs reversed). The map is cleared to its far plane either way, so a texel
// with nothing in it reads as 1 and the `d < 1.0` test below skips it.
let flip = reversed();
// Fewer samples while the view moves (#7165), spread over the same hemisphere. 32 is the
// still picture's count, `AO_SAMPLES` in view.rs.
let count = u32(clamp(u.ao.y, 1.0, 32.0));
var blocked = 0.0;
for (var j = 0u; j < 32u; j = j + 1u) {
let f = (f32(j) + 0.5) / 32.0;
for (var j = 0u; j < count; j = j + 1u) {
let f = (f32(j) + 0.5) / f32(count);
let angle = f32(j) * 2.39996323;
let direction = t * (cos(angle) * sqrt(f)) + b * (sin(angle) * sqrt(f)) + n * sqrt(1.0 - f);
let reach = radius * (0.2 + 0.8 * fract(f32(j) * 0.61803399 + 0.5));
@@ -356,7 +359,7 @@ fn occlusion(i: TOut) -> f32 {
blocked = blocked + smoothstep(0.005, 0.15, delta) * (1.0 - smoothstep(0.5, 1.0, delta));
}
}
return 1.0 - 0.85 * blocked / 32.0;
return 1.0 - 0.85 * blocked / f32(count);
}
/// How fast the normal turns across the pixel (per mm).
+24 -4
View File
@@ -8,6 +8,15 @@ const fn icon_primary(rgb: [u8; 3]) -> Color32 {
impl Tokens {
pub const fn light() -> Tokens {
Tokens {
nav_hover: Color32::from_rgb(233, 237, 242),
nav_press: Color32::from_rgb(220, 226, 234),
nav_dim: Color32::from_rgb(136, 149, 167),
nav_viewport: Color32::from_rgb(238, 241, 245),
nav_tip: Color32::from_rgb(27, 36, 48),
nav_tip_ink: Color32::from_rgb(255, 255, 255),
nav_tip_key_border: Color32::from_rgba_unmultiplied_const(128, 140, 160, 153),
nav_field: Color32::from_rgb(255, 255, 255),
borders: crate::theme::Borders::LEGACY,
icon_palette: None,
file_dim: Color32::from_rgb(58, 70, 86),
@@ -184,8 +193,10 @@ impl Tokens {
sketch_halo: Color32::from_rgb(240, 243, 247),
sketch_point: Color32::BLACK,
sketch_locked: Color32::from_rgb(0, 140, 60),
dimension: Color32::from_rgb(36, 40, 48),
dimension_driven: Color32::from_rgb(120, 126, 138),
// Sketch dimensions in a plum of their own, apart from the blue and black curves for
// every colour vision mode (#7861).
dimension: Color32::from_rgb(130, 42, 110),
dimension_driven: Color32::from_rgb(160, 90, 120),
sketch_point_free: Color32::from_rgb(30, 90, 200),
section_cap: Color32::from_rgb(214, 128, 72),
dialog_bg: Color32::from_rgb(250, 251, 252),
@@ -314,6 +325,14 @@ impl Tokens {
t.render_ink = Color32::from_rgb(224, 116, 174);
t.render_soft = Color32::from_rgb(64, 35, 54);
t.tab_on_fill_dark = Color32::BLACK;
t.nav_hover = Color32::from_rgb(58, 65, 80);
t.nav_press = Color32::from_rgb(70, 78, 96);
t.nav_dim = Color32::from_rgb(124, 135, 154);
t.nav_viewport = Color32::from_rgb(38, 43, 53);
t.nav_tip = Color32::from_rgb(238, 241, 245);
t.nav_tip_ink = Color32::from_rgb(27, 36, 48);
t.nav_tip_key_border = Color32::from_rgba_unmultiplied_const(128, 140, 160, 153);
t.nav_field = Color32::from_rgb(47, 52, 62);
t.dialog_body = Color32::from_rgb(39, 43, 52);
t.dialog_footer = Color32::from_rgb(47, 52, 62);
t.dialog_rule = Color32::from_rgb(53, 59, 71);
@@ -341,8 +360,9 @@ impl Tokens {
t.sketch_halo = Color32::from_rgb(28, 32, 40);
t.sketch_point = Color32::from_rgb(232, 234, 238);
t.sketch_locked = Color32::from_rgb(96, 204, 116);
t.dimension = Color32::from_rgb(224, 228, 234);
t.dimension_driven = Color32::from_rgb(142, 150, 164);
// Sketch dimensions: Light's plum, lightened for the dark view (#7861).
t.dimension = Color32::from_rgb(224, 176, 224);
t.dimension_driven = Color32::from_rgb(176, 104, 144);
t.sketch_point_free = Color32::from_rgb(92, 150, 255);
t.profile_fill = Color32::from_rgba_unmultiplied_const(120, 150, 200, 40);
t.dialog_bg = Color32::from_rgb(39, 43, 52);
+8
View File
@@ -101,6 +101,14 @@
"mesh_fill": "#ffffff",
"mesh_ink": "#ffffff",
"mesh_soft": "#000000",
"nav_dim": "#ffffff",
"nav_field": "#000000",
"nav_hover": "#000000",
"nav_press": "#ffffff",
"nav_tip": "#ffffff",
"nav_tip_ink": "#000000",
"nav_tip_key_border": "#000000",
"nav_viewport": "#000000",
"on_accent": "#000000",
"origin_plane": "#000000",
"origin_plane_edge": "#ffffff",
+8
View File
@@ -101,6 +101,14 @@
"mesh_fill": "#000000",
"mesh_ink": "#000000",
"mesh_soft": "#ffffff",
"nav_dim": "#000000",
"nav_field": "#ffffff",
"nav_hover": "#ffffff",
"nav_press": "#000000",
"nav_tip": "#000000",
"nav_tip_ink": "#ffffff",
"nav_tip_key_border": "#ffffff",
"nav_viewport": "#ffffff",
"on_accent": "#ffffff",
"origin_plane": "#ffffff",
"origin_plane_edge": "#000000",
+2 -2
View File
@@ -50,8 +50,8 @@
"dialog_footer": "#efece8",
"dialog_label": "#403d38",
"dialog_rule": "#d9d5d0",
"dimension": "#403d38",
"dimension_driven": "#6c6863",
"dimension": "#006a70",
"dimension_driven": "#4d8a8c",
"error": "#c71529",
"field": "#fffdfa",
"file_rail": "#e1ddd8",
+2 -2
View File
@@ -50,8 +50,8 @@
"dialog_footer": "#100b04",
"dialog_label": "#f3ca87",
"dialog_rule": "#3b280d",
"dimension": "#ffe2a5",
"dimension_driven": "#9b6922",
"dimension": "#f5e050",
"dimension_driven": "#a8962e",
"error": "#fff0ca",
"field": "#100b04",
"form_accent": "#ca892b",
+2 -2
View File
@@ -50,8 +50,8 @@
"dialog_footer": "#0c223c",
"dialog_label": "#e3f0fa",
"dialog_rule": "#254764",
"dimension": "#e3f0fa",
"dimension_driven": "#94b2cb",
"dimension": "#ffd970",
"dimension_driven": "#c9a95a",
"error": "#ff968d",
"field": "#071d35",
"form_accent": "#baade8",
@@ -50,8 +50,8 @@
"dialog_footer": "#1e1e2e",
"dialog_label": "#cdd6f4",
"dialog_rule": "#45475a",
"dimension": "#cdd6f4",
"dimension_driven": "#a6adc8",
"dimension": "#94e2d5",
"dimension_driven": "#6c9d95",
"error": "#f38ba8",
"field": "#181825",
"form_accent": "#a9b2f2",
+10 -2
View File
@@ -45,8 +45,8 @@
"dialog_footer": "#000000",
"dialog_label": "#55ffff",
"dialog_rule": "#00aaaa",
"dimension": "#ffffff",
"dimension_driven": "#aaaaaa",
"dimension": "#ffff55",
"dimension_driven": "#aa5500",
"error": "#ff5555",
"field": "#000000",
"file_background": "#000000",
@@ -101,6 +101,14 @@
"mesh_fill": "#55ff55",
"mesh_ink": "#55ff55",
"mesh_soft": "#000000",
"nav_dim": "#55ffff",
"nav_field": "#000000",
"nav_hover": "#aa00aa",
"nav_press": "#ff55ff",
"nav_tip": "#ffffff",
"nav_tip_ink": "#000000",
"nav_tip_key_border": "#55ffff",
"nav_viewport": "#000000",
"on_accent": "#000000",
"origin_plane": "#55ffff20",
"origin_plane_edge": "#55ffff80",
+2 -2
View File
@@ -50,8 +50,8 @@
"dialog_footer": "#29241f",
"dialog_label": "#c3bdb5",
"dialog_rule": "#403930",
"dimension": "#c3bdb5",
"dimension_driven": "#9d9285",
"dimension": "#5fc4c0",
"dimension_driven": "#4f9895",
"error": "#f85052",
"field": "#3c352d",
"form_accent": "#a6a2fc",
+2 -2
View File
@@ -50,8 +50,8 @@
"dialog_footer": "#f4eee3",
"dialog_label": "#423e36",
"dialog_rule": "#e0d8c9",
"dimension": "#423e36",
"dimension_driven": "#726a5d",
"dimension": "#006a70",
"dimension_driven": "#4a8688",
"error": "#c71529",
"field": "#fdfaf3",
"form_accent": "#5844bc",
+2 -2
View File
@@ -50,8 +50,8 @@
"dialog_footer": "#ececec",
"dialog_label": "#262628",
"dialog_rule": "#c6c6c8",
"dimension": "#262628",
"dimension_driven": "#6e6e73",
"dimension": "#00646b",
"dimension_driven": "#3d8087",
"error": "#d53137",
"field": "#ffffff",
"form_accent": "#8b62bf",
+2 -2
View File
@@ -50,8 +50,8 @@
"dialog_footer": "#25272b",
"dialog_label": "#e0e2e5",
"dialog_rule": "#484d55",
"dimension": "#e0e2e5",
"dimension_driven": "#a0a6b0",
"dimension": "#5fd0c8",
"dimension_driven": "#4a9a95",
"error": "#ed7777",
"field": "#1c1e21",
"form_accent": "#a08fc4",
+2 -2
View File
@@ -50,8 +50,8 @@
"dialog_footer": "#061009",
"dialog_label": "#8def9f",
"dialog_rule": "#173b22",
"dimension": "#8def9f",
"dimension_driven": "#5b9b6a",
"dimension": "#c8ff4d",
"dimension_driven": "#7fa040",
"error": "#d8ffdf",
"field": "#061009",
"form_accent": "#1faa4e",
@@ -55,8 +55,8 @@
"sketch_fixed": "#ebdbb2",
"sketch_halo": "#141617",
"sketch_locked": "#b8bb26",
"dimension": "#ebdbb2",
"dimension_driven": "#928374",
"dimension": "#fabd2f",
"dimension_driven": "#b57614",
"sketch_point": "#ebdbb2",
"sketch_point_free": "#83a598",
"dialog_bg": "#3c3836",
@@ -56,8 +56,8 @@
"sketch_fixed": "#ebdbb2",
"sketch_halo": "#1d2021",
"sketch_locked": "#b8bb26",
"dimension": "#ebdbb2",
"dimension_driven": "#928374",
"dimension": "#fabd2f",
"dimension_driven": "#b57614",
"sketch_point": "#ebdbb2",
"sketch_point_free": "#83a598",
"dialog_bg": "#3c3836",
+2 -2
View File
@@ -56,8 +56,8 @@
"sketch_fixed": "#ebdbb2",
"sketch_halo": "#1d2021",
"sketch_locked": "#b8bb26",
"dimension": "#ebdbb2",
"dimension_driven": "#928374",
"dimension": "#fabd2f",
"dimension_driven": "#b57614",
"sketch_point": "#ebdbb2",
"sketch_point_free": "#83a598",
"dialog_bg": "#3c3836",
@@ -55,8 +55,8 @@
"sketch_fixed": "#282828",
"sketch_halo": "#fbf8e3",
"sketch_locked": "#79740e",
"dimension": "#3c3836",
"dimension_driven": "#7c6f64",
"dimension": "#1f5c40",
"dimension_driven": "#4f7d64",
"sketch_point": "#282828",
"sketch_point_free": "#076678",
"dialog_bg": "#f9f5d7",
@@ -55,8 +55,8 @@
"sketch_fixed": "#282828",
"sketch_halo": "#f6edd0",
"sketch_locked": "#79740e",
"dimension": "#3c3836",
"dimension_driven": "#7c6f64",
"dimension": "#1f5c40",
"dimension_driven": "#4f7d64",
"sketch_point": "#282828",
"sketch_point_free": "#076678",
"dialog_bg": "#f2e5bc",
+2 -2
View File
@@ -55,8 +55,8 @@
"sketch_fixed": "#282828",
"sketch_halo": "#fcf5d8",
"sketch_locked": "#79740e",
"dimension": "#3c3836",
"dimension_driven": "#7c6f64",
"dimension": "#1f5c40",
"dimension_driven": "#4f7d64",
"sketch_point": "#282828",
"sketch_point_free": "#076678",
"dialog_bg": "#fbf1c7",
+2 -2
View File
@@ -50,8 +50,8 @@
"dialog_footer": "#000000",
"dialog_label": "#ffffff",
"dialog_rule": "#a0a0a0",
"dimension": "#ffffff",
"dimension_driven": "#cccccc",
"dimension": "#ffff66",
"dimension_driven": "#c8c850",
"error": "#ff6666",
"field": "#000000",
"form_accent": "#d98af9",
+2 -2
View File
@@ -50,8 +50,8 @@
"dialog_footer": "#2e3440",
"dialog_label": "#eceff4",
"dialog_rule": "#4c566a",
"dimension": "#eceff4",
"dimension_driven": "#a4b0c2",
"dimension": "#d08770",
"dimension_driven": "#a87060",
"error": "#bf616a",
"field": "#242933",
"form_accent": "#cfa7c7",
+2 -2
View File
@@ -50,8 +50,8 @@
"dialog_footer": "#282a36",
"dialog_label": "#f8f8f2",
"dialog_rule": "#50546d",
"dimension": "#f8f8f2",
"dimension_driven": "#a1a4c4",
"dimension": "#8be9fd",
"dimension_driven": "#62a3b1",
"error": "#ff5555",
"field": "#21222c",
"form_accent": "#c096e8",
+2 -2
View File
@@ -50,8 +50,8 @@
"dialog_footer": "#1b1e20",
"dialog_label": "#bbbec1",
"dialog_rule": "#2f3235",
"dimension": "#bbbec1",
"dimension_driven": "#8f9296",
"dimension": "#5fc4c0",
"dimension_driven": "#4f9895",
"error": "#f85052",
"field": "#2c2e31",
"file_rail": "#0f1113",
+2 -2
View File
@@ -50,8 +50,8 @@
"dialog_footer": "#2f343e",
"dialog_label": "#b4bbc8",
"dialog_rule": "#353b47",
"dimension": "#abb2bf",
"dimension_driven": "#7f848e",
"dimension": "#56b6c2",
"dimension_driven": "#3f8590",
"error": "#e06c75",
"field": "#1e2227",
"form_accent": "#d283e9",
+2 -2
View File
@@ -50,8 +50,8 @@
"dialog_footer": "#dddddd",
"dialog_label": "#222222",
"dialog_rule": "#aaaaaa",
"dimension": "#222222",
"dimension_driven": "#666666",
"dimension": "#00787f",
"dimension_driven": "#4d9196",
"error": "#bb3333",
"field": "#ffffff",
"form_accent": "#704e81",

Some files were not shown because too many files have changed in this diff Show More