Commit Graph
478 Commits
Author SHA1 Message Date
PanosandClaude Opus 5 38f576c296 perf: warm the interaction handle index during open
The first hover over the canvas after opening a large drawing froze the
UI for a second:

    hover-detail  query=0.2 handles=986.1 ... candidates=253
    hover-dwell   986.6ms

`interaction_handle_index` and the insert-hatch map it reads are built
lazily, and first use is that hover. Neither can move to the loader
thread: they read `hatches`, `meshes` and `block_meshes`, which are
installed on the real `Scene` only after the loader has finished.

Build them at the end of the open instead, where the user is already
waiting. This does not make the work cheaper -- open grows by roughly the
second the hover used to cost -- but a second inside an operation that is
already seconds long reads very differently from a second-long freeze on
a mouse move.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-05 09:10:48 +03:00
PanosandClaude Opus 5 d5d9ceec45 perf: hand the loader thread's tessellation memo to the scene
`prepare_open_geometry` builds the first Model wire set on a throwaway
`Scene`, filling its per-entity tessellation memo with an entry for every
one of the drawing's 186 455 entities. `install_prepared_open_geometry`
then transferred the wire set and the interaction index but not the memo,
so the temporary scene took it to the grave.

The first geometry edit therefore rebuilt from cold:

    wires-build 2723.3ms memo_hit=0 memo_miss=186455

against 760 ms once the memo is warm -- 1.3 s of work the loader thread
had already done, repeated on the user's first action.

`PreparedOpenGeometry` now carries the memo, moved rather than cloned
since the scene is dropped immediately afterwards. The guard hash travels
with it: the memo is only usable under the state it was built for, and a
mismatch on the receiving side clears it, which is what happened
unconditionally before.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-05 09:10:48 +03:00
PanosandClaude Opus 5 2d2fdacdfd perf: parse each wire name once when applying draw order
The resident wire sort keys on the entity handle parsed out of each
wire's name `String`. `sort_by_key` evaluates that key on every
comparison, so a 198 k-wire resident set parsed every name roughly
eighteen times over.

Measured at 295 ms on every rebuild of the resident set -- including
rebuilds that re-tessellated nothing, where the memo hit on all 186 455
entities and the sort was most of what was left.

`sort_by_cached_key` evaluates the key once per element. It is stable in
the same way `sort_by_key` is, so draw order is unchanged.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-05 09:10:48 +03:00
Hakan Seven 9d991d7feb Bound GPU uploads and complete Greek and performance integration 2026-09-04 20:26:29 +03:00
Hakan Seven 89624f64fc Merge PR #1002: opt-in performance instrumentation 2026-09-04 20:11:02 +03:00
Hakan Seven 92e1dfd685 Merge PR #1000: cache selection filter entity types 2026-09-04 20:06:56 +03:00
PanosandClaude Opus 5 f1efc73cbe perf: stop rescanning every entity to fill the selection-filter menu
Pan and even plain cursor movement over the canvas ran at ~8 fps on a
large drawing. Nothing rendered was responsible: the GPU idled at 0-8%,
encoding no scene at all changed nothing, and vertices, pixels and draw
calls could each be cut without moving the number. `view` was the frame
-- 110 ms of it against 3-6 ms on a small drawing -- and inside `view`
it was the status bar.

The status bar builds the selection-filter menu, which asks for the
distinct entity type names in the layout. That call cloned the layout's
entire handle list (1 166 357 handles, ~9 MB), then did a map lookup, a
String allocation and a BTreeSet insert for each one. About 107 ms of a
110 ms frame, to produce roughly twenty names, for a menu that is only
visible when opened.

Cache the result against geometry_epoch and the layout block, since it
only changes when entities are added or removed, and make the scan
itself borrow the handle list rather than clone it and collect &str,
allocating only for the names it returns.

