100 Commits
Author SHA1 Message Date
Karim Jerbi c9e763006e fix(block-editor): clear authoring selection on blank pick 2026-10-18 19:57:22 +01:00
Karim Jerbi 9d2f4e592a fix(bpt): compare rotation rows across angle wrap 2026-10-18 19:56:01 +01:00
Karim Jerbi f74e1e8bd3 fix(block-editor): preserve legacy basepoint preview 2026-10-18 19:54:14 +01:00
Karim Jerbi 80366d411f feat(block-editor): use gray viewport with blue grid 2026-10-18 19:49:38 +01:00
Karim Jerbi 29d903d5d2 feat(ui): render BPT popup and authoring selection state 2026-10-18 19:07:20 +01:00
Karim Jerbi 286bdf6426 fix(block-editor): manage parameter and basepoint graph items 2026-10-18 19:07:10 +01:00
Karim Jerbi 4fdf357a7e fix(block-editor): edit and preview authoring parameters 2026-10-18 19:07:06 +01:00
Karim Jerbi 2797b5b9e1 feat(bpt): add reference-side row selection 2026-10-18 19:06:36 +01:00
Karim Jerbi d3e64800f6 feat(bpt): author native table grips and must-match 2026-10-18 19:05:17 +01:00
Karim Jerbi b97e67b533 refactor(ui): finish dialog form helper adoption 2026-10-18 12:56:33 +01:00
Karim Jerbi c80a1d1703 refactor(layer-state-manager): reuse shared form scaffolding 2026-10-18 12:47:02 +01:00
Karim Jerbi 5ac8cc7c03 refactor(ui): finish modal and property cleanup 2026-10-18 12:40:47 +01:00
Karim Jerbi cc947e77d3 refactor(modal): share duplicate row analysis 2026-10-18 12:27:43 +01:00
Karim Jerbi b89689cd03 refactor(statusbar): bundle view inputs 2026-10-18 12:25:29 +01:00
Karim Jerbi f0479a5fc6 perf(ribbon): build only selected density after measuring 2026-10-18 11:46:11 +01:00
Karim Jerbi 140303217f perf(ribbon): cache natural panel measurements 2026-10-18 11:25:39 +01:00
Karim Jerbi 42ba7f12a0 fix(form): unify style manager field styling 2026-10-18 11:03:54 +01:00
Karim Jerbi ddbfb8f72b fix(command_line): preserve argument casing 2026-10-18 10:54:24 +01:00
Karim Jerbi 43bdd18061 fix(style): block edits to xref-dependent dimstyles 2026-10-18 10:40:14 +01:00
Karim Jerbi c0baeda6a6 fix(pointstyle): stage dialog edits until accepted
Keep PDMODE and PDSIZE changes in the Point Style dialog until OK. Cancel and close discard staged edits. Invalid or non-finite size input reports an error and keeps the dialog open. Commit both values with one undo snapshot.

test: cancel discards staged glyph and size edits

test: invalid point size reports error and stays open

test: OK commits glyph and size in one undo step

test: relative point size keeps its sign
2026-10-18 09:21:43 +01:00
Karim Jerbi 248c9aec7b fix(plotstyle): validate and stage table edits
Validate plot-style color, lineweight, and screening fields atomically and report invalid input without changing the table. Keep successful Save and Save As edits as the close baseline; discard edits made after that baseline when the panel closes. CTB files are app-level state, so these changes do not dirty the drawing or create drawing undo entries.

test: invalid screening retains prior value and reports error

test: invalid color retains prior value and reports error

test: invalid lineweight retains prior value and reports error

test: closing panel discards unsaved edits

test: closing panel keeps values from saved baseline
2026-10-18 09:08:08 +01:00
Karim Jerbi 8db77b2398 fix(blocks): give the Polar Stretch palette row its own widget id
The Actions catalog's id fallback assigned authoring-tool-flip-action
to both Polar Stretch and Flip, so id lookups resolved the disabled
Polar Stretch row and Flip clicks never dispatched.
2026-10-18 08:52:48 +01:00
Karim Jerbi a1de7e4ecd feat(blocks): author Block Properties Table from the block editor
Add the BPROPERTIESTABLE command, the Block Authoring palette row and
the grid dialog. The row needs an open block edit session with a Linear
or Polar parameter column; OK parses cells to finite numbers, re-checks
the table against the session it was opened from, writes it in one undo
step, and no-op edits close without an undo.
2026-10-18 08:11:41 +01:00
Karim Jerbi 2b0c1a6b58 Cargo: codec 5d4f11a, kernel a60f18f, graph d9f2aee 2026-10-18 06:17:35 +01:00
Karim Jerbi 0d625bbe56 feat: pin Block Properties Table dependency chain
Synchronize codec, kernel and graph revisions so BPT data types remain unified across the workspace.
2026-10-18 00:51:04 +01:00
Karim Jerbi 5c931e926b feat: evaluate polar Lookup angle inputs
Map UpdatedAngle columns to polar parameter endpoints and verify row-driven geometry materialization.
2026-10-18 00:13:33 +01:00
Karim Jerbi 68f98ef720 feat: evaluate Lookup choices in Test Block
Verify disposable reference geometry follows selected table rows while the editor definition remains unchanged.
2026-10-18 00:05:43 +01:00
Karim Jerbi 09cb28e5b0 feat: validate reverse Lookup inputs
Restrict geometry updates to finite UpdatedDistance columns and reject unsupported mappings atomically.
2026-10-17 23:59:32 +01:00
Karim Jerbi 86c0e05878 feat: apply Lookup rows to block references
Expose writable Lookup outputs as reference choices and materialize each selected row's parameter geometry.
2026-10-17 23:57:58 +01:00
Karim Jerbi ba457d693c feat: verify Polar Stretch target editing
Exercise frame replacement and vertex rebinding across native DWG and DXF round trips.
2026-10-17 23:48:17 +01:00
Karim Jerbi 5a1d87c2af feat: evaluate Polar Stretch actions
Apply Polar Stretch bindings during Test Block and saved-reference evaluation, preserving source geometry.
2026-10-17 23:44:13 +01:00
Karim Jerbi bbf5afe53d feat:(BEDIT) : add Polar Stretch block action authoring and evaluation
Enable Polar Stretch actions through the authoring palette and BACTION command. Persist native action data, edit target selections and frames, and evaluate parameter-driven displacement on block references.
2026-10-17 23:24:20 +01:00
Karim Jerbi 26071f2021 feat(blocks): implement native Array action authoring and dynamic evaluation
Add the native Array action (\BARRAY\, \BACTION ARRAY\, and Authoring Palettes Actions tab \Array\) supporting Linear, Polar, and XY parameters.

