Commit graph

2,471 commits

Author SHA1 Message Date
Hakan Seven
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 Seven
510bcf11e5 feat: redesign Annotate ribbon tab with proper groups and SVG icons
Added 15 SVG icons for all annotation tools (dimensions, leaders,
table, wipeout, revision cloud, tolerance, ddedit).

Annotate ribbon now has 6 groups matching standard CAD layout:
- Text: MText (large dropdown) + Text + Edit Text
- Dimensions: Linear (large dropdown with 6 types) + Continue + Baseline + Tolerance
- Leaders: Multileader (large dropdown) + Leader
- Tables: Table (large)
- Markup: Wipeout + Rev Cloud
- Annotation Scaling: Scale List, Add Scale, Scale Edit, Sync Scales

Added pub tool() + ICON to all annotate tools that were missing them
(aligned_dim, diameter_dim, dim_continue, dim_baseline, table_cmd,
tolerance_cmd, ddedit), and to home/draw/wipeout and revcloud.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 03:03:08 +03:00
Hakan Seven
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 Seven
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 Seven
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 Seven
ea5fd7c9d9 docs: update ROADMAP to v0.1.4 — mark all newly completed features
Closes:
  1.8  Physical printer (PRINT command)
  2.13 Region / Body / Wire / Silhouette entity render
  3.2  Region, Body, Wire/Silhouette, Ole2Frame entity support
  8.5  VPORTS preset viewport splitting (2H / 2V / 4 / SINGLE)
  11.6 VPLAYER per-viewport layer freeze/thaw (previously 🔧)
  14.10 STEP AP203 export (STEPOUT command)

Remaining open items: failsafe DWG parse, Boolean 3D ops, toolbar
customization — all blocked on external library support.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 22:25:03 +03:00
Hakan Seven
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 Seven
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 Seven
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 Seven
28f5c84b09 feat: Solid3D wire fallback render + Ole2Frame placeholder
- When SAT tessellation yields no mesh (binary SAB or unsupported ACIS
  geometry), render the pre-computed edge-wire polylines stored in
  Solid3D / Region / Body entities as a visible line fallback.
- Ole2Frame entities now render a bounding rectangle with diagonal X
  instead of an invisible stub — marks embedded OLE objects in the
  viewport.

Closes ROADMAP 2.13 (partial), 3.2 (Ole2Frame).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 22:16:58 +03:00
Hakan Seven
5cf7a19ca8 feat: Region and Body entity tessellation + render
Refactors solid3d_tess to share tessellate_sat() across Solid3D,
Region (2D planar ACIS body), and Body (3D ACIS body).
populate_meshes_from_document() and add_entity() now tessellate
all three entity types into GPU MeshModels when ACIS SAT data
is available.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 18:37:24 +03:00
Hakan Seven
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 Seven
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 Seven
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 Seven
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 Seven
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 Seven
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 Seven
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 Seven
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 Seven
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 Seven
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 Seven
42048362e2 fix: MSAA resolve no longer overwrites widget backgrounds
MSAA and depth textures are now sized to the shader widget's clip
bounds instead of the full surface. The resolve writes to a matching
clip-sized intermediate texture; a blit pass (blit.wgsl, viewport
trick) then copies the result to the exact clip region of the surface
target, leaving all other widgets untouched.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 12:20:47 +03:00
Hakan Seven
c12b30ad3d feat: 4× MSAA anti-aliasing for main drawing pipelines
All main render pipelines (wire, hatch, image, mesh) now use 4×
multisampling. Drawing passes render to a dedicated MSAA color buffer;
a final empty resolve pass transfers the anti-aliased result to the
iced surface target. The ViewCube renders post-resolve at 1× to avoid
pipeline incompatibility. Depth buffer also upgraded to 4× MSAA.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 00:52:38 +03:00
Hakan Seven
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 Seven
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 Seven
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 Seven
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 Seven
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 Seven
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 Seven
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 Seven
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 Seven
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 Seven
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 Seven
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 Seven
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 Seven
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 Seven
b3dcbe6eb9 chore: remove unused imports and variables (zero warnings)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 19:20:24 +03:00
Hakan Seven
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 Seven
5a682a365a feat: EXTEND and LENGTHEN now support LwPolyline
Both commands detect which terminal segment/vertex is nearest to the
pick point, compute the new endpoint along the segment direction, and
move only that terminal vertex — preserving all other vertices and bulge
values intact.  ROADMAP updated: EXTEND and LENGTHEN marked .

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 15:05:44 +03:00
Hakan Seven
083eb5cbb5 feat: Spline support for TRIM, EXTEND, OFFSET, BREAK, and LENGTHEN
Add shared spline_ops module with:
- spline_to_bspline / bspline_to_spline: acadrust ↔ truck BSplineCurve conversion
- spline_sample_xy: sample DXF-XY projection at N+1 points with parameters
- spline_nearest_t: nearest-parameter search via coarse+bisection
- spline_pts_wire: world-space wire points for WireModel preview

