Commit graph

211 commits

Author SHA1 Message Date
Hakan Seven
320312e81a fix: replace degenerate same-vertex edges with Point in lwpolyline and spline
Empty LwPolyline and single-control-point Spline fallbacks were calling
builder::line(&v, &v) with the same Rc vertex, triggering the
truck-topology panic "Two same vertices cannot construct an edge."

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 20:30:26 +03:00
Hakan Seven
6b4bc1b832 fix: paper background no longer resizes when a viewport is added
White paper fill was calculated from entity bounding boxes (paper_entity_extents),
so adding a viewport caused the paper to visually shrink to the viewport's bounds.
Now paper_limits() (layout min/max limits) is used directly, and the unused
paper_entity_extents() function is removed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 12:02:33 +03:00
Hakan Seven
465dcc1600 ci: include version, OS and arch in release asset filenames
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 10:13:11 +03:00
Hakan Seven
4506cff931 ci: remove one-time upload_tag workaround from release workflow
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 10:11:28 +03:00
Hakan Seven
135fef54c5 ci: support upload_tag input on workflow_dispatch
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 02:12:22 +03:00
Hakan Seven
0a88d063f9 ci: add AppImage build job to release workflow
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 01:57:40 +03:00
Hakan Seven
87eabc9372 chore: bump acadrust 0.3.3 → 0.3.4, H7CAD 0.1.5 → 0.1.6
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 01:51:15 +03:00
Hakan Seven
3ec7bf7065 refactor: deduplicate entity type name mapping
Make scene::properties::entity_type_name the single source of truth.
entity_type_label in helpers.rs now delegates to it instead of
maintaining a separate match list.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 01:44:33 +03:00
Hakan Seven
2ee1c8e196 fix: entity_type_label/key in helpers.rs cover all EntityType variants
The Properties panel header was still showing "Entity" for unrecognized
types because helpers.rs had its own incomplete match. Both functions now
enumerate every acadrust EntityType variant explicitly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 01:43:13 +03:00
Hakan Seven
a5057e26b1 fix: show specific entity type name in Properties panel for all entity types
Expanded entity_type_name() to cover all EntityType variants from acadrust
instead of falling back to the generic "Entity" label.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 01:40:33 +03:00
Hakan Seven
5f3182fa9a fix: NAVVCUBE and UCSICON commands now properly toggle visibility
NAVVCUBE: propagate show_viewcube flag through ViewportPane and the wgpu
Primitive so the ViewCube pipeline skips upload/render when hidden.
UCSICON: bare command (no subcommand) now toggles current state instead
of printing usage info.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 01:31:52 +03:00
Hakan Seven
1ec53a4730 feat: view tab widget toggle commands and unified SVG icon color scheme
Integrate NAVVCUBE, NAVBAR, PROPERTIES, FILETAB, LAYOUTTAB, TOOLPALETTES
and SHEETSET commands to toggle UI widgets at runtime. Add 15 new SVG icons
for view module tools previously using glyph fallbacks. Restyle all SVG
icons to use the established two-color scheme: #e0e0e0 for passive geometry,
#4cc9f0 for active/accent elements.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 01:23:06 +03:00
Hakan Seven
6a0125e4d6 feat: 3D UCS icon with foreshortening, depth ordering and axis labels
Replace the flat fixed-length axis arrows with a proper 3D tripod:
- Axis lengths are proportional (longest fills UCS_ICON_LEN, shorter
  axes stay foreshortened) giving real depth perception as the camera
  rotates
- Draw order computed from NDC Z so back axes render behind front ones
- X / Y / Z labels rendered beyond each arrowhead tip
- All axes drawn at full opacity with solid filled arrowheads

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 21:54:31 +03:00
Hakan Seven
00da80f6e5 fix: align ViewCube hit-test with widget bounds instead of full window
prepare() was passing viewport.logical_size() (full window) to
viewcube.upload(), while hit_test/hover_id used the shader widget's
bounds. With the properties panel present the widget is narrower than
the full window, so the visual cube was scaled smaller but the click
area stayed full-size — causing the mismatch that grew toward the
bottom-left corner.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 21:39:43 +03:00
Hakan Seven
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 Seven
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 Seven
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 Seven
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 Seven
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 Seven
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 Seven
1c0520e4e4 fix: correct CPU projection axes to match GPU look_at_rh convention
viewport_content_wires() computed view_right via world_z × view_direction
(cross-product). This gives the OPPOSITE sign to the right vector that
look_at_rh produces for views with a Y component (FRONT/BACK views):

  GPU look_at_rh:  screen_right = f × up = (−vd) × (rot*Y) = rot*X
  Old CPU formula: screen_right = Z × vd  ← opposite sign for FRONT/BACK

The mismatch caused the paper-space projection to appear mirror-flipped
after panning/rotating in MSPACE.

Fix: use camera_for_viewport() to obtain the exact same rotation
quaternion the GPU uses, then derive both axes from it:
  view_right = rotation * X
  view_up    = rotation * Y