Prompt for column offset (and row offset for XY), constructing native \DynamicBlockData::ArrayAction(BlockArrayAction)\ with class \AcDbBlockArrayAction\ and 4 native connections (\Base\, \End\, \UpdatedBase\, \UpdatedEnd\) bound to the parameter node ID.

Evaluate step displacement along 1D rays and 2D grids, tagging clones with deterministic element IDs to reconcile representations cleanly across incremental grip adjustments without mutating baseline geometry. Validate native DWG/DXF roundtrip, reference independence, COPY isolation, rejections, and dock palette tool state.
2026-10-17 12:49:51 +01:00
Karim Jerbi 5a6a7fab93 feat(blocks): synchronize definition geometry changes to evaluated references
Update evaluated references upon saving block definition edits while preserving each reference's independent parameter values, visibility states, and undo history.

Reconcile representation members by native element identity rather than positional index, preserving handles, extension dictionaries, reactors, nested attribute handles, and 3D polyline vertex handles. Prune erased targets from action dependencies, synchronize anonymous block base points, and prevent element ID collisions across undo/redo. Coalesce representation updates into editor undo deltas and composite structure snapshots for symmetric undo/redo.
2026-10-17 11:35:26 +01:00
Karim Jerbi ee846914dc feat(blocks): edit action selections and refresh evaluated references
Add BACTIONSET and the Block Editor Action Selection ribbon entry. Pick or preselect an action, replace/add/remove its drawing targets, or redefine a Stretch frame while preserving the native action and graph identity.

Retain existing Stretch vertex bindings during target edits and bind new targets against the stored frame. Normalize duplicate picks, allow removing invalid bindings, and rebuild them through a replacement frame. Rebuild evaluated references at their independent cached values so removed targets lose old effects, with local undo, discard and one drawing save delta.

Validate synthetic native DWG/DXF roundtrips, shared COPY representations, stale-result guards, reference geometry refresh, frame/cancel/history and the real ribbon flyout. 348 block tests pass (6 existing opt-in ignored), plus 42 dock and 27 viewport tests.
2026-10-17 11:35:26 +01:00
Karim Jerbi 7c91f5835e feat(blocks): edit action selections and refresh evaluated references
Add BACTIONSET and the Block Editor Action Selection ribbon entry. Pick or preselect an action, replace/add/remove its drawing targets, or redefine a Stretch frame while preserving the native action and graph identity.

Retain existing Stretch vertex bindings during target edits and bind new targets against the stored frame. Allow removing invalid bindings or rebuilding them through a replacement frame. Rebuild evaluated references at their independent cached values so removed targets lose old action effects, with local undo, discard and one drawing save delta.

Validate synthetic native DWG/DXF roundtrips, shared COPY representations, stale-result guards, reference geometry refresh, frame/cancel/history and the real ribbon flyout. 347 block tests pass (6 existing opt-in ignored), plus 42 dock and 27 viewport tests.
2026-10-17 10:22:14 +01:00
Karim Jerbi 042f26a4cc feat(blocks): wire Stretch actions and independent reference evaluation
Author a native Stretch action from a Linear, Polar or XY parameter, a two-corner stretch frame, an object selection and a marker. Preview and retain its frame in BEDIT, with selectable and movable action markers.

Freeze line and planar lightweight-polyline vertex bindings, preserve curved-segment height, move wholly selected objects, and evaluate independent saved INSERTs from their definition. Retain native DWG/DXF data, copied-reference isolation and undo/redo.

Validate with synthetic frame, topology, parameter, history, Test Block, drawing-reference, COPY and roundtrip regressions: 340 block tests pass (6 existing opt-in ignored), plus 41 dock and 27 viewport tests. Other entity types, Polar Stretch, custom multipliers and chaining remain unsupported.
2026-10-17 10:03:59 +01:00
Karim Jerbi 94940ad77c fix(blocks): show directional Flip grip arrows
Use the existing triangular grip marker in Test Block and saved drawing references. Point it across the reflection line, transform it with the INSERT, and reverse the arrow when the native Flip state changes.

Validate arrow shape and both directions through the existing mouse-click, undo/redo and reopen regression in both contexts.
2026-10-17 09:54:30 +01:00
Karim Jerbi 1ee432ac64 fix(blocks): reopen evaluated references in their authoring definition
Resolve BEDIT reference entry through the native dynamic-definition link instead of editing the anonymous geometry variant. Preserve static-block fallback and existing lock/xref checks.

