tab_display_name() is the drawing's real filename including its own
extension (e.g. "Drawing1.dwg") - the CamExportDialogOpen handler
appended ".stl" directly onto that, producing "Drawing1.dwg.stl" instead
of "Drawing1.stl". Strips the existing extension via file_stem() first.
Root cause of "reopen shows nothing, Zoom Extents finds nothing" for any
solid saved to DWG and reopened: SabWriter round-trips exact transform
values (0/1 in an identity matrix - the common case for a freshly drawn
solid) as compact SAB integer tokens (tag 0x04), not doubles.
body_transform()'s value-extraction loop only tried
coordinate_components() -> as_float() -> as_string(), never as_integer(),
so it silently parsed 0 of 13 values out of a perfectly valid transform
record. tessellate_sat() then hit its own (already-instrumented) "no
resolvable transform" bailout and aborted the whole document.
Reproduced directly against a real saved/reopened file (a standalone
harness against acadrust+cadkernel, bypassing the app's own broken native
desktop build - unrelated pre-existing issues, not touched here): the
transform record's tokens were confirmed to be Sab{tag:4,...}, and adding
the as_integer() fallback resolved them to the expected identity matrix.
Fix: fall back to token.as_integer() (cast to f64) alongside as_float()
in body_transform(). Added regression coverage with a synthetic
SAB-integer-encoded transform record.
The web build's logger (sys.rs's BannerLogger) installs
log::set_max_level(LevelFilter::Error) - warn! records never reach it (or
even the browser console) at all, they're filtered at the macro call site.
error! also gets a free on-page banner via show_banner(), not just a
console line - the more useful behavior for a user hitting this without
DevTools open.
Every early-out here (a bad-body abort, or zero triangles produced) used
to vanish with no trace anywhere, including upstream's own UI - the exact
reason the open '3D solids don't survive save/reopen' bug has resisted
diagnosis so far. Now logs the body index, which step failed, and (for the
zero-bodies case) how many surfaces/curves/pointers lift() couldn't
resolve, so the next real occurrence is diagnosable from the browser
console instead of another silent None. No behavior change - purely
diagnostic.
Every one of those requests 404s from a CMMS deployment - the embedded
editor's build never carries opencadstudio.com's supporters.json /
video_thumbs/*.jpg / discussions payloads (fetched from pages.dev-style
static hosting upstream, not part of trunk build's output), and the
Start page they'd populate is never shown anyway (embedded launches go
straight into a file). Gated on the existing window.CAD_EDITOR_CONFIG
check; standalone/opencadstudio.com use is unaffected.
Introduce a cache for the grid overlay to prevent redundant geometry
reconstruction on every UI redraw. Extract the pure projection logic
from draw_grid into a renderer-free grid_segments function, and add
GridKey and GridCanvasState to memoize the resulting Geometry.
The cache key includes all per-pane GridParams and the overlay bounds,
preventing stale geometry when camera changes within the same canvas
size. On a params-key miss, the iced cache is cleared before redrawing
to bypass its bounds-only reuse.
Tests: 8 new unit tests cover key invalidation and state handling.
Benchmarks: uncached geometry ~32 us/frame vs cached decision ~90 ns,
a >99% reduction. Verified: 472 passed / 1 pre-existing failure / 4
ignored.
Tests:
ui::overlay::grid_key_tests::grid_key_matches_identical_params
ui::overlay::grid_key_tests::grid_key_invalidates_on_changed_fields
ui::overlay::grid_key_tests::grid_key_invalidates_when_any_pane_changes
ui::overlay::grid_key_tests::should_reuse_empty
ui::overlay::grid_key_tests::should_reuse_equal
ui::overlay::grid_key_tests::should_reuse_changed
ui::overlay::grid_canvas_state_tests::default_state_has_no_cached_key
ui::overlay::grid_canvas_state_tests::stored_key_is_recognized_by_should_reuse
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.
The out-of-process plugin design proposal in REPORT.md has been
implemented and evolved to API v4. The current architecture is
documented in ARCHITECTURE.md. REPORT.md is unreferenced and no
longer needed; its content remains in git history for reference.
INSERT enumerated all block names in a single prompt string, causing unbounded overlay growth and full-screen occlusion in drawings with many blocks. Replace prompt enumeration with a ranked, incrementally filtered suggestion model: BlockPicker maintains precomputed lower/upper caches and usage ranks (MRU/frequency), filters via O(n) substring scan and partial sorting (select_nth_unstable) to O(k), bounded to CLIPROMPTLINES.
Introduce CLIPROMPTLINES (Integer 0-50, Registry, default 3) for the number of temporary prompt lines above the command window; persist in UserSettings, expose via SETVAR and direct entry, enforce in CommandLine::view. Suggestion count is in direct relation to CLIPROMPTLINES (limit = clip, capped to 50).
Make search live without requiring Enter: add CadCommand::on_live_input, implement for INSERT/MINSERT via picker.set_needle, and wire to command-line input paths (Message::CommandInput, on_command_append_char, on_command_backspace). Updates use upper/lower caches and partial sort for <0.2ms per keystroke on 10k blocks, with debounced block-usage persistence (MRU cap 20, freq cap 200) to avoid I/O thrash. Correct tri_count test helper to use display_from_solid.
- Add HostNotification::SelectionChangedV4 { tab_id, handles } with discriminant 7
- Broadcast active-tab selection changes at update() and automation_op boundaries
- Use stable order-independent signature to avoid spurious hover notifications
- Clear Scene selection in automation new/open to avoid stale handles
- Add crates/ocs_plugin_api/ARCHITECTURE.md and module-level rustdoc
- Cross-link README.md and docs/plugin-architecture.md
- Fix test env race with shared ENV_LOCK and EnvVarGuard helpers