Commit Graph
119 Commits
Author SHA1 Message Date
Hakan SevenandClaude Sonnet 4.6 a6592cc9bc fix: ViewCube hover, glow, centroids, corner geometry and snap angles
- Hide OS crosshair and drawn crosshair when cursor is over ViewCube area
- Enhanced hover glow in WGSL shader (blue tint + brightness boost)
- Fixed region_centroids() Y-axis sign for all FRONT/BACK-related regions
- Swapped corner geometry assignments (TPF↔TBK, BTF↔BBK) to match
  intended FRONT/BACK semantics (sy=-1 = FRONT, sy=+1 = BACK)
- Corrected all snap_angles: yaw_pitch_to_quat(0,0) places eye at -Y
  (FRONT view), so FRONT=0 and BACK=PI — cascaded through edges/corners

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 19:11:19 +03:00
Hakan SevenandClaude Sonnet 4.6 578dd51af4 fix: set A4 landscape limits on initial Layout1 at document creation
acadrust initialises every Layout with 12×9 imperial defaults; override
all non-Model layouts to 297×210mm in new_drawing() so the first paper
tab opens at A4 size, consistent with layouts added later.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 14:23:38 +03:00
Hakan SevenandClaude Sonnet 4.6 f63858876d fix: align white paper fill with entity borders
- paper_entity_extents() computes the bounding box of actual DXF entities
  so the white fill always matches the drawn title-block / frame borders,
  regardless of whether Layout min/max_limits match entity positions
- Falls back to paper_limits() (→ A4 297×210) when layout has no entities
- Removed paper_boundary_wire: the white fill now acts as the visual paper
  edge so the near-white wire (invisible on white) was redundant
- LayoutCreate sets limits to A4 landscape immediately after add_layout()
  to override acadrust's imperial default (12×9)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 14:21:03 +03:00
Hakan SevenandClaude Sonnet 4.6 0a291c877b feat: A4 landscape default paper, white paper area on dark desk
- paper_limits() falls back to A4 landscape (297×210mm) even when no
  Layout object exists in the document
- paper_bg_color default changed to white [1,1,1,1] (paper surface color)
- PaperCanvas::draw() fills canvas with dark desk color first, then draws
  the paper area rectangle in paper_bg_color so the sheet is clearly
  visible against the desk background
- view.rs container background uses the fixed desk color instead of
  paper_bg_color so it no longer conflicts with the paper-surface color
- BACKGROUND RESET for paper space now resets to white instead of dark gray
- Removed unused PaperSheet variant, paper_sheet() constructor,
  build_paper_sheet_primitive() and associated match arms (dead code
  after 2D canvas replacement)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 14:05:07 +03:00
Hakan SevenandClaude Sonnet 4.6 fcc29de469 feat: inline MSPACE viewport overlay on 2D paper canvas
- viewport_screen_rect now mirrors PaperCanvas::draw()'s camera-based
  to_px transform instead of using a fixed paper-limits scale, so the
  3D overlay lands exactly over the drawn viewport border at any zoom/pan

- blue border frame (stack layer above the shader) makes the active
  viewport boundary always visible even when it fills the canvas

- space-mode pill in MSPACE now dispatches LayoutSwitch("Model") so
  clicking it jumps to full Model Space instead of just exiting to PSPACE

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 13:57:34 +03:00
Hakan SevenandClaude Sonnet 4.6 459b525ffe feat: replace paper-space shader with 2D Iced canvas widget
Paper space is now rendered as a 2D vector canvas (iced::widget::canvas)
instead of a 3D shader widget.  This allows direct interaction with
paper-space entities (title blocks, viewport borders, annotations)
without needing to enter MSPACE first.

Changes:
- src/scene/paper_canvas.rs: new PaperCanvas<'a> canvas::Program that
  renders paper wires (with linetype dashes), solid/gradient hatch fills,
  and wipeout backgrounds using the paper camera's orthographic transform.
- Scene: three new public helpers (paper_canvas_wires, paper_canvas_hatches,
  paper_canvas_wipeouts) feed the canvas with the same data the old shader
  used, including inactive viewport projections and interim/preview wires.