Add synthetic regressions for evaluated-reference DWG reload and save/close/reedit, plus Rotation-only save/close/reopen followed by Flip placement. Validated with 334 block tests passing (6 existing opt-in tests ignored).
2026-10-17 09:33:29 +01:00
Karim Jerbi de7ed432fb feat(blocks): wire Rotate and Flip actions and saved reference grips
Author Rotate actions against Rotation parameters and Flip actions against Flip
parameters through the existing palette, BACTION selection flow and native
evaluation graph. Keep markers selectable and editable in BEDIT.

Rotation grips accept a new direction at the original radius. Flip grips toggle
immediately. Evaluate both from immutable definition geometry in Test Block and
independent drawing references, preserving per-INSERT angle/state caches across
DWG/DXF saves and COPY. Undo/redo includes the native state and representation.
Accept parameter names containing spaces at the action parameter prompt.

332 block regressions pass (6 existing opt-in checks ignored), including native
binding/marker roundtrips, composed rotation/flip, repeated reversible toggles,
COPY isolation, viewport mouse interactions, history and saved-reference reopen.
Custom base modes, constrained/chained evaluation and parameter-target actions
remain unsupported; Rotate currently binds Rotation parameters.
2026-10-17 09:15:37 +01:00
Karim Jerbi f67f2cf4f5 feat(blocks): persist independent Move and Scale reference grips
Selected drawing references now expose action parameter grips outside Test
Block. Point input evaluates immutable definition geometry into an independent
anonymous representation and stores per-INSERT values in native AppDataCache
XRecords, preserving definition graphs and sibling references.

Reuse visibility representation isolation, including shared COPY blocks, and
retain cache metadata. Record geometry, INSERT links, new block records and
parameter values in one undo step. Support transformed uniform references and
Point, Linear, Polar and XY endpoints for the existing Move/Scale actions.

Validate synthetic DWG/DXF persistence, re-edit/resave, COPY isolation,
XY/Polar cache layouts, metadata, cancellation, transformed grips and undo/redo.
327 block regressions pass (6 existing opt-in checks ignored).
2026-10-17 08:48:26 +01:00
Karim Jerbi ddf348af22 fix(text): stroke aliases txt/monotxt must ignore a same-named TTF
Face::resolve routes a name to a system TrueType face when installed_alias
reports that an alias names a real TTF face (the #1764 escape hatch, added so
an installed ISOCPEUR draws that face instead of its LFF stand-in).

That hatch also caught TXT/MONOTXT: on a machine with a font family matching
"txt" (e.g. a "Txt Regular"), the DXF stroke text font resolved to that
TrueType face instead of the embedded stroke substitute, contradicting the
documented contract that a missing .shx draws with the stroke substitute and
never with a similarly-named TrueType face.

TXT/MONOTXT are stroke aliases, so exclude them from the hatch. ISOCPEUR keeps
its #1764 behaviour.

Eight tests failed on such a machine and now pass: the four font-face/LFF
assertions (shx_name_stays_lff, lff_falls_back_to_ttf_for_uncovered_glyph,
big_font_pairing_routes_ideographs_and_leaves_latin_alone,
lff_tessellation_golden) and the four searchable-PDF assertions that route
through the same Face::resolve. Adds a regression test for the contract.
2026-10-17 05:56:14 +01:00
Karim Jerbi 8265444fd6 test(explode): cover ByBlock transparency and linetype on EXPLODE
The codec explode resolver started resolving those two in e6486c0.
These two tests cover the command path: the INSERT's ByBlock children
take the insert's transparency and linetype, and a child that already
names its own keeps them.
2026-10-16 22:18:57 +01:00
Karim Jerbi 677ff0e08c feat(block-editor): select and edit native parameter and action grips
Parameters and Move/Scale action markers were drawn as overlays with no selectable authoring objects. Pick their points, labels or graphics in BEDIT to display editable definition, endpoint, reference and label grips using the existing selection overlay and point-input commands. Show the selected object's coordinates in the Properties panel.

Write edits to the native parameter/grip/action records while preserving graph identities and target bindings. Maintain Rotation radii and oriented grip directions, synchronize visibility lookup data, and retain Basepoint attribute relocation with recorded entity history. Escape cancels edits or clears selection; editor undo/redo and save/discard preserve the native changes.

Validate with self-contained viewport-input and native DWG/DXF persistence regressions, all ten parameter types, action bindings, cancellation and Basepoint attribute undo. Checks: 3 focused, 323 block (6 existing opt-in ignored), 39 dock and 23 viewport tests passed; counts overlap.

Ordinary drawing-reference grips and per-instance saved action evaluation follow in the next milestone.
2026-10-16 17:44:09 +01:00
Karim Jerbi f69aefc3df feat(block-editor): author Move and Scale actions with Test Block evaluation
Add BACTION/BACTIONTOOL workflows for compatible parameter endpoints, selected geometry and native action markers. Persist Move/Scale records, target handles and evaluation graph bindings; reuse shared adjacency editing with Lookup and the existing palette, tooltips and selection UI.

Evaluate endpoint changes in the disposable Test Block document from immutable starting geometry, with geometry/grip undo, source isolation and transformed-reference support. Preserve visibility representations and their native Basepoint anchor. Refuse unsupported options, value constraints and shared test references.

This milestone supports default Move and uniform Scale on basic drawing entities. Other actions, custom options, live preview and ordinary drawing-reference evaluation remain pending.

