Box selection is a two-click window (corner, corner): the first empty
click armed the box AND cleared the selection, and the box completion
cleared again before applying its hits — so a second box dropped
everything the first one picked. Stop clearing on the arming click and
make the completion accumulate like individual picks (#47): a plain box
or lasso adds, Shift+box/lasso removes the enclosed entities, an empty
box/lasso (or Esc) clears.
Fixes#83
Co-Authored-By: Claude Opus 4.8 <[email protected]>
The trim/extend hover preview (on_hover_entity) gets the cursor in
offset-relative space but compares it against WCS document entities and
returns WCS preview wires. On a drawing with a non-zero world_offset the
preview highlighted the wrong segment and the wires were shifted off the
geometry by the offset. Pass the world-offset-corrected click to
on_hover_entity and shift its returned wires back to the offset-relative
frame the renderer uses. Point-creation previews keep the local cursor.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
The pick point handed to commands is in offset-relative (local) space,
matching the camera and point-creation commands. Entity-pick, tangent
and structure-pick handlers (TRIM / EXTEND / FILLET / OFFSET, …) instead
compare the click against WCS document entities, so on a drawing with a
non-zero world_offset (UTM-scale coordinates) the click landed ~1e6
units off the geometry — TRIM cut the wrong side or reported the click
as off the segment. Add world_offset back to the pick (model space only)
before passing it to those handlers, matching what the grip path already
does. Point-creation commands keep the local point unchanged.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
A block reference with a visibility parameter now shows a triangular
lookup grip at the parameter point. Clicking it opens a dropdown of the
named states (current one marked); picking a state toggles which of the
anonymous block's members are visible and rebuilds, so the reference
shows the chosen profile instead of being frozen on the saved state.
The state list is data-driven (owned strings from the file) and applying
it mutates other entities (the anonymous block's members), so it stays
separate from the static GripMenuAction grip-menu: a dedicated
VisibilityPopup and an app-level apply path. The anonymous block is a
parallel-ordered clone of its definition, so a member visible in the
definition's state maps to the same index in the inserted block; the
chosen visibility flags round-trip through the DWG writer.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Grip markers drew visibly offset from the entity on large-coordinate
(UTM-scale) drawings: every Grippable impl cast the f64 entity coordinates
to f32 BEFORE the world-offset subtraction, and at 1e7 magnitude an f32
holds ~0.9 drawing units of rounding error. The wires subtract the offset
in f64 first (precision-preserving), so the grips landed up to ~1 unit
away from the geometry they belong to.
GripDef.world is now DVec3: producers fill it straight from the f64
entity data, refresh_selected_grips subtracts the world offset in f64,
and only the small offset-local result is cast to f32 for screen-space
projection (grips_to_screen / find_hit_grip) and drag state.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Bump acadrust to pick up the new $CTABLESTYLE / $CMLEADERSTYLE header
variables, then on load seed the ribbon's active table style and the
tab's active multileader style from the document header so the ✓ marks
the style the file actually declares (DXF). Set Current writes the header
field as the round-trip source of truth, and the style-manager staging
snapshot now covers it. sync_ribbon_styles honours the active table style
instead of always falling back to the first one.
DWG still leaves these at "Standard" until acadrust parses them from the
binary header.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Every style manager now shows a leading ✓ next to the current style
(current text/dim style, active table/multileader/multiline style), with
the other rows padded so names stay aligned. The marker replaces the
multileader/multiline-only ◀ and is wired for all five managers by
threading the current-style name into each view.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
A style manager is now a staged transaction. When it opens, a snapshot of
the style tables, style objects and current-style pointers is taken. Every
New / Copy / Delete / Rename / Set Current / property edit mutates the
document live so the dialog previews the result, but the tab is not marked
dirty, nothing is pushed to undo, and the drawing is not rebuilt.
- Apply commits: one undo entry (restoring the pre-edit state), the tab is
marked dirty, the drawing rebuilds, and the baseline is reset so further
edits stage afresh.
- Closing the window without Apply discards: the opening snapshot is
restored, so none of the changes persist.
Side effects (dirty / undo / bump_geometry) were removed from every style
edit handler and routed exclusively through the commit. Multiline's Apply
is a structural-only commit since its editor has no editable properties.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
The list row wrapped a `button` inside the `mouse_area`. The button
captured the press, so the parent `mouse_area` never saw the second
click and `on_double_click` never fired — double-clicking a style name
did nothing.
Drop the inner button: the row is now a plain `mouse_area` carrying both
`on_press` (select) and `on_double_click` (start rename), with selection
shown via the container background. Focus the rename field on start so
the user can type immediately.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
The text/dimension/table/multileader/multiline managers were hand-copied,
so their list CRUD kept drifting and breaking: Dimension's New created
nothing (#73), new text styles never reached the ribbon dropdown (#74),
and several were added with a NULL handle (dropped on DWG save, #67).
Collapse the duplicated parts into three shared pieces and leave only the
per-manager property editor bespoke:
- app/style_ops.rs: one StyleKind-dispatched CRUD layer (new / copy /
delete / rename) handling handle allocation, ribbon sync, Table re-key
and name-reference rewrites in a single place.
- ui/style_manager.rs: the window scaffold — uniform toolbar (New / Copy /
Delete on the left, Set Current + Apply on the right), style list and
chrome. Each manager now only builds its editor.
- ui/style_list.rs: the list row — single click selects, double click
starts an inline rename.
New capabilities, now consistent across all five:
- Copy duplicates the selected style.
- Double-click a name to rename it inline.
- Right side is always Set Current + Apply (added Table set-current;
MLine apply is a documented placeholder until its editor is editable).
Co-Authored-By: Claude Opus 4.8 <[email protected]>
PR #80 added the internal SnapType::ObjectPick variant, which left the
exhaustive snap_id match in the settings module non-exhaustive and broke
the build after the merge. Map it to a stable id; it is not a
user-toggleable OSNAP mode, so it never enters SNAP_ORDER or the
persisted set.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
POLAR locked the cursor to the nearest angle everywhere, so it could
never point between angles. Snap only when the cursor is within the snap
aperture (in screen pixels) of a polar ray; otherwise leave it free, so
POLAR behaves as if off when pointing away from every angle. The polar
guide line now shows only while actually snapped.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
OTRACK alignment was computed in the wrong plane (it used Z as the
second axis while the model is XY / Z-up), so tracking never aligned
correctly and the aligned point was never fed to a pick.
Rework it: project the cursor onto a ray from a tracking point in the
XY plane — horizontal/vertical by default, or every POLAR increment
when POLAR is on. The aligned point is now used for both the live
preview and the committed click, and a dashed guide shows the ray.
While aligned, a typed distance places the point along the ray from the
tracking point, via the command line and the dynamic-input box (which
shows a single Distance field). The alignment clears with the command.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
OTRACK acquired tracking points by dwell during a command or grip drag,
but only cleared them when OTRACK was toggled off — so the temporary
tracking-point symbols (drawn straight from the point set) lingered in
the view after the command ended.
Drop the tracking points once neither a command nor a grip drag is
active. Acquisition only happens during those, so this covers every
exit path (Esc, cancel, commit) from one place. The tracking vector is
a preview wire already cleared on cancel.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
DYN, ORTHO, POLAR, the polar increment, the grid toggle and the
object-snap configuration (OSNAP on/off, active snap modes, OTRACK)
reset to defaults on every launch. Persist them to a per-user
settings.txt, matching the existing recent-files / status-bar stores
(plain key=value, no serialization crate).
Settings load on boot and apply to live state; the update wrapper
snapshots them after each message and writes only on change, so a
toggle survives a restart without thrashing the file. LWT is left out
on purpose — it is a drawing header variable, not a UI preference.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
New layers were added to the table with a NULL handle, and the first
patch used the non-advancing `next_handle()` getter, so two new layers
(or a layer and the next allocated object) shared one handle. The DWG
format is handle-based, so the collision dropped the layer on save;
DXF is name-based and survived, which is why a rename appeared to fix
it.
Allocate a unique advancing handle via `allocate_handle()` in LAYER NEW
(panel + command line) and on rename when the source handle is invalid.
Rename now also clones the whole record so colour/linetype/lineweight
are kept, not just the flags.
Adds DWG/DXF round-trip tests covering one and multiple new layers.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
iced has no built-in ellipsis, so long user content (file names, layer
names, paths, property values) wrapped or spilled past fixed-width
panels. Add an `elide` helper (char-budget truncation with a trailing
ellipsis) and apply it to the layer manager, properties panel, document
tabs, recent-files list and the save dialog.
In the layer manager a truncated name reveals its full text in a
cursor-following tooltip on hover, so the column need not be widened.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
The current step's prompt was written into the command-line widget
label. Instead, keep it as a normal history line but freeze its
cooldown: the step prompt is pinned so it does not fade while the user
is still on that step. When the step changes the previous line's
cooldown restarts; when the command ends the pin clears and it fades.
`update` is now a thin wrapper that mirrors the active command's prompt
into the command line after each message; the body moved to
`update_inner`.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
The save dialog wrote the typed name verbatim, so entering "foo" with
DWG 2018 selected produced an extensionless "foo". The extension was
only added when the format pick-list changed, not on confirm.
Now confirm appends the selected format's extension when the name has
none (empty name falls back to drawing.<ext>); a name that already
carries an extension is left untouched.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Text-input steps (OFFSET distance, POLYGON sides, radii, counts) were
swallowed by the dynamic-input overlay: typed digits landed in the field
buffer and Enter committed a point pick, so the value never reached
on_text_input (issue #61). Now each text step shows one scalar box whose
value routes to on_text_input on commit; non-numeric prompts (names,
keywords) keep going to the command line so mixed text like "Bolt12"
isn't split.
OFFSET reworked: object first, then through-mode by default — the offset
follows the cursor at the perpendicular distance to the object. Typing a
number locks the magnitude (cursor then only picks the side); a value
typed and clicked without Enter is applied before the point pick.
The dynamic-input overlay and the command line now show the active
step's prompt and hold it until the step completes.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Reports showed structure placement could stall if command-line text entry
didn't register (ribbon-invoked commands, dynamic-input/focus interactions).
Make a canvas click ALWAYS place a structure, using whatever values were typed
so far (defaults for the rest) — so dropping an inlet works regardless of typed
entry. If typing works, enter invert/rim/area/C first, then click to place with
those values. Pipes are pick-first: click START then END structure; the pipe
commits on the second click with the current diameter/n.
Drop the early focus_cmd_input() return in the dispatch arms (the normal
dispatch tail already focuses the command line and records last_cmd).
15 module tests green.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
The structure/pipe commands took a viewport interaction first and then asked
for typed values. But a point-pick result (NeedPoint) does not re-focus the
command line, so after the click the typed digits went nowhere and Enter hit
on_enter -> Cancel ("Command cancelled.").
Reorder both commands to the OFFSET-style flow: collect typed values first
(command line focused at dispatch and kept focused through text input), then
take the viewport click last and commit from it.
- PlaceStructure: enter invert/rim/area/C, then click the location.
- PlacePipe: enter diameter/n, then click START and END structures; commit
from the second pick using the click points (connectivity stays exact via
structure handles).
- Dispatch arms focus the command line so the first prompt is typeable.
- Reverts the update.rs inject_picked_entity allow-list change (the pt-based
pipe no longer needs the picked entity).
15 module tests updated and green.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Replaces the .ssn-file workflow with an interactive one driven by the canvas:
- Structures (SS_INLET / SS_JUNCTION / SS_OUTFALL) prompt invert/rim/area/C on
the command line and commit a CIRCLE tagged with STORMSEWER_STRUCT XDATA
[kind, invert, rim, area, C]. Outfalls skip area/C.
- SS_PIPE picks a START and END structure (entity-pick), snapping its endpoints
to their centers, prompts diameter/n, and stores connectivity (the two
structure handles) in STORMSEWER_PIPE XDATA [diameter, n, from, to].
- SS_ANALYZE / SS_REPORT / SS_PROFILE rebuild the network from the drawn
entities (data.rs::network_from_entities) and analyze it directly; SS_ANALYZE
overlays flow/HGL labels without redrawing the geometry.
Because the data lives on the entities as XDATA, the network round-trips to
DWG/DXF. One additive line in src/app/update.rs adds SS_PIPE to the
inject_picked_entity allow-list so the command can read the picked structure's
center for snapping.
15 module tests cover the XDATA round-trip, analyze-from-drawing, and the
command step machines.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Adds a "Storm Sewer" ribbon tab backed by a new in-repo `stormsewer` engine
crate (vendored under crates/). The engine implements standard public-domain
methods — Rational-method peak-flow accumulation, Manning circular-pipe
hydraulics, time-of-concentration / IDF intensity, and an HGL backwater pass
with junction losses — with 24 unit tests and no external dependencies.
Module (src/modules/storm_sewer/):
- Drafting: SS_INLET / SS_JUNCTION / SS_OUTFALL place structure markers and
SS_PIPE chains pipe runs (interactive CadCommands).
- Analysis: SS_ANALYZE / SS_REPORT / SS_PROFILE open a .ssn network file, run
the engine, draw the plan and HGL long-section, and print a report.
- SVG icons; SS_* commands registered for command-line autocomplete.
Integration is additive: build.rs auto-discovers the module and one dispatch
block is added to src/app/commands.rs. 7 module integration tests.
See src/modules/storm_sewer/INTEGRATION.md for the design and the optional
follow-up (drive analysis from canvas geometry via XDATA).
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Phase 2.2. wires_for_block_culled re-tessellated every visible entity on
any geometry bump, so a single-entity edit cost a full model re-tess
(~30ms baseline after the block_epoch fix).
Add a per-entity memo (tess_memo: Handle -> Arc<Vec<WireModel>>) on the
culled Model render path. It's guarded by a hash of the tessellation
parameters (tol / view / anno / world_offset / bg / entered viewport); a
mismatch (zoom, layout switch) clears it. The render path now classifies
the visible set against the memo, materializes hits and tessellates only
the misses in parallel, then stores the misses back.
- bump_geometry clears the memo (structural change — safe default);
- incremental edits drop just the changed handle via mark_entity_dirty
and bump with bump_geometry_no_blocks: line commit (new handle is a
natural miss) and grip commit / Esc-cancel (mark the dragged handle).
The hit-test (view_aabb == None), paper and per-viewport paths bypass the
memo so their differing cull parameters don't thrash it. A single-entity
edit now skips the per-entity geometry math for the entire unchanged set;
the Vec assembly + batched-buffer upload stay O(N).
Co-Authored-By: Claude Opus 4.8 <[email protected]>
The block-definition tessellation cache (BlockCache::build — every block
defn) was keyed on geometry_epoch, so every edit rebuilt all block defns.
On a block-heavy drawing that turned the ~30ms visible-wire re-tess into a
~400ms spike at line-commit, grip first-move and grip release.
Key the block cache on a separate block_epoch. bump_geometry bumps both
geometry_epoch and block_epoch (safe default — xref, block create,
explode, REFCLOSE, undo, open all keep rebuilding blocks). Operations that
provably can't change a block definition now call bump_geometry_no_blocks,
which bumps only geometry_epoch so the visible wires re-tessellate against
the reused block cache:
- add_entity for a non-Insert/Block entity (line, arc, text, hatch, …) —
scene.add_entity only ever routes to model/paper space, never block
content;
- grip drag hide / commit / Esc-cancel — moving a top-level entity or an
insert never edits a block defn.
Line-commit and grip start/end drop from ~400ms to the ~30ms baseline.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
The grip drag mutates the document live (so grips and the properties panel
track the cursor), which meant Esc left the entity at its dragged position.
Back up the edited entity when the drag starts (the same first-move point
that hides it for the overlay preview) and, on Esc, restore that backup
before un-hiding and re-tessellating — reverting the entity to where it was
when the drag began. A normal release drops the backup and keeps the
dragged geometry.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Phase 2.2 (partial). Dragging an entity's grip called scene.apply_grip on
every mouse move, which bumped geometry and re-tessellated the whole model
per move (plus an O(N) clone of every wire to exclude the edited one from
snapping). On a large drawing that's the 30ms->400ms spike, per frame, for
the duration of the drag.
apply_grip no longer bumps. The drag flow now:
- first move: hide the edited entity from the base tessellation (one
re-tess) and record it in grip_preview_handle;
- each move: apply the grip to the doc (no bump) and show the entity as a
one-entity overlay preview (set_preview_wires) — the base is a cache hit;
- commit on release / Esc: un-hide, drop the preview, one final re-tess.
Because the edited entity is hidden, it's already absent from
hit_test_wires, so snapping runs against the cached set directly — no
per-move clone and no self-snap. Two re-tessellations per drag instead of
one per move.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Now that selection/hover are decoupled from tessellation, highlighting the
entity under the cursor only refreshes the GPU xray overlay — no
re-tessellation — so a general rollover is cheap. On an idle ViewportMove
(no active command, no drag) hit-test at the cursor and set_hover_highlight
the result; clear it during commands/drags and on ViewportExit so it
doesn't stick over the ribbon. hit_test_wires is the cached entity-wire
Arc, so the per-move cost is just the existing click_hit projection — the
same the command-hover path already pays.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Phase 5.3 (CPU tessellation slice). Add a `PERF` command that toggles an
overlay on the active viewport showing the cost of the most recent wire
re-tessellation: ms, wire count, geometry epoch. Anchored top-left via
position_canvas_overlay.
Timing is captured at the wire-cache miss paths (model_tile_wires_arc,
paper_sheet_wires_arc) and stored in Cells on Scene, read directly by the
UI view (Scene is single-threaded / Rc-based, so build_primitive and view
share a thread). Reads ~0 ms on a warm cache, so it isolates the exact
work a miss costs — the slice 2.2 / 3.1 / 3.3 each move, making them
PR-to-PR comparable.
GPU upload/draw/GPU-wait spans (need wgpu timestamp queries) remain open.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Phase 5.2. Time each open phase — parse, purge, derived-cache build on
the loader thread, plus xref resolve on the UI thread — and emit a
breakdown line on open completion:
parse 1240ms · purge 80ms · caches 340ms · xref 60ms · total 1820ms
Makes open-time regressions (and the wins from 1.1 / 2.4) visible at a
glance. Timings ride back on DerivedCaches; total is wall time from the
Open click to post-xref.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Phase 4.1. Handle / u64 keys dominate the hot maps (block_defn,
hatch / image / mesh caches, draw-depth map, viewport wire caches);
the default SipHash is wasted work on integer keys. Alias the std
types to rustc_hash::FxHashMap / FxHashSet crate-wide so every map and
set — including the cross-module draw-depth map shared between scene
and the GPU pipelines — uses the faster hasher consistently.
Mechanical: no behavioural change. Constructors moved from ::new() to
::default() (Fx variants carry no RandomState). Build + 13 tests green.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Phase 1.1: resolve_xrefs now purges corrupt entities inline as it
merges each xref and returns the dropped count, removing the second
full-document purge_corrupt_entities walk in the FileOpened handler.
Every xref-bearing open saves one O(N) entities() pass.
Phase 2.4: split compute_world_offset into offset_prep / offset_centroid
/ world_offset_from_centers; centroid accumulation now rides the existing
cache-handle walk in build_derived_caches. Two O(N) entity walks collapse
into one, with identical MSPACE-membership filtering preserved.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Row exit now clears the preview only when the highlight still points at
that row. Moving between rows can fire on_enter before the previous
row's on_exit, so the unconditional clear wiped a freshly highlighted
row (notably when returning to the first row). Guarding the clear fixes
the highlight not reappearing.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Add a scene hover_highlight handle that renders an entity with the
selection colour without joining the real selection. The cycling list
box sets it on row enter / clears on exit, so hovering a row glows the
matching object in the drawing.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Replace the repeat-click cycling with a list box: when a click lands on
two or more overlapping objects (cycling on), a small list of the
candidates opens at the cursor. Picking a row adds that object to the
current selection (accumulate); clicking outside dismisses it. A single
object under the cursor falls through to the normal click.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Add a click_hits_all hit-test and an SC pill that, when on, makes
repeated clicks at the same spot step through the overlapping objects
there (nearest first) instead of accumulating the selection. The whole
cycling path is gated behind the toggle, so default picking is unchanged
when it is off.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Add a per-type selection filter to the scene: the FILTER pill opens a
checklist of the entity types in the layout, and unchecking a type
excludes it from interactive picking (click, box and lasso selection all
honour it). The pill lights up while any type is filtered out.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
When the QP pill is on, a compact floating panel appears at the canvas
top-left on selection, reusing the docked panel's editable section rows.
Toggleable from the status-bar customization menu.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Add a transparency_enable uniform read by the wire shader: when the new
TPY pill is off, every line is forced opaque; when on, baked entity
transparency shows through. Toggling is a uniform write, no retessellate
(same mechanism as the lineweight-display toggle). Pill is toggleable
from the status-bar customization menu.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Clicking the ISO pill now opens a small menu with Isolate Objects, Hide
Objects and End Isolation instead of ending isolation directly; rows
that don't apply (no selection / nothing hidden) are dimmed. The same
actions are added to the viewport right-click menu.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Add a hidden-entity set to the scene that the tessellation visibility
test skips, so hidden objects neither render nor hit-test. New commands
ISOLATEOBJECTS (show only the selection), HIDEOBJECTS (hide the
selection) and UNISOLATEOBJECTS (restore). An ISO status pill lights up
while anything is hidden and restores everything on click.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Add a Units pill that shows the drawing's current INSUNITS value and
opens a picker to change it (Unitless, mm, cm, m, km, in, ft, mi, yd).
Toggleable from the status-bar customization menu like the other pills.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Add a customization menu (far-right handle) that lists every status-bar
pill with a check mark; toggling a row shows or hides that pill, and the
choice persists across sessions in the config dir.
New pills:
- Coordinates: live cursor readout (re-adds the model-space world offset
so it shows true drawing coordinates), updated on every move rather
than only while a command is active.
- Clean Screen: hide the ribbon and side panels for a full canvas.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Read the model-space annotation scale from the standard CANNOSCALE /
CANNOSCALEVALUE header variables instead of a user-variable hack, and
populate both the status-bar scale picker and the viewport Scale
property purely from the drawing's ACAD_SCALELIST — no built-in
fallback set. Xref-derived scales (`_XREF` suffix, `name|` prefix)
are filtered out so only the host drawing's own scales appear.
Bumps the patched acadrust to the commit that adds CANNOSCALE/
CANNOSCALEVALUE read/write.
Co-Authored-By: Claude Opus 4.8 <[email protected]>