- view.rs: paper_canvas_view() now wraps PaperCanvas instead of
  shader(ViewportPane::paper_sheet(…)).  The PaperViewportPane 3D shader
  overlay for the active MSPACE viewport is unchanged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 09:48:53 +03:00
Hakan SevenandClaude Sonnet 4.6 c2df63c4cc feat: add clickable space-mode button to status bar
Replaces the static MODEL/LAYOUT pill with an interactive button that
shows and toggles the current editing context:

  Model tab     → "MODEL"  (non-clickable, informational)
  Layout PSPACE → "PAPER"  (click → MspaceCommand: enter MSPACE)
  Layout MSPACE → "MODEL"  (click → ExitViewport: return to PSPACE)

Highlights in blue when in MSPACE to signal active model editing.
Mirrors the AutoCAD status-bar convention for MODEL/PAPER switching.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 09:18:01 +03:00
Hakan SevenandClaude Sonnet 4.6 f176f7c80a fix: correct ViewCubeSnap and MSPACE orbit to write viewport entity
- Add orbit_active_viewport(), snap_active_viewport_to_angles(),
  active_view_rotation_mat(), active_viewport_yaw_pitch() helpers so
  navigation gestures modify the DXF viewport entity's view_direction
  instead of the paper-space camera.
- Fix "already there → flip opposite" check: the previous code used
  rot * Vec4::W (always (0,0,0,1) for a rotation matrix); now reads
  (yaw, pitch) directly from camera_for_viewport() via the new helper.
- MSPACE right-drag orbit early-returns after writing the viewport
  entity, preventing the paper-space camera from also being modified.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 08:53:30 +03:00
Hakan SevenandClaude Sonnet 4.6 97dbd80c93 feat: render active MSPACE viewport as a true 3D widget in paper space
When a paper-space viewport is activated (double-click / MSPACE command),
it is now rendered through its own dedicated PaperViewportPipeline rather
than the CPU-projection approach used for inactive viewports.

Architecture:
- PaperSheet widget (full-canvas): renders paper entities + CPU-projected
  content of all viewports *except* the active one.
- PaperViewportPane widget (Fixed w×h, positioned at viewport screen rect):
  renders the active viewport with a true 3D camera derived from the
  viewport's view_direction/view_target/view_height.

PaperViewportPipeline is a newtype of Pipeline.  Having a distinct type
gives it its own Iced storage entry (keyed by TypeId), preventing the
shared prepare() overwrite that broke the earlier per-viewport approach.

Changes:
- render.rs: PaperViewportPipeline, PaperViewportPrimitive newtypes;
  build_active_viewport_primitive(); build_paper_sheet_primitive() now
  excludes active_viewport from CPU projection.
- viewport_pane.rs: PaperViewportPane<'a> with shader::Program impl.
- mod.rs: viewport_content_wires() gains exclude_vp parameter;
  viewport_screen_rect() is no longer dead code.
- view.rs: paper_canvas_view() overlays PaperViewportPane when MSPACE
  is active.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 03:19:15 +03:00
Hakan SevenandClaude Sonnet 4.6 d1d4bb3d02 fix: restore paper-space viewport rendering as single full-canvas widget
Iced 0.14 batches all shader prepare() calls before any render() calls.
Multiple ViewportPane widgets sharing the same Pipeline type overwrite
each other's GPU buffers, causing the PaperSheet layer (full-canvas) to
render the last viewport's model content — appearing full-screen.

Fix: paper_canvas_view() now renders a single full-canvas PaperSheet
widget. build_paper_sheet_primitive() is updated to include model-space
content projected through each viewport's view matrix (via
viewport_content_wires()), restoring the original working behaviour.

ViewportPane::Paper mode and viewport_screen_rect() are kept with
#[allow(dead_code)] — a per-viewport wgpu sub-renderer that accumulates
data across frames could revive them in the future.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 03:02:01 +03:00
Hakan SevenandClaude Sonnet 4.6 da9fafc0f8 feat: introduce ViewportPane widget for unified model/paper rendering
- Remove Scene: shader::Program<Msg> impl; all GPU rendering now goes
  through ViewportPane which supports three modes:
    Model      — full model-space view (unchanged behaviour)
    PaperSheet — paper-space entities only, using the paper camera
    Paper      — model content through a specific viewport's own camera