Validation: self-contained synthetic DWG/DXF roundtrips, graph adjacency, command cancellation/history, Test Block isolation/undo, transformed references, visibility/Basepoint and real-view palette/viewport input checks; broader block and dock suites.

Keep action object selection active across mouse picks/removals and advance only on Enter. Cover empty selection, multiple targets, Shift removal, marker placement and Move/Scale Test Block evaluation using viewport mouse events. Verified 10 focused, 320 block and 39 dock tests (6 existing opt-in block checks ignored).
2026-10-16 17:05:18 +01:00
Karim Jerbi 10c5a9d382 feat(block-editor): author Lookup tables and wire Basepoint insertion
Add native Basepoint placement and relocation, shared insertion and Test Block anchor behavior, and attribute-safe coordinate reframing. Wire native Lookup parameter placement and the Property Lookup Table editor through the existing palettes and BLOOKUPTABLE.

Stage input columns, rows, reverse lookup and audit across multiple tables; apply all drafts atomically as one undo entry. Persist native Lookup actions and graph dependencies while preserving unrelated objects and IDs. New inputs cover Linear and Polar distances; reference Lookup evaluation and geometry actions remain separate work.

Pin codec c418d92, kernel 0f6f225 and graph dcb9eda for correct R2010 inline constraint-group decoding. The codec regression uses a checked-in synthetic DWG and reproducible generator, with normal self-contained loading and edited DWG/DXF tests. Keep dock control tests independent of scene adapter warning dialogs in software snapshots.

Validation covers native round trips, all 17 research fixtures, graph preservation, insertion and attributes, staged editing, undo/cancel, and real palette/dialog controls.
2026-10-16 15:29:08 +01:00
Karim Jerbi abb84751a2 chore: pin the plugin template to the host's codec 85bb5a2
codec 85bb5a2 fixes the BLOCKVISIBILITYPARAMETER DXF defect: AcDbEvalExpr
ends after 90/98/99 when the eval has no value instead of emitting a stray
70 -9999. Readers rejected that group 70 ('Unexpected DXF group code: 70')
and discarded every visibility-bearing drawing on open.
2026-10-16 00:22:43 +01:00
Karim Jerbi 1b5f7a19d8 Cargo: codec 85bb5a2, kernel c038693, graph d518926 2026-10-16 00:20:49 +01:00
Karim Jerbi b947f99a87 Cargo: codec 91b0cfd, kernel f45e472, graph 7e1d46e 2026-10-15 22:04:33 +01:00
Karim Jerbi 4143a01ff4 fix(commands): deny list during BEDIT
Refuse LAYOUT, VPORTS, MVIEW, WBLOCK, PURGE, RENAME, REFEDIT,
REFEDIT_BEGIN and PLOT from the command line while a block editor
session is open, matching the reference product's
"<CMD> command not allowed in block editor" behaviour (spec section 8,
based on the V7 hands-on check). XREF, NEW, OPEN and SAVEAS stay
allowed. The service-level RENAME guard stays as defense in depth.
2026-10-15 20:06:41 +01:00
Karim Jerbi 72c762e944 feat(block-editor): wire Rotation, Alignment and Flip parameter placement
Enable the existing palette rows and BPARAMETER choices. Rotation accepts a
center, picked or numeric radius, and picked or numeric default angle.
Alignment places a tangent direction from its base point. Flip places a
reflection line and state label, with native grip and state expressions.

Extend shared graph append/capacity checks for Flip's additional state node
while preserving existing subgraphs. Keep Polar/Rotation angle labels unique
in either placement order. Add editor graphics, extents and definition
reframing through the existing overlay/history/save paths.

This milestone implements native parameter placement and persistence.
Rotate/Flip action association, reference alignment/grip editing, parameter
property editing and parameter sets remain separate work.

Validation covers command and palette placement, cancellation, local/parent
undo, save/discard, native DWG/DXF objects, existing graph preservation and
the 17 research fixtures. Broader block/dock regressions and editor renders
are also checked.
2026-10-15 16:50:47 +01:00
Karim Jerbi 6dab5a7229 feat(block-editor): wire Linear, Polar and XY parameter placement
Enable the three existing palette rows and BPARAMETER choices. Pick a base,
endpoint and label location to create the appropriate native parameter, one
end grip and its location expressions in the shared authoring graph.

Render editor dimensions and labels, preserve them when reframing the block,
and include them in editor extents. Reuse local undo/redo, save/discard and
native DWG/DXF persistence. Reject incomplete or invalid placement without
changing document data or history.

This milestone implements parameter placement. Action association/evaluation,
parameter property editing, alternate grip counts and parameter sets remain
separate work.

Validation: focused placement and palette interaction checks; Block Editor and
dock regressions; native append and DWG/DXF round trips in all 17 research
fixtures, preserving existing graph data and source files; app-view renders.
2026-10-15 16:00:15 +01:00
Karim Jerbi cdfb4ed632 feat(block-editor): add native Point parameter placement
Enable Point in Authoring Palettes and BPARAMETER. Pick parameter and label
positions, then create the native Point, XY grip and position expressions in
one undo transaction. Draw editor-only markers and clear placement previews.

Share graph append construction with Visibility so both types coexist in
either order. Allocate node, expression and edge IDs independently; preserve
existing objects, nodes and relationships and reject malformed/opaque graphs.

Reframe parameter, label and grip with the edited definition. Include authoring
positions in editor framing while keeping reference geometry extents unchanged.
Retain save/discard and parent saved-edit undo. Action association/evaluation
and parameter property editing remain separate milestones.

