Commit Graph
324 Commits
Author SHA1 Message Date
Hakan Seven 313349fd71 fix(io): verify saves through edit leases 2026-08-17 23:13:07 +03:00
NgoQuocViet2001 c88f07d219 fix(io): stop the drawing lock blocking our own reads on Windows
Saving to a path that already holds a drawing fails on Windows with
"could not verify <path> before saving: ... (os error 33)". Save As over any
existing drawing is affected; saving to a new path is not.

EditLease::acquire() opens the destination and takes the platform drawing
lock on it, then the save fingerprints the same path to check nothing changed
underneath. LockFileEx is mandatory and scoped to the handle that took it, so
that second open is refused against our own lock, lands in the non-NotFound
arm and aborts the save. flock on Unix is advisory and the second open
succeeds, so neither CI nor a Linux desktop sees it.

Read through the handle the lease already holds instead. A duplicate shares
the lock ownership, so the pre-replace re-check on the save worker can use
one too rather than re-opening the path.

The same collision reached the headless open op, which read a path this
session may hold leased: automation's save_then_open_round_trips fails on
main for that reason, one line after the save it no longer reaches.
2026-08-17 22:49:54 +07:00
Hakan Seven 1dded7f881 fix: restore workspace verification 2026-08-15 23:11:26 +03:00
gianlucafiore 3f989fe94c Merge pull request #771 from gianlucafiore/fix/overlapping-grips
Fix overlapping grips moving independently
2026-08-15 14:23:17 -03:00
gianlucafiore bc9e206c19 fix: move coincident grips together 2026-08-15 14:22:22 -03:00
Hakan Seven f247d15f6e feat(plugin): harden V4 host integration
Preserve legacy wire indices and route concurrent V4 responses and background requests by correlation and stable tab ID.
2026-08-15 20:17:43 +03:00
Hakan Seven 6cc1bf9755 fix(layer): centralize rename flow 2026-08-15 19:56:35 +03:00
Karim Jerbi b4da342f0e refactor(ribbon): derive the Block Palette button highlight from app state
The ribbon kept its own \show_block_palette\ copy that the app had to
manually sync at every mutation point (the BLOCKPALETTE command and the
dock Close handler). Drop the copy and thread the app's authoritative
\show_block_palette\ into \Ribbon::view\ at render time, so the button
highlight can't drift from the panel's true visibility — those two
handlers are now mutate-points only and the ribbon view is the single
place that reads the state back.
2026-08-15 14:42:08 +01:00
Karim Jerbi c3e3132b39 refactor(props): key active fields by a typed enum, not a sentinel string
The \\\x01attr\\x01…\ sentinel-prefixed string was used to tell geometry
fields (\&'static str\ names) apart from block attribute rows (runtime
tags) in \ctive_field\ and \dit_buf\. Replace it with a \FieldKey\
enum (\Geom(&'static str)\ / \Attr(String)\), so the two namespaces can't
collide by construction: \dit_buf\ is now \HashMap<FieldKey, String>\,
\ctive_field\ is \Option<FieldKey>\, and the sentinel decoding in
\ctive_key_id\ is replaced by \FieldKey::widget_id\.

While touching the key plumbing, replace \prop_field_key_for_id\'s
per-event scan of every section x prop (with a \String\ format per
candidate) with an O(1) precomputed \HashMap<iced::widget::Id, FieldKey>\
(\ield_key_by_id\), built once in \
efresh_properties\ alongside the
sections — and rebuilt after \make_sections_read_only\ so rows demoted
to read-only stop mapping. \PropSyncActive\ now does a single map lookup
per event.
2026-08-15 14:29:20 +01:00
Karim Jerbi eead4eb5f0 perf(props): skip focus sweep when the properties panel is hidden
The global left-click listener fires PropPointerPressed on every mouse
press anywhere in the app, and the handler used to launch a full
widget-tree focus sweep on each one - even when the Properties panel
was closed. Gate the sweep on dock_panel_visible(Properties): when the
panel is hidden the handler now returns Task::none, turning an O(whole
UI) traversal per click into an O(1) boolean check in the common case.

The other sweep call sites already gate via sync_active_field_if_any;
this was the only ungated one.

Tests:
- hidden_properties_panel_skips_the_focus_sweep - a click with the
  panel closed returns a Task::none (units == 0), i.e. no sweep.
- visible_properties_panel_runs_the_focus_sweep - a click with the
  panel open still fires the sweep (units > 0), preserving the
  select-whole-value behavior.
2026-08-15 13:49:26 +01:00
Hakan Seven 37325f4d63 fix(layers): keep rename state consistent
Keep table keys, entity references, dependency caches, and current
layer handles aligned across case-only and mixed-case renames.

Refs #764
Refs #765
2026-08-15 13:22:06 +03:00
NgoQuocViet2001 9c6adedc44 fix: keep layer rename state in sync 2026-08-15 15:56:15 +07:00
Karim Jerbi fbab4c4934 feat(ribbon): Block Palette button reflects panel open state
The Insert tab's Block Palette button now behaves like the View tab toggles
(UCS Icon, View Cube, Ortho, Properties, File Tabs, Layout Tabs): it stays
highlighted while the block palette panel is open and clears when closed.

The Ribbon gains a show_block_palette flag with a set_block_palette setter,
fed into ToggleState and mapped in is_active_tool for the BLOCKPALETTE tool
id. show_block_palette on the app remains the single source of truth; both
mutation paths now mirror it onto the ribbon:

- BLOCKPALETTE / BLOCKSPALETTE command toggles ribbon state alongside the
  panel (src/app/commands/blocks.rs).
- Closing the panel via the dock rail close button clears the ribbon state,
  matching how Close(Properties) already syncs (src/app/update/dialog.rs).
2026-08-14 23:33:45 +01:00
Karim Jerbi df940ad58e fix(dock): size drag preview by visible panels, not stack size
The drag preview divided the edge height by the raw panel count on the target
side. Closed panels keep their stack slot, so a hidden panel (e.g. the block
palette tucked away while Properties stays open) split the ghost and the drop
index as if it were rendering — leaving a half-height preview on that edge.
Size slots from the panels actually rendered on the edge instead, via a shared
visibility helper used by both the drop-index math and the ghost/edge-tint
geometry.
2026-08-14 22:24:57 +01:00
Karim Jerbi 2a0b7805c0 fix(dock): size drag preview slots by the edge viewport height
The dock drag preview computed slot heights and drop indices from the full
window height, but docked panel columns only span the model viewport, so the
preview overlay and insertion point drifted below the actual dock edge. Use the
current viewport height so the ghost and drop index line up with the panels.
2026-08-14 21:21:40 +01:00
Karim Jerbi 9f68034a60 feat(props): select whole value when a property field is clicked
Clicking an editable property value field now selects its entire value instead
of only placing the caret, so typing immediately replaces it. The click is
observed through a global left-press subscription (PropPointerPressed); a focus
sweep reports which widget took focus and PropSyncActive maps it back to the
active property row, then issues a select-all operation only when focus landed
on a different field.

The active row stays highlighted while its text input holds keyboard focus and
clears when focus moves elsewhere.
2026-08-14 21:21:40 +01:00
Karim Jerbi dceb9626ae fix(dock): block palette reflects new blocks without reopening
Creating a block from selected entities now bumps the geometry epoch, so the
block palette's per-update stale check notices the new definition and refreshes
its list in place instead of requiring the user to close and reopen the panel.
2026-08-14 21:21:40 +01:00
gianlucafiore f47ab7e891 fix: respect drawing units for annotative text 2026-08-14 15:38:54 -03:00
Sebastian 83d7a4d7db plugin: parallel release fetches, faster shutdown, uninstall runner stop
- Run Plugin Manager release fetches on OS threads so they execute in

  parallel instead of serialising on the async executor.

- Reduce V4Connection shutdown poll from 3s to 100ms; the runner is killed

  and reaped without blocking host shutdown.

- Add PluginManager::remove and PluginProcess::shutdown_and_wait so

  uninstall can stop the runner before deleting files, fixing Windows

  access-denied errors on plugin removal.

- Rebuild ribbon immediately after uninstall so the tab disappears.
2026-08-14 20:18:59 +02:00
gianlucafiore 4aa317f413 fix: restore text editing on double click 2026-08-13 17:53:24 -03:00
Sebastian 883e703b02 Fix V2/V3 messaging ABI-break 2026-08-13 09:49:57 +02:00
gianlucafiore e21d4954a3 fix: respect drawing units in annotation scales 2026-08-12 23:41:22 -03:00
Sebastian 29c41a4041 Snapshot: V4 plugin API and host integration 2026-08-12 21:01:39 +02:00
Hakan Seven 0df2356243 fix(view): correct 3D mesh interaction
Sync projection controls from the active camera, preserve the UCS icon in perspective views, and use visible or selected 3D geometry for orbit pivots. Dense mesh vertex grips remain hidden.
2026-08-12 19:49:52 +03:00
Hakan Seven 0be9c41773 fix(layers): protect locked entities
Keep locked-layer objects selectable for inspection while suppressing grips, property edits, command mutations, and stale editor writes.
2026-08-12 12:46:41 +03:00
gianlucafiore ff61164d8b fix: preserve current layer for hatches and DWG loading 2026-08-12 00:30:21 -03:00
gianlucafiore b8b66163d6 Merge pull request #745 from gianlucafiore/fix/dwgunits-annotation-scales
Fix viewport and annotation scales for drawing units
2026-08-11 22:48:27 -03:00
gianlucafiore cc7894cd92 fix: honor drawing units in annotation and viewport scales 2026-08-11 22:41:26 -03:00
Hakan Seven 4fd9b98da4 perf(render): instance block geometry
Share source buffers across block placements and render nested content with GPU instance transforms.\n\nChunk silhouettes and compact mesh material data so large drawings stay under device buffer limits and remain responsive.
2026-08-12 02:33:10 +03:00
Karim Jerbi 7bfb617745 feat(dock): stacked edge rendering and drag-to-reorder preview 2026-08-11 23:13:05 +01:00
Karim Jerbi 10a1d89f19 feat(dock): migrate block palette onto general edge-stack dock
Pin/close/resize/drag-between-edges/auto-collapse hover, themed and
persisted, mirroring the properties panel chrome.
2026-08-11 23:13:05 +01:00
Karim Jerbi dce555f5bc feat(config): persist general edge-stack dock layout 2026-08-11 23:13:05 +01:00
gianlucafiore 9fb075f8ee fix: improve plot style editing and print all plot actions 2026-08-11 18:45:00 -03:00
Hakan Seven c4dfa7567d fix(model): correct primitive creation and grips 2026-08-12 00:03:27 +03:00
Hakan Seven 59ca0f693f feat(model): edit primitive history properties 2026-08-11 20:14:51 +03:00
Hakan Seven 4ac10187c2 fix(model): preserve solid history lifecycle 2026-08-11 20:10:23 +03:00
Hakan Seven dc6dc2256d fix(model): sync solid render interaction 2026-08-11 19:39:01 +03:00
gianlucafiore e0ead249b6 Merge pull request #740 from gianlucafiore/fix/dimension-properties-editable
Fix dimension styles incorrectly treated as read-only
2026-08-11 08:45:12 -03:00
gianlucafiore 3a752029cd fix: allow editing dimension styles 2026-08-11 08:40:54 -03:00
Hakan Seven 6fdd090176 fix(ui): restore start actions and web copy
Route About info through browser clipboard on WASM.
Let Start-page links reach the existing command allowlist.

Refs #707
Refs #738
2026-08-11 13:15:09 +03:00
gianlucafiore e2e4bfdcd4 feat(plotstyle): improve CTB editor workflow 2026-08-10 19:09:40 -03:00
gianlucafiore 1cd1b89250 Merge pull request #729 from gianlucafiore/fix/705-grip-dynamic-input
Add dynamic input and precision snapping to 2D grip editing
2026-08-10 13:30:27 -03:00
gianlucafiore 86d7226df6 feat(grips): add dynamic input and precision snapping 2026-08-10 13:26:35 -03:00
gianlucafiore 4697e8cc33 feat(color): add CAD indexed color picker 2026-08-09 23:40:55 -03:00
Hakan SevenandClaude Opus 5 273f482aee refactor: retire the solid3d feature — the web build gets solids too
The feature existed for one reason: truck's mesh and boolean crates reach
`vtkio → xz2 → lzma-sys`, a C library that cannot cross-compile to wasm32. So
the web build dropped it, and with it the Model tab, solid tessellation and
ACIS import — all of which quietly did nothing in the browser.

cadkernel is pure Rust and has no C dependency, so none of that holds any
more. The feature gated exactly two things by the end, `acis_export` and the
save-path sync that calls it, and both are as portable as everything around
them. Removing it means the web build makes primitives, runs booleans, draws
ACIS solids read from a file, and writes them back out as exact geometry — the
same as the desktop build.

Verified against all three: native, `--no-default-features`, and an actual
`wasm32-unknown-unknown` check rather than an assumption about one.

The docs claimed otherwise in four places and are corrected. `tessellation.md`
in particular was organised around whether an entity "goes through truck",
which is no longer a question anything can be asked — the three paths are now
a kernel B-rep mesh, a curve sampled through `entities::curve`, or geometry
emitted directly, and the per-entity table is updated to match.

`index.html` no longer passes `data-cargo-no-default-features`; there are no
features left to turn off.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-10 01:28:25 +03:00
Hakan SevenandClaude Opus 5 8c7ebdc9f1 refactor: drop truck, and evaluate every curve through the kernel
The last four truck crates are gone from the manifest. What they were doing
falls into three parts, and each now has one answer instead of two.

NURBS evaluation. truck was carrying B-spline curves and surfaces for the
SPLINE entity, hatch boundaries, BLEND's endpoint frames, the spline preview
and ACIS spline-surface faces. The kernel now has both, over one de Boor
written across however many coordinates a control point holds — so a plane
curve and a space curve cannot drift apart, and a surface is the same
algorithm applied twice. The rational and the polynomial cases stop being
separate types: weights absent means polynomial.

The entity conversion. Every LINE, ARC, ELLIPSE, SPLINE and polyline was
built into truck topology purely so it could be sampled back into points.
They are sampled through `entities::curve` now, which is where each one's
geometry is already defined once and what EXTRUDE and REVOLVE read — so a
circle drawn on screen and a circle handed to the Model tab come from the
same definition. That retires four of TruckObject's variants and the module
is renamed for what it does.

SWEEP and LOFT. Both only ever produced a mesh, so both are built from point
lists: a band of quads per span, and a lid where a profile closes. Lofting
profiles of different densities resamples them by distance rather than by
index, so a circle lofted to a square no longer twists.

Two things worth noting for anyone reading the old comments. The tolerance
globals that lived in the tessellation module were never about truck at all —
they are the per-frame chord height, and they move to `curve_tol`. And the
rule that a profile handed over as `Lines` silently broke EXTRUDE and REVOLVE
no longer holds: those read the curve directly and never look at this channel.

The two `automation` test failures are unchanged from before this and are not
caused by it.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-10 01:08:50 +03:00
Hakan Seven 8016b79ddf fix(snap): align extension tracking
Require OTRACK crossings to include the active Extension ray and resolve Shift constraints consistently across preview, grips, and clicks.\n\nRefs #716
2026-08-09 23:55:06 +03:00
gianlucafiore af7613f1d8 Merge remote-tracking branch 'upstream/main' into fix/716-perpendicular-tracking 2026-08-09 11:43:08 -03:00
gianlucafiore 080a82306e Fix perpendicular and OTRACK snap interactions 2026-08-09 11:37:21 -03:00
Hakan Seven f57c258ada fix(snap): correct active intersection snapping 2026-08-09 13:27:51 +03:00