- Add Scene helper methods (render.rs):
    build_primitive / build_paper_sheet_primitive / build_viewport_primitive
    update_viewcube_state / viewcube_mouse_interaction

- Add Scene helpers (mod.rs):
    paper_sheet_wires()        — paper entities without viewport projection
    camera_for_viewport()      — derive Camera from Viewport entity data
    model_wires_for_viewport() — model wires filtered by per-viewport frozen layers
    viewport_screen_rect()     — paper-space → pixel rect mapping

- Add paper_canvas_view() in view.rs:
    Stack of PaperSheet + one Paper widget per Viewport entity,
    positioned with Space offsets from viewport_screen_rect()

- Update VIEWPORT_WIDGET_PLAN.md: mark Steps 1–4 done, document remaining work

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 02:18:41 +03:00
Hakan SevenandClaude Sonnet 4.6 070ad1f9c5 feat: add Report/About/Changelog buttons to Support ribbon group
- REPORT opens GitHub new-issue page
- ABOUT opens a dialog window with version, OS and arch info + Copy Info button
- CHANGELOG opens GitHub releases page
- Fix Windows build: add windows-sys as target-specific dependency for PRINT command

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 22:22:33 +03:00
Hakan SevenandClaude Sonnet 4.6 ef988c20a3 feat: redesign Insert tab and fix all warnings
- Redesign Insert ribbon tab with 6 groups matching screenshot layout:
  Reference (Attach/Clip/Adjust large + Underlay Layers/Frames/Snap small),
  Point Cloud (Attach), Block (Multi-View Block/Insert large + Create/Edit/Base small),
  Attributes (Define/Edit large + Manage/Sync small),
  Import (Import/Land XML), Content (Content Browser/Design Center)
- Remove Primitives group and dead box_prim/clear/cylinder/sphere modules
- Fix all compiler warnings with #[allow(dead_code)] on unused-but-intentional items

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 12:44:31 +03:00
Hakan SevenandClaude Sonnet 4.6 bd68114bde feat: add style selector comboboxes to Annotate ribbon tab
New StyleComboGroup RibbonItem renders a dropdown combobox for selecting
text style, dimension style, multileader style, or table style. Ribbon
groups in the Annotate tab now match the reference layout: each group
has a large tool on the left and a style combobox with tool rows on the
right.

Each combobox shows the active style name, opens a scrollable item list
on click, and has an optional "Manage…" row that fires the style manager
command (STYLE / DIMSTYLE / MLEADERSTYLE / TABLESTYLE).

Style state is synced from the document on every layer refresh via
sync_ribbon_styles(). RibbonStyleChanged message propagates selections
back to the acadrust document header and the active_mleader_style field.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 03:38:23 +03:00
Hakan SevenandClaude Sonnet 4.6 08b9a21d31 feat: add missing Annotate tab commands and icons
New dimension commands: QDIM, DIMEDIT, DIMTEDIT, DIMBREAK, DIMSPACE,
DIMJOGLINE with full command workflows and SVG icons.

New multileader commands: MLEADERADD, MLEADERREMOVE, MLEADERALIGN,
MLEADERCOLLECT with entity injection pattern for in-place editing.

Updated annotate ribbon: all tools exposed across Text, Dimensions,
Leaders, Tables, Markup, and Annotation Scaling groups. Added STYLE,
FIND, DIMSTYLE shortcut buttons.

Added `inject_picked_entity` to the CadCommand trait for commands that
need a cloned copy of the picked entity to modify (DIMTEDIT, MLEADERADD,
MLEADERREMOVE). Sentinel-based dispatch in cmd_result.rs handles
DIMBREAK, DIMSPACE, DIMJOGLINE, MLEADERALIGN, and MLEADERCOLLECT.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 03:26:47 +03:00
Hakan SevenandClaude Sonnet 4.6 fe4f9ca844 refactor: move all dialog UIs to dedicated files under src/ui/
Each dialog window (Page Setup, DimStyle, TextStyle, TableStyle,
MLineStyle, PlotStyle, Layout Manager, Shortcuts) is now a proper
window-filling layout in its own src/ui/<dialog>.rs file.