Validation: 10 targeted, 286 block and 60 dock checks passed (overlapping
filters). Appending a Point to an existing native graph passed DWG/DXF
roundtrips in all 17 local fixtures; old objects and original checksums stayed
unchanged. Real-view palette interaction and rendered marker/label verified.
2026-10-15 15:33:27 +01:00
Karim Jerbi daa26007f9 feat(block-editor): add functional Visibility ribbon controls
Add the current-state selector, Visibility States dialog and mode/show/hide
controls to the contextual ribbon, using shared icons, tooltips, modal UI
and adaptive flyouts. Disable the controls until a Visibility parameter exists.

Stage state creation, rename, deletion, current-state changes and reordering
until OK. Support copied, show-all and hide-all new states in one undo step,
preserve native graph metadata, and restore current-state identity on undo/redo.

Implement nonsaved BVMODE and display-only reveal during BVSHOW selection.
Cancelling selection leaves saved visibility flags and history unchanged.
Keep the existing command-line state workflows available.

Validation: 6 targeted tests; 277 block, 31 app dock, 35 ribbon and 12 history
checks passed (overlapping filters). All 17 local DWG fixtures passed in-memory
DWG/DXF preservation checks with unchanged original checksums.
2026-10-15 15:08:21 +01:00
Karim Jerbi 308990e672 feat(block-editor): wire Visibility parameter placement
Milestone 1: enable Parameters > Visibility and add interactive
BPARAMETER VISIBILITY placement using the existing native visibility
parameter, grip and state engine. Bare BPARAMETER currently offers only
Visibility; other parameter, action and set entries remain unavailable.

Show the placed parameter in the editor and support cancel, local undo/
redo, save/discard and saved-edit undo. Bind placement to its document
and definition, reject duplicates and invalid points, and protect existing
authoring graphs from replacement.

Keep visibility parameters and their grips aligned with geometry when a
BEDIT UCS change reframes the definition, including parameter-only blocks.

Validation: 9 targeted tests, 272 block checks and 58 dock checks passed
(overlapping groups). All 17 local DWG fixtures passed in-memory DWG/DXF
placement roundtrips and graph-preservation checks; originals unchanged.
2026-10-15 15:08:21 +01:00
Karim Jerbi 16d3fd80f8 feat(block-editor): add authoring palette UI
Add a dockable Block Editor palette with selectable Parameters, Actions,
Parameter Sets and Constraints pages, reusing shared dock controls, icons
and ribbon-style hover bubbles.

Parameters, Actions, Parameter Sets and Block Properties Table are UI
catalogs only. Their entries remain disabled; this commit does not add
parameter placement, dynamic action behavior, parameter-set authoring or
block properties table functionality.

The Constraints page connects its geometric and dimensional entries to
existing ribbon commands. It reuses their implementations and adds no new
constraint behavior.

Keep the palette specific to BEDIT and retain its placement and selected
page across closing/reopening and Test Block. Opening, closing, switching
pages and clicking disabled entries preserve the document, undo history
and any running command.

Validation: 7 palette tests, 57 dock checks and 46 ribbon checks passed
(overlapping groups); rendered pages inspected and native debug build passed.
2026-10-15 12:45:16 +01:00
Karim Jerbi c48fac7ae9 feat(block-editor): edit definition properties in the Properties panel
Add the no-selection Block section with annotation, orientation, scaling, exploding, units, description and hyperlink controls. Integrate definition edits with editor history, save checkpoints and discard, and keep staged text tied to its definition.