TRIM: Spline entities can now be used as cutting boundaries (Geo::Spline
sampled into polyline segments) and as entities being trimmed; uses
BSplineCurve::cut() to produce surviving pieces.

EXTEND: extend_spline() shoots a tangent ray from the nearest endpoint
and appends a control point at the first boundary hit.

OFFSET: offset_spline() offsets each sample point along the local
perpendicular normal and rebuilds a new spline from the offset control pts.

BREAK: break_spline() uses spline_nearest_t() + BSplineCurve::cut() to
split the spline at one or two click points.

LENGTHEN: lengthen_spline() uses numerical arc-length integration +
bisection to cut the spline at the parameter corresponding to the new
requested length.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 15:00:22 +03:00
Hakan Seven
71667cfafe cleanup 2026-04-07 14:43:25 +03:00
Hakan Seven
2c71ad5aeb feat: FILLET now supports LwPolyline segments and corner filleting
- Add LwPolyline helper functions: nearest-segment finder, segment-to-line
  extractor, corner vertex replacer, segment shortener, bulge calculator
- Add FilletEntity::LwPoly variant carrying poly, handle, and segment index
- compute_fillet_entities handles all new combinations: LwPoly×LwPoly
  (same entity corner fillet with bulge encoding), LwPoly×LwPoly (different
  entities), LwPoly×Line, LwPoly×Arc and their symmetric counterparts
- on_entity_pick detects LwPolyline picks and allows same-entity re-pick for
  adjacent-segment corner filleting
- on_hover_entity preview updated to show LwPolyline wire geometry
- entity_pts extended to cover LwPolyline for preview rendering
- Update prompts to mention LwPolyline as a supported entity type

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 14:42:49 +03:00
Hakan Seven
7a07ef8710 feat: EXPLODE now supports Dimension entities
Decomposes Dimension (Linear, Aligned, Radius, Diameter, Angular2Ln,
Angular3Pt, Ordinate) into constituent Lines (extension lines, dimension
line) plus a Text entity for the dimension label value.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 11:29:39 +03:00
Hakan Seven
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 Seven
1ef7bb5131 docs: update ROADMAP priorities — mark completed roadmap items
Mark as done: Named Views, DDEDIT, HATCHEDIT, MASSPROP, FILLET Arc support.
Update priority list to reflect remaining work.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 11:09:06 +03:00
Hakan Seven
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 Seven
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 Seven
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 Seven
cfb27d93c3 feat: FILLET now supports Line-Arc, Arc-Line, and Arc-Arc pairs
Extended FilletCommand and ChamferCommand to accept Lines and Arcs as
first/second entity. Added fillet_line_arc() and fillet_arc_arc()
geometry functions that find a tangent fillet circle between the two
entities, trim each to the tangent point, and insert the fillet arc.
r=0 case trims/extends to the nearest intersection without inserting an arc.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 10:58:46 +03:00
Hakan Seven
8e484d55cf docs: update ROADMAP to reflect completed session work
Mark as completed: ARRAY Path, BREAK/TRIM/EXTEND/OFFSET/LENGTHEN Ellipse
support, EXPLODE MLine, command history navigation (↑↓), RECTANG/POLYGON
command aliases. Update priority list accordingly.

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