Pattern: toolbar strip at top + vertical separator + scrollable
content filling the rest — no modal card, no backdrop, no stack[].
Matches the existing Layer Manager window pattern.

Removed ~1600 lines of old overlay functions from view.rs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 22:56:51 +03:00
Hakan SevenandClaude Sonnet 4.6 888095cc3e refactor: convert all overlay dialogs to separate OS windows
Every dialog panel that previously rendered as an in-viewport overlay is
now opened as its own OS window, matching the behaviour of the Layer
Properties Manager:

  • Page Setup           (520×460, non-resizable)
  • Text Style           (620×460)
  • Table Style          (620×420)
  • Multiline Style      (620×420)
  • Layout Manager       (640×320)
  • Plot Style Editor    (780×540)
  • Dimension Style Mgr  (720×560)
  • Keyboard Shortcuts   (720×520)

Changes:
  - mod.rs: replace *_open: bool fields with *_window: Option<window::Id>;
    add window IDs to OsWindowClosed tracker; add per-window title strings.
  - update.rs: Open handlers call window::open(); if already open, call
    window::gain_focus() instead of reopening. Close handlers call
    window::close(). OsWindowClosed clears all panel window IDs.
  - view.rs: each window_id is matched at the top of view() and returns
    the panel content directly. All overlay let-bindings and stack![]
    references removed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 22:36:28 +03:00
Hakan SevenandClaude Sonnet 4.6 781bd186ee chore: fix all compiler warnings
- cmd_result.rs: remove unused Point3 and Rad imports (SWEEP block)
- scene/mod.rs: remove unused Solid3D struct import
- commands.rs: drop unnecessary `mut` on new_entities (REFCLOSE block)
- refedit.rs: annotate insert_handle with #[allow(dead_code)]

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 22:28:31 +03:00
Hakan SevenandClaude Sonnet 4.6 b24e0c5da9 feat: STEPOUT command — export 3D meshes to STEP AP203
Adds STEPOUT / STPOUT / EXPORTSTEP command that exports all tessellated
Solid3D / Region / Body meshes to an ISO 10303-21 (STEP AP203) file.

Each triangle is encoded as a minimal ADVANCED_FACE with a PLANE surface
and CLOSED_SHELL topology — sufficient for import into all major CAD systems.
A file-save dialog picks the output path; the command line reports success or
errors. Requires at least one tessellated solid in the drawing.

Closes ROADMAP 14.10.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 22:23:58 +03:00
Hakan SevenandClaude Sonnet 4.6 f515b556c7 feat: PRINT command — send layout to system printer via lp/lpr
The PRINT command renders the current layout to a temporary PDF (reusing
the existing PDF export pipeline) and dispatches it to the OS default
printer:
  - Linux/macOS: `lp` (CUPS) with `lpr` as fallback.
  - Windows: ShellExecute "print" verb (compiled-in, unused on Linux).

PLOT and EXPORT still open the save-file dialog as before.
Status messages are shown in the command line during the async job.

Closes ROADMAP 1.8.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 22:21:50 +03:00
Hakan SevenandClaude Sonnet 4.6 ff39759d02 feat: VPORTS preset viewport configurations (2H / 2V / 4 / SINGLE)
VPORTS now accepts a layout subcommand in paper-space:
  VPORTS 2H     — two viewports side by side (horizontal split)
  VPORTS 2V     — two viewports stacked (vertical split)
  VPORTS 4      — 2×2 grid of four equal viewports
  VPORTS SINGLE — one full-page viewport

Paper dimensions are read from PlotSettings (fallback A4 landscape).
Existing user viewports are replaced and each new viewport is
auto-fitted to show model-space content.
Bare VPORTS still lists existing viewports.

Closes ROADMAP 8.5.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 22:19:08 +03:00
Hakan SevenandClaude Sonnet 4.6 67b5f5e3d5 feat: Keyboard Shortcuts panel + SHORTCUTS command
Opens a reference panel listing all built-in keyboard shortcuts
(F3-F12, Ctrl+N/O/S/Z/C/X/V, etc.) and any user-defined overrides.