Persist annotation and hyperlink metadata on the block record, migrate legacy marker values on edit, and honor orientation and hyperlink descriptions during block creation. Cover native DWG/DXF roundtrips and replacement after reopening.
2026-10-15 09:45:58 +01:00
Karim Jerbi f3973f08a7 fix(bedit): optimize block editor close and preserve warm render caches
Avoid rebuilding derived caches and clearing tessellation memos when closing the block editor on clean exit or discard. Scope entity delta computation to block record members instead of scanning and cloning the entire drawing, and add a fast path to the dirty check when no local commands were executed.
2026-10-15 09:41:01 +01:00
Karim Jerbi b221ce5e33 fix(bedit): refuse entities_create and redefine while a session is open 2026-10-15 06:10:51 +01:00
Karim Jerbi 6025d8be44 style: rustfmt the tree so the CI lint check passes 2026-10-15 04:10:06 +01:00
Karim Jerbi 1317a7b4fd fix(scene): keep xdict tree ownership with the root's own entity
The union precompute assigned each shared object to whichever copied
tree reached it last while descending only from the first reacher, so
a root ref'd by a later-sorted sibling lost its owner and the true
owner's clone pass skipped its own root. Seed every root's ownership
up front and make the walk first-wins with a claimed set, so ownership
stays consistent with the per-entity clone passes in any selection
order. Also wrap the new tests to rustfmt and drop product names from
added comments.
2026-10-15 03:44:00 +01:00
Karim Jerbi 71cc9a5a95 feat(scene): remap extension-dictionary cross-refs across copied entities
A multi-entity COPY cloned each entity's extension-dictionary tree
independently, so refs crossing between the copied trees (root to
sibling root, nested sibling objects, entity handles inside XRecords)
stayed pointed at the sources. Precompute the union closure of every
copied tree, preallocate authoritative clone handles, skip re-cloning
sibling-owned objects during each per-entity pass, and rewrite
entity-valued refs through the completed copy map afterwards. Trees
outside the copy set are deep-cloned inline, matching the reference
product, which clones an out-of-set dictionary target rather than
keeping it verbatim.
2026-10-15 03:44:00 +01:00
Karim Jerbi abad1b9045 feat(bedit): add Edit Block Definition dialog and new block authoring
Open the Edit Block Definition dialog when BEDIT is invoked without an active selection, listing candidate block definitions alphabetically while filtering layout records, anonymous blocks, and external references. Allow typing a new valid block name to start an empty block editor session that only commits to the drawing block table upon explicit save.
2026-10-14 14:46:48 +01:00
Karim Jerbi 9632979d09 feat(block-editor): add Test Block preview
Preview the current unsaved block in a disposable drawing with independent history. Keep normal Draw tools available, append Close Test Block, and return to the original editor without saving. Guard persistence paths and handle refresh and parent-close lifecycle by stable document identity.
2026-10-14 14:44:58 +01:00
Karim Jerbi 07fd162bd6 fix(history): preserve native networks during unrelated undo
Synchronize the native parametric graph only when replay changes constraints or named parameters. Geometry and visibility history preserve existing imported network identities and ownership. Add a regression for a rejected block copy followed by local undo and redo.
2026-10-14 09:11:55 +01:00
Karim Jerbi 78bdfa3c74 feat(block-editor): add Save Block As
Create a new named definition from current session edits, restore the source checkpoint, and continue editing the copy with fresh local history. Add the name dialog and Save dropdown, clone supported owned metadata onto independent handles, and refuse unsupported relationships atomically.
2026-10-14 09:11:55 +01:00
Karim Jerbi acb8c5ea54 scene: deep-clone extension-dictionary trees on in-drawing copy
A copied entity used to keep its source's extension-dictionary
handle, so the copy and source shared one tree and edits crossed
between them. In-drawing copy now clones the whole tree onto fresh
handles: dictionary entries, owners, reactors, nested xdictionary
links, and XRecord handle references that land inside the tree are
remapped; references leaving it stay pointed at the originals. A
dangling or missing root leaves the copy without an extension
dictionary rather than sharing. Annotative context trees and the
paste/export clone path are unchanged. Undo stays on the full
snapshot path when a tree is cloned.
2026-10-13 21:24:56 +01:00
Karim Jerbi f39fb31137 feat(block-editor): isolate session history and add save checkpoints 2026-10-13 15:35:24 +01:00
Karim Jerbi 535710e5d1 docs: add comprehensive per-release changelogs and master index
- Add root CHANGELOG.md as master index with executive release summaries
- Add dedicated changelogs for last 4 releases (v2026.38, v2026.39, v2026.40/40.1 unified, v2026.41) and unreleased
2026-10-13 15:35:24 +01:00
Karim Jerbi 8d287decd8 fix(explode): use codec block explosion for attributes and arrays
Delegate INSERT and MINSERT explosion to the document-aware codec implementation, removing duplicate attribute and base-point handling. Update workspace, kernel and graph pins together and cover rotated arrays with a nonzero base.
2026-10-13 11:10:11 +01:00
Karim Jerbi 9c08e8a3ed fix(blocks): prevent circular block nesting and cut render cycles
Introduce would_create_cycle in block_service to prevent recursive block definitions with case-insensitive matching across block records. Enforce cycle refusal at INSERT commit in BEDIT and during block redefinition (redefine_block_raw) with a shared error message. Ensure render-time recursion truncates safely with a one-time session warning on cyclic documents.
2026-10-13 11:10:11 +01:00
Karim Jerbi 59bb6faabd fix(blocks): enforce constant attributes in ATTEDIT and restore ATTDEFs on explode
Enforce constant attribute flag in ATTEDIT dialog by presenting constant attributes as disabled and ignoring modifications. When exploding an insert, restore block-definition attribute definitions as transformed ATTDEF entities while dropping instance attribute values.
2026-10-13 11:10:11 +01:00
Karim Jerbi 006be8909e feat(mcp): add side-effect-free request preflight
Add local ocs_read validate calls that check operation parameters, nested definitions, request envelopes and batch bindings without dispatching. Report document-dependent checks and unresolved result bindings explicitly. Share validation with execution and validate inline JSON Schema fragments before dispatch.

Validation: 66 targeted tests, desktop build, WebAssembly app/worker check, schema validation and MCP stdio smoke tests.
2026-10-13 09:33:49 +01:00
Karim Jerbi 97afb57333 feat(mcp): expose entity creation schemas on demand
Expose creation fields, constraints and examples for the 11 supported types without expanding startup tool schemas. Share the creation contract and constructor with execution to keep accepted inputs consistent.

Validation: MCP, contract/factory and entity creation regression tests.
2026-10-13 09:33:49 +01:00
Karim Jerbi b5b505ee9d fix(blocks): cross-document entity copies must not share extension dictionaries
add_entity_clone reset handle, owner and mode but kept the source extension dictionary handle, so a copy claimed a dictionary its document does not own. The clone now gets no extension dictionary, like baked and transformed-block children. Failing-first test included.
2026-10-13 07:05:54 +01:00
Karim Jerbi 8943a6fd39 feat(mcp): serve specialist guides on demand and shorten instructions 2026-10-12 15:20:28 +01:00
Karim Jerbi 50030be8c2 feat(mcp): bind batch parameters to earlier step results 2026-10-12 15:12:59 +01:00
Karim Jerbi 6ff8d8d705 fix(mcp): return resource links for reference-only captures 2026-10-12 15:08:15 +01:00
Karim Jerbi 7b68d274ad feat(mcp): add batch summaries with read-only detail retrieval
Add opt-in response_detail=summary with step and change counts, compact state, warnings, and actionable errors or prompts. Return an ocs_read batch_result request for full cached details without resuming mutations.