The immediate-mode UI rebuilds every widget on every mouse move, which is
fine as long as nothing in that path is O(document). This was.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-04 16:20:30 +03:00
PanosandClaude Opus 5 2787dcc1a3 perf: instrument the file-open load path behind PERF
The 52 s silent stretch in a large-DWG open could not be attributed:
OpenTimings covered parse / purge / xref / caches, but the FINALIZING
phase -- prepare_open_geometry, which does the first full Model
tessellation and builds the interaction index -- was unmeasured and
reports only two progress ticks, so it was indistinguishable from parse
time.

Add finalize_ms to OpenTimings and a per-stage PERF breakdown:

  open-phases     parse / purge / xref / caches / finalize
  open-finalize   tessellation vs interaction index
  open-index      index build vs prepare_screen
  wires-build     sort cache, visible filter, block cache, classify,
                  memo hits, parallel tessellate, materialize, sort
  resident-post   scene markers, refedit fade, resident layout
  wire-upload     build_wire_buffers, which runs on the render thread

The wires-build line separates the parallel tessellate from the serial
materialize loop that deep-clones every WireModel while the memo retains
a second copy -- the leading hypothesis for both the stall and the
6.45 GB RSS.

No behaviour change. Every timer is gated on crate::perf::enabled(), so
nothing runs without PERF=1 or the in-app PERF panel. The localized
open-summary format string is left alone; changing it would rekey the
string across every locale, so the full breakdown goes to PERF instead.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-04 16:20:30 +03:00
ramox81 9279384e9a Complete PRESSPULL selection, face editing and extrusion history 2026-09-04 15:31:30 +03:00
ramox81 479bf87988 Complete LOFT commands, surfaces, previews and editable history 2026-09-04 13:03:33 +03:00
Hakan Seven 3088e641aa fix(view): stabilize 3D navigation and hidden lines
Refresh stale depth bounds after geometry edits, allow orbiting through camera poles, and preserve hidden-line occlusion for selected solids.\n\nFixes #957
2026-09-03 20:22:35 +03:00
Hakan Seven b5a926cc20 Merge remote-tracking branch 'origin/main' into review/pr-986
# Conflicts:
#	Cargo.lock
#	Cargo.toml
2026-09-03 19:52:20 +03:00
Karim Jerbi 688785a6cf feat(model-space): theme-aware model space canvas and CAD selection/grip sysvars
Model space appearance now follows the active UI theme instead of a
hardcoded dark background. Canvas mode is user-selectable (Match Theme /
Classic CAD Dark / Custom RGB), with matching controls for the paper
sheet and desk surround backgrounds and grid opacity.
Implements industry-standard CAD system variables, all settable via
command name, SETVAR, and the Options dialog:
- COLORTHEME (0/1 dark/light UI scheme, preserves custom palettes)
- COLORSCHEME (interactive named-theme selection)
- BACKGROUND (THEME/CLASSIC/DEFAULT/DESK presets, RGB triplets)
- SELECTIONAREA, SELECTIONAREAOPACITY (translucent marquee fill)
- WINDOWSAREACOLOR/WINDOWAREACOLOR, CROSSINGAREACOLOR (ACI or theme)
- SELECTIONEFFECT, SELECTIONEFFECTCOLOR (GPU highlight pass, driven by
  selection_generation invalidation — no retessellation)
- SELECTIONPREVIEW (bit 0 = idle rollover, bit 1 = in-command hover)
- GRIPSIZE, GRIPCOLOR, GRIPHOT, GRIPHOVER (grip overlay styling)
2026-09-03 17:44:44 +01:00
ramox81 1a913ee640 Fix revolve angle and wireframe display 2026-09-03 16:24:43 +03:00
ramox81 ea6eb58c53 Fix extruded solid grip preview and taper range 2026-09-03 10:35:02 +03:00
Karim Jerbi 46190ccba1 refactor(selection): migrate Scene.selection to Arc<RefCell> to avoid per-frame deep clone
Scene.selection was Rc<RefCell<SelectionState>> (31 fields, ~1.6KB
with poly_points) cloned deep per view_main per pane via
(*sel_ref).clone() at view/mod.rs:760. Replace with
Arc<RefCell<SelectionState>> (Arc::new(RefCell::new(...)) at
scene/mod.rs:1436,1868), SelectionCanvas holds Arc<RefCell> and
selection_overlay takes Arc<RefCell> (overlay.rs:365,415),
view_main does Arc::clone(&tab.scene.selection) (atomic bump)
instead of deep clone. sel_ref stays borrowed for field reads
(vp_size etc.).