SHORTCUTS LIST         — open the panel
SHORTCUTS SET <k> <c>  — add/update a custom shortcut label
SHORTCUTS CLEAR <k>    — remove a custom entry

Custom shortcuts are stored in app state (runtime only) and shown
in the panel alongside the hardcoded bindings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 18:34:10 +03:00
Hakan SevenandClaude Sonnet 4.6 e36fafe6df feat: COLORSCHEME command — runtime UI theme/color-scheme switching
Adds active_theme: Theme field to app state and wires the daemon's
.theme() callback to use it dynamically. COLORSCHEME <name> switches
among all 19 built-in iced themes (Dark, Light, Dracula, Nord, Tokyo
Night, Gruvbox, Kanagawa, Moonfly, Nightfly, etc.).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 18:31:09 +03:00
Hakan SevenandClaude Sonnet 4.6 85f9b930a2 feat: Layout Manager GUI (LAYOUTMANAGER / LAYOUTPANEL command)
Panel overlay showing all layouts with their active status.
Supports: select, rename, new, delete, reorder (◀▶), set current.
Also adds Scene::swap_layout_order() for tab-order resequencing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 18:28:30 +03:00
Hakan SevenandClaude Sonnet 4.6 b8d15e5155 feat: Plot Style Table Editor GUI (PLOTSTYLEPANEL / STYLESMANAGER)
Opens a panel overlay showing all 255 ACI entries with their current
overrides (color, lineweight, screening). Allows editing entries
interactively, creating a new identity table when none is loaded,
and saving the modified table back to a CTB/STB file.

Commands: PLOTSTYLEPANEL, PLOTSTYLEEDITOR, STYLESMANAGER

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 18:19:48 +03:00
Hakan SevenandClaude Sonnet 4.6 1fceec92ea feat: MLEADERSTYLE command — create and manage MultiLeader styles
Stores MultiLeaderStyle objects in document.objects. Supports:
  MLEADERSTYLE LIST — list all styles
  MLEADERSTYLE NEW <name> — create a new style
  MLEADERSTYLE SET <name> <prop> <val> — edit text_height,
    arrowhead_size, landing_distance, landing_gap
  MLEADERSTYLE CURRENT [<name>] — get/set active style

Active style name tracked per-tab in active_mleader_style.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 18:13:21 +03:00
Hakan SevenandClaude Sonnet 4.6 1d349c53af feat: LOFT command — ruled-surface loft through multiple cross-sections
Picks 2+ profile entities (closed or open wires), builds ruled shells
between consecutive pairs via builder::try_wire_homotopy, caps closed
ends with planar faces, and tessellates the result into a Solid3D mesh.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 18:08:53 +03:00
Hakan SevenandClaude Sonnet 4.6 063a1d5be1 feat: SWEEP command — sweep profile along Line/Polyline path
Picks a profile (closed or open 2D entity) then a path entity
(Line or LwPolyline). For Line paths uses tsweep along the line
vector; for Polyline paths uses start→end as translation direction.
Closed profiles produce a capped Solid; open profiles a Shell.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 18:07:00 +03:00
Hakan SevenandClaude Sonnet 4.6 6fa3157e72 feat: OBJ mesh import (IMPORTOBJ / OBJIMPORT command)
Parses Wavefront OBJ files (v/vn/f, fan-triangulation, face normals
fallback) and inserts the result as a Solid3D placeholder + MeshModel
visible in the 3D viewport.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 12:59:27 +03:00
Hakan SevenandClaude Sonnet 4.6 549ae38459 feat: BOX, SPHERE, CYLINDER primitives + EXTRUDE / REVOLVE commands
BOX, SPHERE, and CYLINDER build truck topology solids and tessellate
them into MeshModels stored alongside a Solid3D placeholder entity so
the GPU mesh pipeline renders them immediately.

EXTRUDE picks any closed 2D profile (Circle, LwPolyline, etc.),
attaches a planar face via try_attach_plane, and translational-sweeps
it (tsweep Face → Solid) along Z by the given height.

REVOLVE picks a profile, two axis points, and an angle (default 360°),
then rotational-sweeps the wire (rsweep) around the axis.

Three new CmdResult variants drive the operations:
  CommitSolid3D, ExtrudeEntity, RevolveEntity.