Keep compact/full behavior and idempotent batch retries intact. Preserve active-step context and report unavailable cached results explicitly. Document cache scope and retention; update schemas and digest.

Validation: 47 MCP unit tests, live stdio smoke test, rustfmt, and diff checks passed.
2026-10-12 09:39:54 +01:00
Karim Jerbi f4b33d5cde perf(mcp): deduplicate operation schemas with shared definitions
Share operation definitions between individual requests and batch steps, reducing the execute request schema by 39%. Place definitions at the tool input schema root so local references resolve correctly.

Update the schema digest and smoke assertions. Verified with 45 MCP tests, the live stdio smoke test, and 228 schema validation comparisons.
2026-10-12 09:05:38 +01:00
Karim Jerbi 2b50b6c858 fix(blocks): one block definition service for delete, rename and purge on every path
new src/scene/block_service.rs (references, delete, rename, purge candidates, name validation, one error type and message). The command-line RENAME, palette Remove, plugin API, control/MCP block_delete and PURGE all use it. Layout, xref, dynamic-block, anonymous and open-in-editor records are protected; PURGE removes an anonymous block only when nothing references it. PROTOCOL CHANGE: control/MCP block_delete refuses a referenced block unless force=true (erases referencing INSERTs in one undo step). New REST route DELETE /api/v1/blocks/{name}?force=true. MCP tool digest re-pinned. Undo labels are Delete block X, Rename block X to Y and Purge.
2026-10-12 07:25:11 +01:00
Karim Jerbi 5dfa41c032 fix(blocks): one base point convention for creation, redefine, insert, explode, XCLIP and REFEDIT
world = insert_point + Rot * Scale * (P - base_point). Attribute placement, EXPLODE, XCLIP storage, REFEDIT's working copy, the UCS reframe of attributes and the dynamic-block visibility grip ignored the base point and were offset by Rot*Scale*base. They now share insert_transform_with_base. Creation stores a ZERO base and redefine resets it; a no-op redefine moves nothing; the Block Definition dialog prefills the base from the definition. XCLIP filters stored by older builds keep their old displacement.
2026-10-12 04:35:19 +01:00
Karim Jerbi a456367b26 fix(save): baked dimension blocks and block clones must not share extension dictionaries
bake_dimension_blocks copied the dimension's whole EntityCommon, including its extension dictionary handle, into every baked child, so many entities claimed one dictionary and file validation reported an error per entity. Baked children now get no extension dictionary. The same defect is fixed in define_transformed_block and the cross-document paste clone. Each has a test.
2026-10-12 04:35:19 +01:00
Karim Jerbi 9cf9ff2c5c style: apply cargo fmt across workspace 2026-10-11 03:14:29 +01:00
Karim Jerbi 2824b2943f fix(styles): reload Table/MLine buffers on structural ops, validate cell text style
style_new/copy/delete funneled through a load_style_bufs no-op for Table/MLine, leaving stale editor buffers pointed at the fresh style; both arms now route to the existing loaders. Table cell text-style typos persisted as dangling names; unknown names are now rejected with command-line feedback, keeping the buffer text for correction. Silent numeric parse-drops deliberately untouched (codebase-wide keep-old-valid norm). Tests: table_new_reloads_cell_buffers plus table_cell_unknown_text_style_is_rejected incl. retention assert (RED each verified by temporary revert). Full suite: 2048 passed / 0 failed / 25 ignored, zero warnings.
2026-10-11 02:17:18 +01:00
Karim Jerbi 2c2bb9bba5 ci: run tests on Linux, Windows and macOS; add non-blocking lint job
Tests previously ran on Ubuntu only, so Windows- and macOS-specific breakage went unseen. Add a 3-OS test matrix and a separate lint job for rustfmt and clippy. Lint is continue-on-error because the tree is not yet fmt-clean or clippy-clean.