Also replaces the perspective depth dot-product (mp · vd) with
mp · (rotation*Z) so the depth direction is consistent too.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 09:28:54 +03:00
Hakan Seven
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 Seven
2c5405aa49 fix: correct MSPACE orbit and pan direction
orbit_active_viewport was writing cam.rotation*Z directly to
view_direction, but yaw_pitch_to_quat(y,p)*Z has its Y component
negated relative to the snap convention: (cos(p)*sin(y), -cos(p)*cos(y),
sin(p)) vs (cos(p)*sin(y), +cos(p)*cos(y), sin(p)).  This caused
camera_for_viewport to reconstruct yaw = π - original_yaw, making every
orbit appear reversed.  Fix: negate Y when writing view_direction back.

pan_active_viewport was using the paper-space camera to convert screen
pixels to model-space delta.  This gives wrong pan axes for tilted
MSPACE views (e.g. front/side views where cam_up is Z, not Y).  Fix:
use camera_for_viewport so the pan axes match the 3-D view orientation,
and update all three view_target components (X/Y/Z) for tilted views.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 09:10:55 +03:00
Hakan Seven
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 Seven
7e0e892bcc chore: remove VIEWPORT_WIDGET_PLAN.md as refactoring steps are complete 2026-04-23 03:25:15 +03:00
Hakan Seven
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 Seven
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 Seven
592e3da6ac docs: mark Steps 5-6 complete in ViewportPane plan
Both items were already implemented prior to this commit:
- MSPACE mouse routing (double-click/pan/zoom/Escape) was fully wired
  through the existing viewport_mouse overlay and scene helpers.
- Per-viewport frozen layer filtering uses matching Handle values from
  the same CadDocument, confirmed correct in model_wires_for_viewport().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 02:47:42 +03:00
Hakan Seven
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 Seven
de04b7e351 chore: bump version to 0.1.5
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 22:23:00 +03:00
Hakan Seven
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 Seven
62fbaf5da4 fix: hide block definition entities from viewport
Block-definition geometry (entities stored inside named blocks) was
leaking into the viewport when DXF files omit the owner-handle group
code (330) on block-content entities.

The fix tightens `belongs_to_visible_block`: when `owner_handle` is
null, the current layout block-record's `entity_handles` list is used
as the authoritative allow-list before falling back to the older
"not-in-any-other-block" heuristic.  This ensures block definitions
are never rendered directly, only when referenced via an INSERT.

Bumps version to 0.1.4.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 22:03:32 +03:00
Hakan Seven
e2f5715de8 fix: correct arc sweep direction for reversed normals and mirrored blocks
- Arc rendering now respects the normal vector: when normal.z < 0 the
  midpoint is placed on the clockwise side so the curve sweeps the right way
- Removed spurious .to_radians() / .to_degrees() round-trips in arc.rs
  (angles are already stored in the unit the trig functions expect)
- apply_grip and apply_transform use consistent angle units
- normalize_insert_entity no longer converts arc angles; the old conversion
  was only needed by the now-removed .to_radians() call in to_truck
- Added fix_mirrored_arc: swaps arc start/end angles when the INSERT has a
  mirrored scale (x_scale * y_scale < 0) so exploded arcs curve correctly

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 21:48:21 +03:00
Hakan Seven
a255b99863 docs: add COMMANDS.md and update ROADMAP.md in English
- Add COMMANDS.md: full CAD command reference (256 commands across 11
  categories) with implemented/partial/missing status for each
- Update ROADMAP.md to English, remove external product name references

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 20:06:35 +03:00
Hakan Seven
a879c9d878 docs: add ROADMAP.md with unimplemented ribbon commands
Lists 33 stub commands across Insert, View, Manage, and Annotate tabs
with descriptions and Low/Medium/High complexity estimates.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 19:49:06 +03:00
Hakan Seven
fce611d782 feat: redesign Manage tab to match reference layout
- Add Customization group: User Interface (CUI), Tool Palettes (large),
  Import, Export, Edit Aliases dropdown (small)
- Add Cleanup group: Find Non-Purgeable Items (large), Purge, Overkill, Audit (small)
- Add 8 new SVG icons for all new commands

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 13:27:40 +03:00
Hakan Seven
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 Seven
e3bce16545 feat: redesign View tab and fix Annotate/tab order
- Redesign View ribbon tab with 8 groups matching AutoCAD layout:
  Viewport Tools (UCS Icon, ViewCube, Navigation Bar),
  Navigate, Model Viewports (Viewport Configuration, Named, Join, Restore),
  Visual Style (dropdown), Projection, Preset,
  Palettes (Tool Palettes, Properties, Sheet Set Manager),
  Interface (File Tabs, Layout Tabs, Tile Horiz/Vert, Cascade)
- Add Extract Data and Link Data tools to Annotate → Tables group
- Fix tab order to Home → Insert → Annotate → View → Manage via build.rs PRIORITY list
- Add 17 new SVG icons for all new commands

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 12:25:15 +03:00
Hakan Seven
c8991bcc5a fix: make Wipeout and RevCloud large tools in Markup group
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 03:47:22 +03:00
Hakan Seven
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 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