Scene::layer_color() added to retrieve the active layer's RGBA color.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 12:55:28 +03:00
Hakan SevenandClaude Sonnet 4.6 a773a1a1f1 feat: REFEDIT / REFCLOSE — in-place block reference editing
REFEDIT picks an INSERT, extracts the block entities into model space
with the INSERT transform applied (translate + rotate + uniform scale),
and enters an editing session.  Any normal modify command works on the
temporary entities.

REFCLOSE SAVE applies the inverse transform, replaces the block
definition, and rebuilds all derived caches (hatch/image/mesh), so
every INSERT of that block reflects the edits immediately.
REFCLOSE DISCARD removes the temp entities without changing the block.

Non-uniform-scale inserts are rejected with an error message.
RefEditSession is stored on DocumentTab; undo snapshots bracket the
begin and close operations.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 12:40:19 +03:00
Hakan SevenandClaude Sonnet 4.6 25b91bc09e feat: STL export (STLOUT / EXPORTSTL command)
Exports all tessellated 3D mesh models in the current drawing to a
binary STL file via a save-file dialog. Normals are taken from the
MeshModel where available, otherwise computed from triangle vertices.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 00:46:05 +03:00
Hakan SevenandClaude Sonnet 4.6 9ede70ef1c feat: 3D ARRAY (ARRAY3D / 3DARRAY command)
Three-dimensional rectangular array: prompts for rows, columns, levels
and their respective spacings, then generates copies translated along
X (columns), Z (rows in drawing plane), and Y (levels / height).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 00:43:21 +03:00
Hakan SevenandClaude Sonnet 4.6 3cdd86a674 feat: right-click context menu + CONSTRUCTIONLINE alias
Viewport right-click now shows a proper widget-based context menu:
- When a command is active: Cancel / Enter
- Otherwise: Repeat last commands, Delete/Move/Copy (if selected),
  Select All, Zoom Extents

CONSTRUCTIONLINE added as an alias for XLINE (XL).
Canvas-drawn placeholder removed; context menu closes on Escape,
click-outside, or when any action is taken.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 00:41:01 +03:00
Hakan SevenandClaude Sonnet 4.6 a20558a024 feat: ATTREQ — attribute prompting during INSERT
When inserting a block that contains AttributeDefinition entities,
the INSERT command now enters an attribute-filling phase: each attdef
is prompted tag-by-tag (showing its prompt text and default value).
Pressing Enter accepts the default. The completed AttributeEntity list
is embedded in the Insert before committing.

Blocks without attdefs continue to insert immediately as before.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 00:33:56 +03:00
Hakan SevenandClaude Sonnet 4.6 f73d38f0a2 feat: Object Snap Tracking (OTRACK / F11)
- snap/mod.rs: Snapper gains otrack_enabled, tracking_points, dwell state;
  update_otrack_dwell() acquires a snap point after DWELL_THRESHOLD=4
  consecutive moves near the same position; otrack_snap() returns an
  H/V alignment snap position; clear_tracking() resets state on command end
- overlay.rs: selection_overlay accepts ost_points + cursor_screen;
  draws light-blue dashed H/V lines from acquired points + small cross marker
- statusbar.rs: OTRACK pill (F11) added next to DYN
- view.rs: projects tracking_points to screen, passes to selection_overlay
- update.rs: calls update_otrack_dwell + otrack_snap in ViewportMove;
  overrides effective point with OST alignment when no normal snap is active
- ROADMAP.md: Object Snap Tracking marked ✅

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 00:26:54 +03:00
Hakan SevenandClaude Sonnet 4.6 d2a58bdd08 feat: DIMORDINATE + mark Named UCS saving and DIMORDINATE complete
- ordinate_dim.rs: OrdinateDimCommand picks feature point then leader
  endpoint; auto-detects X vs Y ordinate from movement direction
- Ordinate dim added to the Dimensions dropdown in the Annotate ribbon
- ROADMAP.md: DIMORDINATE ✅, Named UCS (already implemented) ✅

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 00:21:35 +03:00
Hakan SevenandClaude Sonnet 4.6 6f741a92e0 feat: ATTEDIT — edit block attribute values interactively
- attedit.rs: AtteditCommand picks an INSERT entity then iterates through
  each attribute tag prompting for a new value (Enter keeps existing)