Also add BEDIT characterization tests that pin current session, undo and refusal behavior ahead of the editor refactor. Locked tests guard behavior that must survive; documenting tests record questionable behavior expected to change.
2026-10-11 02:17:18 +01:00
Karim Jerbi 8dca7fbaed refactor(ribbon): single dock predicate, drop dead layer_names mirror
The edge-stack closure duplicated dock_panel_visible arm-for-arm; it now delegates (tab is provably the active tab at that site). Ribbon.layer_names was written but never read outside one test; deleted, test reads via layer_infos. Faces and combo-refresh sub-items investigated and dropped (already unified upstream; no live stale path). Tests: dock visibility parity pins incl. Start-tab. Full suite: 2046 passed / 0 failed / 25 ignored, zero warnings.
2026-10-11 02:17:18 +01:00
Karim Jerbi 6fa11887c7 fix(xref): carry stable row identity in row messages
XrefManagerSelect/RightClick/RowOp/PathPick/FindReplace carried positional display indices that rescans could retarget. New XrefRowId{key,saved_path} (the identity refresh uses) in all 5 variants, resolved via row_index at dispatch with graceful no-op; panel selection stays index-based. display.index remains for view-time styling/lookup only. Tests: xref_rowop_unknown_id_is_noop (RED first); existing dialog/simulator/click tests migrated to ids. Full suite: 2044 passed / 0 failed / 25 ignored.
2026-10-11 02:17:18 +01:00
Karim Jerbi 7bbc5b0319 fix(ui): explain silent anno-scale toggles, theme xref empty state
AnnoObjectScaleToggle had three silent no-op paths (no target, locked layer, unknown scale); each now pushes command-line info mirroring the open-path guards. Xref empty-state hardcoded grey now uses muted_style. DD_BOUNDS eviction and attr-clamp changes investigated and deliberately dropped (no reachable defect in either). Tests: anno_scale_toggle_tests cover all three paths (RED: silence). Full suite: 2032 passed / 0 failed / 25 ignored, zero warnings.
2026-10-11 02:17:18 +01:00
Karim Jerbi 15cfabdb0f fix(layer-state): share linetype list via Arc instead of cloning per row
editor_layer_row and view_editor took Vec<String>, cloning N strings per row per frame (times two build-closure runs). Both take Arc<[String]> now; a plain borrow cannot cross the twice-run closure (E0373), hence the Arc. Cow empty-filter short-circuit for both search queries. Test: view_editor_accepts_shared_linetypes (RED first). Full suite: 2029 passed / 0 failed / 25 ignored, zero warnings.
2026-10-11 02:17:18 +01:00
Karim Jerbi 6c3cfb55b5 fix(layers): VP glyph and filter-aware shift ranges
VP-freeze columns used the global-freeze glyph; shift-ranges swept filtered-out rows into bulk ops. Glyph swapped to layer_vp_freeze (ribbon precedent); new visible_indices helper shared by the view loop and the shift arm. Test: shift_select_skips_filtered_out_rows (RED: hidden row in range). Full suite: 2028 passed / 0 failed / 25 ignored.
2026-10-10 20:41:28 +01:00
Karim Jerbi b66f890546 fix(statusbar): scale pill number, label and badge follow one viewport
The pill number used the first-content fallback while the label and sync badge used explicit-only resolution, showing e.g. a 1:50 number beside a 1:1 label with no badge. Label and badge now resolve through target_viewport_handle like the number; render-path handle fn, set-paths and Model branches untouched. Tests: scale_pill_sources_agree_without_targeted_viewport (RED: live probe Some(0.02)/1:1/None) plus Model-unchanged pin. Full suite: 2027 passed / 0 failed / 25 ignored.
2026-10-10 16:14:22 +01:00
Karim Jerbi d1da26feb6 fix(properties): scope asym-scale opt-out per tab
props_asym_scale was app-global keyed by raw handle values, but fresh documents restart numbering at seed 1, leaking one tab's unchecked Uniform box into another tab reusing the value. The set moves to DocumentTab; all uses tab-scoped. Also removes a dead destructure left in overlay.rs. Test: asym_scale_opt_out_does_not_leak_across_tabs with handle-reuse premise assert (RED first). Full suite: 2025 passed / 0 failed / 25 ignored, zero warnings.
2026-10-10 16:14:22 +01:00
Karim Jerbi 0c9cc839fe fix(overlay): guard draw_axes against behind-eye projection
draw_axes projected with raw project_point3, so a behind-camera axis endpoint wrapped to a finite mirrored point (proven: clip.w=-100 projected to screen centre). Extracted shared project_point with the eye-plane guard (grid_segments delegates verbatim) and axes now skip when an end is unprojectable plus clip_seg. Legacy canvas offset preserved pixel-identically; remaining raw project_point3 sites elsewhere are out of scope. Tests: project_point_rejects_behind_eye plus axes_segments geometry pins. Full suite: 2024 passed / 0 failed / 25 ignored.
2026-10-10 07:23:35 +01:00
Karim Jerbi 6d6a8b1439 fix(layers): key rename and picker state by name, not row
LayerPanel.editing and color_picker_row were positional indices, so a sort/sync/filter between start and commit retargeted renames and swatches. Both are Option<String> now; commit resolves fresh with graceful no-op on deleted layers. Existing rename tests migrated. Tests: layer_rename_commit_follows_name_across_resort (RED first) plus deleted/empty no-op and picker-resort pins. Full suite: 2019 passed / 0 failed / 25 ignored.
2026-10-09 21:22:47 +01:00
Karim Jerbi a3742e5668 fix(styles): follow text rename into dimstyle dimtxsty
rename_style_storage and rename_symbol rewrote entities and table rows but left dimtxsty stale, so the next Apply resolved a NULL handle. The follow now lives in both shared functions; the plugin workaround is removed as redundant. Tests: text_rename_follows_dimtxsty drives the manager path (RED first); pre-existing plugin rename test stays green via the shared path. Full suite: 2015 passed / 0 failed / 25 ignored.
2026-10-09 20:44:53 +01:00
Karim Jerbi 2187fe0d34 fix(tablestyle): ribbon pick writes header so inserts follow it
StyleKey::TableStyle only updated the ribbon mirror, so inserts kept using the header value and resync re-seeded from the mirror. The arm now writes current_table_style_name plus dirty when the style exists, and sync_ribbon_styles seeds from the document like Text/Dim. Tests: tablestyle_ribbon_pick_writes_header_and_dirties plus pick_flows_into_table_insert covering pick-to-dialog (both RED first). Full suite: 1996 passed / 0 failed / 25 ignored.
2026-10-09 19:50:17 +01:00
Karim Jerbi d3274543b7 fix(mcp): omit image payloads for unchanged diff captures
Return metadata only when a diff capture detects no visual change,
avoiding repeated image payloads across all delivery modes
2026-10-09 18:08:34 +01:00
Karim Jerbi 44ffb1ca5a fix(macos): forward launcher CLI arguments and preserve MCP stdio 2026-10-09 14:53:12 +01:00
Karim Jerbi d361d4f40e bench: add QuadTree spatial index construction benchmark 2026-10-09 14:20:13 +01:00