Bench (release, n=5000): SelectionState::clone 39-68ns (64pts) /
11-22ns (0pts) vs Arc::clone 7ns — 5-9x on the hot path.

Tests:
- selection_is_arc_not_refcell: asserts type_name contains Arc
- bench_selection_state_clone / bench_selection_arc_clone / bench_selection_state_clone_empty (ignored, release)
2026-09-02 22:14:32 +01:00
Hakan Seven 76bdab1e5b feat(display): add model lineweight scale 2026-09-02 23:03:04 +03:00
Hakan Seven dba81bc8b6 Use feature edges for normal 3D selection (#971)
Use feature edges for normal 3D selection
2026-09-02 17:45:27 +03:00
Hakan Seven 7f03456cfe fix(selection): limit solid edge candidates 2026-09-02 17:44:58 +03:00
ramox81 a706858ff1 Use solid edges for normal selection 2026-09-02 14:38:22 +03:00
ramox81 847d218c35 Complete EXTRUDE behavior and properties 2026-09-02 10:25:00 +03:00
Hakan Seven 6606da5029 fix(blocks): complete block-backed instance rendering 2026-09-01 22:41:12 +03:00
ramox81 0f4825f06c Align CONE properties and editing 2026-08-31 11:58:29 +03:00
Hakan Seven 19629d1246 fix(blocks): unify block-backed content
Route pictures, table cells, leader content, symbols, and arrows through one dependency and transform graph.\n\nRefs #864
2026-08-31 01:09:32 +03:00
Hakan Seven d991289a56 chore(dimension): sync with main 2026-08-28 19:01:59 +03:00
ramox81 d8e998b5e8 Complete continued dimension workflow 2026-08-27 15:22:12 +03:00
ramox81 c6f6c00220 Add dimension continuation creation policy 2026-08-27 11:49:32 +03:00
Hakan Seven 81e7add1dd fix(tolerance): complete workflow integration
Sync current main and companion codec changes before preserving unsupported frame rows, rendering in the entity plane, and sharing final layout metrics with placement preview.
2026-08-27 00:14:08 +03:00
Hakan Seven 8c61d89b1e fix(layout): complete paperspace integration
Apply each layout's embedded page setup and plot style consistently across display, PDF, printing, and multi-layout output.\n\nRefs #844
2026-08-26 08:58:44 +03:00
Hakan Seven 81de94fdbb fix(zoom): include inserted block extents
Use current rendered geometry instead of load-time cluster spans when fitting model extents.

Refs #853
2026-08-25 22:11:18 +03:00
ramox81 a30010cb3e Keep linear dimensions associated with sources 2026-08-24 12:10:29 +03:00
Hakan Seven 06cd0ec6a9 feat(model): add exact solid modelling tools 2026-08-23 22:53:31 +03:00
Karim Jerbi 236b7756f8 feat(draworder): HATCHTOBACK command and interactive DRAWORDER workflows
Implement the AutoCAD compatible HATCHTOBACK (HB) command and enhance the interactive DRAWORDER command pipeline with comprehensive verb selection and viewport entity picking.

Key implementations and architectural details:

1. HATCHTOBACK command execution
   * Isolates entities belonging to the active layout block record or global space.
   * Filters out entities residing on locked layers using an efficient hash set lookup.
   * Records targeted delta undo operations on SortEntitiesTable objects (~100 bytes) rather than snapshotting full document structures.
   * Performs granular draw depth cache invalidation via Scene::invalidate_draw_depth, preserving existing geometry tessellations and spatial indices.
   * Emits localized user notifications when no qualifying hatch entities are found.

2. Interactive DrawOrderCommand state machine
   * Supports preselected entities as well as interactive on demand selection gathering.
   * Implements subverb selection supporting single character shortcuts (A for Above, U for Under, F for Front, B for Back) and case insensitive keyword parsing.
   * Enables interactive reference object picking directly in the viewport via needs_entity_pick and on_entity_pick callbacks.
   * Supports hexadecimal handle specification directly from the command line interface.

3. Ecosystem and system integration
   * Bumps DEFAULT_ALIASES_VERSION from 2 to 3 to register the HB alias while preserving existing user overrides.
   * Integrates HATCHTOBACK and HB into dynamic autocomplete registries.
   * Adds localized message strings across all 20 Fluent translation catalogs.
   * Corrects hatch boundary serialization flags to ensure outermost boundary rings consistently carry the external attribute.
2026-08-23 18:56:01 +01:00
Hakan Seven 44a40eda0b fix(model): restore saved solid booleans
Reload exact B-reps from solid history or ACIS before model operations and pin the closed-cut kernel fix.
2026-08-23 19:35:48 +03:00
Hakan Seven e94cbedaa2 fix(save): preserve 3D view and thumbnails
Persist camera, render state, and solid fallback geometry across saves. Generate previews from a clean live viewport and refresh recent-file thumbnails immediately.
2026-08-23 17:59:12 +03:00
Hakan Seven 339d9afcfe Merge pull request #857 from ramox81/codex/align-point-behavior
Align point command, properties, and display behavior
2026-08-22 22:58:42 +03:00
Hakan Seven 7293bec1b9 fix(point): preserve relative marker sizing
Keep rendering, picking, block transforms, and plotted output on the
same viewport-relative PDSIZE geometry without overloading wire width
fields.
2026-08-22 22:22:01 +03:00
Hakan Seven e5b84ab8de fix(plot): honor wipeout draw order 2026-08-22 15:33:43 +03:00
Hakan Seven bd5f9436ea Merge pull request #852 from ramox81/codex/complete-hatch-workflow 2026-08-21 21:02:14 +03:00
Hakan Seven 4bc02b6b4a fix: correct hatch geometry workflow 2026-08-21 20:52:03 +03:00
Hakan Seven b648000e78 Merge pull request #850 from ramox81/codex/associative-center-mark 2026-08-21 20:19:54 +03:00
Hakan Seven 77e1f1b876 fix(plot): respect non-printing layers
Filter nested block, attribute, table, hatch, and wipeout geometry during export while preserving canvas visibility.
2026-08-21 18:57:23 +03:00
ramox81 f83037271c Complete hatch creation and editing workflow 2026-08-21 12:57:19 +03:00
ramox81 ff09fc7800 Implement associative center mark workflow 2026-08-21 12:05:18 +03:00
ramox81 eba4fb87a8 Complete associative centerline workflow 2026-08-21 11:01:18 +03:00
Hakan Seven 44efb8fd53 feat(frame): complete frame controls
Preserve frame geometry for selection while separating viewport and plot visibility across supported reference entities.

Refs #642
2026-08-20 23:37:02 +03:00
Hakan Seven 2a852f4479 feat(gradient): align editing and rendering 2026-08-20 21:17:10 +03:00
Hakan Seven 0e944c19a6 feat(boundary): trace exact planar loops 2026-08-20 19:44:16 +03:00
Hakan Seven bb49f92e99 fix(model): repair solid booleans
Track selection order for directional subtraction and use the kernel fixes for periodic curved-face intersections.\n\nRefs #816
2026-08-20 16:00:20 +03:00
ramox81 4d2e8bf0b0 refactor(gradient): remove obsolete outline collector 2026-08-20 15:41:45 +03:00