- attedit_pending_handle() / attedit_set_attrs() trait methods inject
  attribute data into the command after entity-pick (avoids document access
  in the command itself)
- cmd_result.rs: NeedPoint handler injects attr data; ReplaceEntity detects
  the __ATTEDIT__ sentinel and calls apply_attedit() on the document
- apply_attedit() encodes tag/value pairs as __ATTEDIT__tag\x01val\x02...
- ROADMAP.md: ATTEDIT marked ✅

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 00:19:43 +03:00
Hakan SevenandClaude Sonnet 4.6 0fc3766da7 feat: SPLINEDIT — close, open, reverse spline control-point editing
- splinedit.rs: SplineditCommand picks a spline (entity-pick phase) then
  accepts CLOSE/OPEN/REVERSE/EXIT sub-commands via text input
- apply_spline_op() mutates the spline in the document directly, with knot
  vector regeneration via generate_clamped_knots()
- Sentinel XLine trick: ReplaceEntity with a magic __SPLINEDIT_* layer name
  is intercepted in cmd_result.rs before erasing the original entity
- Control-point dragging already works via the existing grip editing system
- ROADMAP.md: SPLINEDIT marked ✅

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 00:16:44 +03:00
Hakan SevenandClaude Sonnet 4.6 51e6c4b359 feat: Dynamic Input overlay (DYNMODE / F12)
- overlay.rs: dynamic_input_overlay() canvas widget draws a semi-transparent
  coordinate tooltip near the cursor; shows X/Y in absolute mode or
  dist/angle relative to last_point when a command base point exists
- statusbar: DYN toggle pill with F12 tooltip (calls ToggleDynInput)
- app/mod.rs: dyn_input: bool field (default true), ToggleDynInput message
- view.rs: builds DYN label and pushes overlay into viewport_stack when
  dyn_input=true and a command is active
- document.rs: last_cursor_screen: iced::Point — updated on every ViewportMove
- ROADMAP.md: Dynamic Input overlay marked ✅

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 00:12:09 +03:00
Hakan SevenandClaude Sonnet 4.6 f80d694818 feat: DATAEXTRACTION — export entity data to CSV
- DATAEXTRACTION / EATTEXT / ATTEXT commands trigger an async save dialog
- Extracts all model-space entities with: Type, Handle, Layer, Color,
  Linetype, and a geometry summary per entity type (coords, radius, etc.)
- DataExtractionSave / DataExtractionSaveResult message pair drives
  the rfd save-file dialog asynchronously
- CSV fields are properly escaped (commas, quotes, newlines)
- ROADMAP.md: 12 DATAEXTRACTION marked ✅

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 00:07:58 +03:00
Hakan SevenandClaude Sonnet 4.6 b15be3af3d feat: WBLOCK — write block or selected entities to external file
- src/modules/insert/wblock.rs: extract_block_to_doc() copies a named
  block's entities into a fresh CadDocument; extract_entities_to_doc()
  does the same for a selection set; layer definitions are carried over
- WBLOCK <name> writes the named block; WBLOCK * writes selected entities
- WblockSave / WblockSaveResult messages drive the async save-dialog flow
- ROADMAP.md: 1.10 WBLOCK marked ✅

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 00:05:04 +03:00
Hakan SevenandClaude Sonnet 4.6 64837e9aed feat: XREF management — auto-resolve, XATTACH, XREF, XRELOAD
- src/io/xref.rs: resolve_xrefs() scans block_records for is_xref flags,
  resolves paths relative to the opened file's directory, loads the
  referenced DWG/DXF and merges model-space entities into the xref block
- src/modules/insert/xattach.rs: XATTACH command with file-picker flow
  (XAttachPick/XAttachPickResult messages), prepare_xref_block() creates
  BlockRecord + Block entities and immediately resolves content
- XREF command: lists all external references in the drawing
- XRELOAD command: re-resolves all xref paths and rebuilds scene caches
- Auto-resolve on FileOpened: reports Loaded/NotFound per xref block
- CadCommand trait: added optional xattach_path() method
- ROADMAP.md: 1.9 XREF management marked ✅

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 00:02:38 +03:00
Hakan SevenandClaude Sonnet 4.6 4c1c13cab6 feat: Grid snap adaptive spacing + Polar tracking improvements
Grid snap (F9):
  • snap spacing now tracks the visible grid zoom level — computed via
    compute_grid_step() (same adaptive pow-of-5 logic as draw_grid),
    updated on every ViewportMove so zooming in/out keeps snap aligned
    with the grid lines on screen

Polar tracking (F10):
  • configurable angle increment stored in polar_increment_deg (default 45°)
  • right-click the POLAR pill to cycle through 15 → 30 → 45 → 90°
  • pill label shows current angle ("POLAR 45°")
  • visual guide line: while drawing with polar on, a dashed cyan line is
    drawn from last_point along the snapped direction across the viewport
  • SetPolarAngle message + handler; all polar_constrain() calls use the
    stored increment instead of the hardcoded 45°

ROADMAP updated: Grid snap and Polar tracking marked ✅.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 19:30:25 +03:00
Hakan SevenandClaude Sonnet 4.6 a99115bda5 feat: Solid3D (3DSOLID) ACIS tessellation
Parse SAT geometry directly into GPU MeshModel without going through
the truck B-rep pipeline:
  • plane-surface faces  → fan-triangulate the coedge-loop polygon
  • cone-surface faces   → parametric grid (handles cylinders and cones)
  • sphere-surface faces → UV sphere grid (GRID_U × GRID_V)
  • torus-surface faces  → UV torus grid

Scene integration:
  • add_entity(): tessellates Solid3D on insert, stores in scene.meshes
  • erase_entities(): removes mesh from scene.meshes on delete
  • populate_meshes_from_document(): rebuilds all meshes on file load
    and undo/redo (called alongside populate_hatches/images)

ROADMAP updated: Solid3D tessellation marked ✅ in sections 2.12, 14.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 19:11:24 +03:00
Hakan SevenandClaude Sonnet 4.6 d3d4ec4a08 feat: STRETCH with proper crossing-window vertex selection
Replaced the simplified MOVE-based STRETCH with a real crossing-window
implementation. Workflow: pick two crossing-window corners, then base+target
points. Only vertices/endpoints inside the window are translated:
- Line: moves start/end independently
- LwPolyline/Polyline: moves individual vertices inside window
- Arc/Circle/Ellipse: moves whole entity if center is inside
- Insert/Text/MText: moves if insertion point is inside

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 11:25:39 +03:00
Hakan SevenandClaude Sonnet 4.6 f6d716dfc5 feat: HATCHEDIT command to edit existing hatch pattern, scale, and angle
Add HATCHEDIT (HE alias) command. Works on pre-selected hatch or via
entity pick. Accepts text options: P <pattern>, S <scale>, A <angle>.
Enter applies changes; rebuilds hatch entity and GPU model via add_hatch.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 11:08:51 +03:00
Hakan SevenandClaude Sonnet 4.6 8078c4c9da feat: DDEDIT command and double-click text editing
Add DDEDIT (ED alias) command that edits Text/MText/Attribute entities
in-place via the command line. Double-clicking a text entity in model space
now auto-launches DDEDIT for that entity. Supports Text, MText,
AttributeDefinition, and AttributeEntity types.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 11:05:24 +03:00
Hakan SevenandClaude Sonnet 4.6 25ec6f66e5 feat: add MASSPROP command — area, perimeter, centroid of selected entities
Computes mass properties for selected entities and prints results to the
command line. Supports: Circle (area+perimeter), Arc (sector area+arc length),
Line (length), LwPolyline (shoelace area+perimeter+centroid), Ellipse
(numerical 256-pt integration for area and arc length).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 11:00:18 +03:00
Hakan SevenandClaude Sonnet 4.6 80ca095121 feat: command history navigation with up/down arrow keys
CommandLine now records every submitted command in a recall list (up to
50 entries).  Pressing ↑ in the command input walks back through the
list, ↓ moves forward, and returning to the newest position restores
the draft text the user had typed before navigating.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 00:04:12 +03:00