Commit Graph
3537 Commits
Author SHA1 Message Date
Hakan Seven 7cd62a68f7 Merge pull request #1315 from ghost/ordered-perpendicular 2026-09-17 07:00:52 +03:00
Hakan Seven 03f4e7cb86 Merge pull request #1309 from ghost/embed-print-fonts 2026-09-17 06:57:42 +03:00
Hakan Seven 1701e672dd Merge pull request #1311 from ghost/plotting-station-a 2026-09-17 06:53:00 +03:00
Hakan Seven 49afac176b Merge pull request #1306 from ghost/plugin-doc-findings 2026-09-17 06:50:21 +03:00
Hakan Seven 144abc96fe fix(parametric): order polyline constraints by drawing direction 2026-09-16 23:15:40 +03:00
Karim Jerbi ca0ee37d26 feat(snap): independent 3D object-snap system with six modes
Grid snap locks to SNAPUNIT instead of magnetizing; snapped 3D points keep elevation instead of flattening to z=0. New SnapTypes Vertex/EdgeMidpoint/FaceCenter/Knot/FacePerpendicular/NearestFace with their own F4 master toggle and mode set, tiers, and markers, fully independent of the 2D master. Solid B-rep corners/edge-midpoints/face-centers from mesh edges and kernel faces, spline knot points, and live perpendicular/nearest-to-face on mesh triangles merged priority-aware in move/click paths. Drafting Settings 3D Object Snap tab is fully live (was dead placeholders); Nearest-to-face off by default. TDD: behavioral LINE-to-solid tests plus engine/scene unit tests.
2026-09-16 16:43:37 +01:00
ramox81 60bfc88b39 Fix ordered perpendicular constraint behavior 2026-09-16 18:21:16 +03:00
PanosandClaude Opus 5 737666b894 feat(plot): printer driver properties and a roomier plot dialog
Properties… next to the printer used to open the CUPS web interface in a
browser. It now edits the driver options of the *selected* printer the
way LibreOffice's Properties… does, without leaving the plot dialog:

- CUPS platforms (Linux, any desktop; macOS): an in-line editor lists the
  printer's PPD options as `lpoptions -l` reports them — media type,
  colour mode, quality, duplex, trays, scaling — with readable choice
  labels, Reset / Cancel / Apply. Apply keeps only the choices that differ
  from the driver defaults, per printer, in the plot config, and every job
  for that printer passes them as `lp -o key=value`. Where CUPS cannot
  answer, the desktop's printer settings panel opens instead of a browser.
- Windows: the driver's document-properties sheet (`DocumentPropertiesW`
  with prompt, owned by the main window) and, on OK, the result stored as
  the user's printing preferences for that printer (`SetPrinter` level 9),
  which the job honours. `printui /e` (printing preferences) replaces the
  device-properties sheet as the fallback.

The desktop print portal was tried first and dropped: GTK 4's print
dialog loses the preselected printer when the default queue is listed
before it, so the dialog always opened on the wrong printer.

Dialog layout: the modal grows to 940×620; Printer / plotter and Paper
size share a line with their pickers (long queue and media names now fit);
Copies + Properties… and Custom… sit beneath; the custom-sheet editor
labels each margin (Left / Right, Top / Bottom) and shows the unit.

Also recognises `none_device`, AutoCAD's stored spelling for "no plotter",
and writes it back unchanged.

Tests: `lpoptions` parsing and keyword humanising, the editor flow (load,
stale answer ignored, set, apply, remember, reset, error, cancel), device
name round-trips including `none_device`.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-16 16:05:47 +03:00
PanosandClaude Opus 5 5e271e2dbb feat(plot): custom paper sizes with printable margins
AutoCAD lets a plotter configuration carry user-defined sheets; a drawing
then names them like any other media (`Roll_24_(609.60_x_1500.00_MM)`).
The plot dialog now defines such sheets inline, under the Size row:
name, width/height, unit, and the printable margins in that unit. Added
sheets are selected at once, offered for every device after the device's
own list, remembered in the plot config across sessions, and written to
the layout with their own margins (a printer that reports the same size
still wins with its hardware margins). A selected user-defined sheet can
be removed; the sheet itself stays selectable in the drawing that uses it.

`CustomPaper` / `Margins` live in the paper catalogue with serde support;
`PlotDevice::margins_mm` consults the user's definitions. The Plot
dialog's form helpers (button and field styles, dividers, `label :
control` rows) move to `ui::style::form` so the next dialogs share them
instead of copying.

Tests: draft validation and seeding, catalogue naming of user sheets,
device margins with user definitions, and dialog round-trips (add,
select, persist, write, replace, remove, refuse an invalid size).

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-16 16:05:47 +03:00
PanosandClaude Opus 5 a7c89eca33 fix(plot): use AutoCAD's DWG To PDF printable areas
Replace the provisional PDF margins with the values AutoCAD's Plotter
Configuration Editor lists for `DWG To PDF.pc3`. They depend on the sheet
family and variant, not the size: ISO sheets 5/17/6/18 mm (left, bottom,
right, top), ISO expand 5/10/6/11 mm, ISO full bleed 0/1/0/1 mm; ANSI and
ARCH sheets 0.23/0.70 in, expand 0.23/0.42 in, full bleed 0.03 in all
round. Inch sets are stored in millimetres like the sheet itself.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-16 16:05:46 +03:00
PanosandClaude Opus 5 c03a40cb33 feat(plot): plot device model with AutoCAD names and printable areas
A page setup names its plotter, and AutoCAD looks that name up in its own
configurations: `DWG To PDF.pc3` for PDF output, the spooler name for a
system printer, `None` when nothing is assigned. Drawings saved here used
to carry the dialog's label ("Save to PDF file…"), so AutoCAD reported a
missing device on every layout plotted to PDF from Open CAD Studio.

- New `io::plot_device`: `PlotDevice { None, Pdf, Printer }` with AutoCAD's
  spellings, a reader for stored names that keeps any plotter
  configuration AutoCAD wrote (an HP `.pc3`, `DWF6 ePlot.pc3` — plotted to
  PDF here but preserved for AutoCAD) and upgrades the legacy label.
- Printable areas: the PDF driver's margins per sheet variant (full bleed
  edge to edge; standard / expand insets provisional until read off
  AutoCAD's plotter configuration), and for CUPS printers the media and
  margins the queue reports over IPP (`ipptool` `media-col-database`),
  parsed once per printer and cached. Windows enumeration follows with
  native GDI printing.
- Page setups now store the device in AutoCAD's spelling and the margins
  of the chosen device/sheet, keeping the drawing's own values while
  neither changed (AutoCAD's `PAPERUPDATE` behaviour). The paper-space
  printable-area rectangle follows.
- Plot dialog: the default entry names the printer it resolves to; a
  printer that answered lists its own sheets with a note; the media query
  runs in the background and answers for a since-deselected printer are
  dropped.

Tests: device names, stored-name resolution, PDF margin table, IPP media
parsing (sizes, margins, borderless folding, default sheet), PWG names,
plus dialog ↔ layout round-trips for PDF, legacy label, preserved plotter
configuration, sheet change → margins, and printer selection.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-16 16:05:46 +03:00
PanosandClaude Opus 5 567eb90925 feat(plot): paper catalogue with AutoCAD canonical media names
AutoCAD stores a layout's sheet as the plotter driver's canonical media
name (`ISO_A4_(210.00_x_297.00_MM)`, `ANSI_full_bleed_B_(11.00_x_17.00_Inches)`),
so a drawing saved here has to carry the same spelling for AutoCAD to find
the sheet in its DWG To PDF list, and a name that arrives from AutoCAD must
resolve to its dimensions and go back out untouched.

- New `io::paper_catalog` replaces the eight-entry `paper_sizes`: ISO A/B,
  ANSI, ARCH (incl. E1) and JIS series with full-bleed / expand variants,
  Letter / Legal / Tabloid, millimetre and inch units, a parser that
  reconstructs any well-formed AutoCAD name (custom or driver-specific)
  from its embedded dimensions, driver / legacy-config aliases (`A4`,
  `Letter`, `Ledger`), and dimension matching that prefers the plain sheet.
- The Plot dialog stores the canonical name and shows the sheet as
  `ISO A4 (210 × 297 mm)`; a sheet that only exists in the drawing is
  listed first so it stays selectable.
- A sheet the user did not change keeps the drawing's own media name
  (`paper_name_for_settings`), so a Windows printer's `A4` is not rewritten
  to `ISO_A4_(…)` just by passing through the dialog.
- Drops the unused `PlotFormat` / `PlotOrientation` messages,
  `paper_label_from_dims`, and three duplicated `match "A4" | …` tables.

Tests: catalogue spelling, parser round-trip, aliases, dimension matching,
display formatting, plus dialog ↔ layout round-trips for driver-named,
catalogue and unknown sheets.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-16 16:05:46 +03:00
gianlucafiore d894b8eb05 Merge pull request #1310 from gianlucafiore/fix-hatch-boundary-v2
Fix hatch arc direction for polyline boundaries
2026-09-16 09:18:10 -03:00
gianlucafiore 8c2d880e65 Fix hatch arc direction for polyline boundaries 2026-09-16 09:14:20 -03:00
huanld a45207f7c9 ci(release): gate signing steps on env mirrors of secrets
Step-level if: conditions cannot read the secrets context, which made
GitHub reject the workflow file outright (startup failure, zero jobs).
The signing waterfall now keys off job-level env booleans mirrored from
the credential secrets - a pattern actionlint accepts.
2026-09-16 17:52:01 +07:00
Karim Jerbi 624fe53382 feat(snap): editable Snap X/Y spacing with Equal lock, grid snap locks
Drafting Settings dialog gets text inputs for Snap X/Y spacing plus a working Equal X and Y checkbox (mirrored inputs, Y follows X on apply). Snapper gains fixed snap_spacing_x/y (persisted in UserSettings, default 10) decoupled from the adaptive visible-grid step. Grid snap no longer aperture-gated: with Snap On it rounds every point to the grid, object snaps still override by tier. Adds parse/lock regression tests.
2026-09-16 11:39:38 +01:00
huanld 53cd8e0109 ci(release): signing waterfall so forks build without upstream secrets
Forks do not inherit repository secrets, and the previous hardwired
Azure Trusted Signing steps failed the Windows job outright on a fork.
Each signing step is now gated on its credentials being present and the
pipeline falls through: Azure Trusted Signing (upstream setup, unchanged
when the secrets exist) -> PFX certificate from WINDOWS_PFX_BASE64 /
WINDOWS_PFX_PASSWORD via signtool with RFC-3161 timestamping -> unsigned
with a note in the job summary. The build and installer assembly always
complete.
2026-09-16 17:34:27 +07:00
huanld 28efbffd57 feat: embed images (OLE2FRAME), print pipeline fixes, plot prefs, community fonts
- IMAGEEMBED: pack raster images into OLE2FRAME entities so a .dwg is
  self-contained; 'Embed Image' entry in the XREF attach menu; control/MCP
  op embed_image for external tools; dxf_name for OLE2FRAME queries.
- Scene: populate_images_from_document now rebuilds OLE2FRAME and PDF
  underlay models too (they used to vanish after any XREF op).
- Printing: add PRINTER_ENUM_NETWORK pass when listing printers; GDI
  spooler fallback (hayro raster at 300 DPI + StretchDIBits) for hosts
  whose PDF handler registers no print verb; DEVMODE orientation with a
  90-degree raster rotation fallback for v4 drivers; fix the fit-scale
  precedence bug that printed blank pages.
- PDF export dialogs on Windows use the async file dialog so the native
  overwrite confirmation no longer deadlocks the UI thread.
- Plot dialog: persist the chosen printer (saved on selection) and the
  picked plot window across sessions; page setups with no device no
  longer reset the output device.
- Community fonts: detect unresolvable .shx references on open and offer
  a download from the repository's fonts/ folder (contribution guide in
  fonts/README.md); custom font source URL setting for intranet font
  servers; downloaded fonts resolve from the per-user fonts directory.
2026-09-16 16:42:21 +07:00
Karim Jerbi 1057790456 feat(ui): bring ALIASEDIT to shortcut-editor parity
Port press-to-capture dialog safeguards to the alias editor: transient top draft row with explicit accept, duplicate-alias and unknown-command danger styling plus persistent banners, reset-to-defaults with inline confirmation, Apply and Apply-and-Exit, alias count, Esc-cancels-draft-first, and unsaved-changes guard on close.
2026-09-16 09:32:06 +01:00
Hakan Seven 457f4b3dbb Fix block details hidden by wipeout masks (#1304) 2026-09-16 10:24:55 +03:00
Hakan Seven d10a0cf798 Merge pull request #1301: Add associative viewport dimensions
Refresh associations after complete SpaceMouse camera updates and recognize imported paper-space owners without Layout objects. Use kernel containment, intersection, perpendicular and spline tangent solving; pin cadkernel 7ce27f2 and add regressions.
2026-09-16 09:56:33 +03:00
Hakan Seven af847ad92e Merge pull request #1299: Add Windows SpaceMouse navigation 2026-09-16 09:41:25 +03:00
Hakan Seven 306d5d0957 Merge pull request #1302: Preserve valid zero-radius curves 2026-09-16 09:37:48 +03:00
Hakan Seven ffdb79a226 Merge pull request #1297: Fix perspective draw-order clipping 2026-09-16 09:35:59 +03:00
Hakan Seven 8f016d0431 Merge pull request #1298: Fix imported space layer invalidation 2026-09-16 09:31:26 +03:00
Hakan Seven 318dee2db8 Merge pull request #1294: Fix thumbnail scaling and nested signing 2026-09-16 09:29:50 +03:00
Hakan Seven 1a7aad8e04 Merge pull request #1293: Fix constraint indicator visibility 2026-09-16 09:28:49 +03:00
Hakan Seven 01a23673f1 Fix constrained corner and edge grip behavior 2026-09-16 08:45:09 +03:00
Felix RiestraandClaude Sonnet 5 bd49bd66d4 docs(plugin): fix inaccuracies and flag real gaps found building a plugin
Found while building an out-of-tree scripting plugin from scratch against
this doc and the actual ocs_plugin_api/host source. Two categories:

Fixed outright (docs/examples didn't match the real code):
- The worked CadModule example returned Vec<RibbonGroup> from
  ribbon_groups(); the real trait requires &[RibbonGroup] - the example
  wouldn't compile. Fixed with the OnceLock pattern the host's own
  benchmark code already uses.
- Reconciled a contradiction between "process isolation removes the need
  for a shared Rust ABI" and the exact-rustc_version requirement described
  a few paragraphs earlier in the same doc.
- The roadmap's "Next" list still had external automation as unstarted;
  --mcp/--serve are real and operational (src/cli.rs, src/mcp.rs).
- Added the missing plugin.toml to docs/plugin-template-v2 (its own
  DESIGN.md already claimed one could be installed).
- Documented that plugin-template's CI floats rust-toolchain@stable, which
  doesn't guarantee matching the host's exact rustc - added acadrust_source
  to both templates' plugin.toml plus the release.yml step that fills it
  from Cargo.lock's resolved acadrust source, alongside the existing
  rustc_version fill.

Flagging for your call, not fixed here (found the behavior, not sure it's
the intended one, prefer to ask than guess at a fix):
- acadrust_compatible()'s ABI gate only runs at all if plugin.toml declares
  acadrust_source - an undeclared field is silently treated as compatible,
  unlike rustc_version (undeclared = incompatible). The same shortcut
  appears in two places: ExternalPlugin::acadrust_compatible
  (src/plugin/external.rs) and the inline check inside fetch_release_info
  (src/plugin/marketplace.rs). If this is deliberate (e.g. back-compat with
  manifests from before the field existed), no action needed beyond a
  comment; if not, both call sites need the same fix.
- The command line still uppercases typed/pasted input even with the `>`
  literal-spaces prefix (Message::CommandInput, src/app/update/mod.rs) -
  `>` only stops a space from auto-submitting the line, it doesn't skip
  `s.to_uppercase()`. A plugin command needing a case-sensitive typed
  argument has no escape today short of automation.
- fetch_release_info (src/plugin/marketplace.rs) returns every release
  under a linked repo with no filter on the manifest's own id field (which
  it already parses to build ReleaseInfo) - a repo hosting more than one
  plugin under tag-namespaced releases surfaces all of them mixed
  together in one plugin's version list.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-16 03:37:54 +02:00
Karim Jerbi 1450fdeedf chore(i18n): sync locale catalog and translations with source strings
Remove the dead catalog entry for the deleted XREF dead-end text and add the 389 source strings missing from the catalog (data extraction, drafting settings, panels, commands). Every locale gets the English text as placeholder under common/insert following existing practice. scripts/test_locales.py passes (5077 lookups).
2026-09-15 23:56:32 +01:00
Karim Jerbi 4b351911bf fix(xref): deliver row-menu clicks via press-publishing rows
Each menu row is now a single mouse_area that publishes on PRESS instead of a button nested in a mouse_area. iced_aw ContextMenu keeps its overlay element in the widget struct, so every view rebuild wipes the overlay subtree state - including a button's is_pressed between press and release - and release-time clicks published nothing. Headless simulator tests through the real overlay guard row clicks, flyout clicks, the Change Path Type hover trigger, and pin the subtree-reset mechanism. Requires iced_test as a dev-dependency; the Cargo.lock gpu-allocator/windows edge is pinned back to 0.62.2 (see docs/review-context-menu-click-delivery.md).
2026-09-15 23:56:32 +01:00
Karim Jerbi be32af38a2 feat(xref): per-row path actions and right-click row selection
Row menu Select New Path and Find and Replace now act on the right-clicked row via dedicated XrefRowPathPick / XrefRowFindReplacePrompt messages (prefill + command-line focus, XOPEN output included). Rows use a RightClickArea wrapper so right-click selects the row even though ContextMenu captures the press, and opening or acting on the menu resets the Change Path Type flyout state.
2026-09-15 23:56:32 +01:00
Karim Jerbi 10758f3e59 fix(xref): Change Path Type flyout with hover reveal
The Change Path Type row shows a right-triangle affordance and reveals the Make Absolute / Make Relative / Remove Path submenu beside it. The flyout opens on hover only and a shared submenu-row style removes dead code from the earlier iterations.
2026-09-15 23:56:32 +01:00
Karim Jerbi 1c8e3ff3d7 feat(xref): 8-item filtered row menu, preview on selection, details display size
Row right-click menu is exactly Open, Attach..., Unload, Reload, Detach, Change Path Type group with Make Absolute, Make Relative, Remove Path, Select New Path, Find and Replace. Change Path Type renders as indented group. Open uses OCS for DWG and OS default for images and PDFs. Preview decodes on selection change, not only at refresh. Details shows placed display width and height for image instances.
2026-09-15 23:56:31 +01:00
Karim Jerbi 37085949a6 feat(xref): per-entry nested errors for Detach and Bind row operations
Detach and Bind on nested rows report the CLI-worded per-entry error instead of skipping silently. Adds GUI-path regression tests for every row operation on direct and nested rows, plus Reload All, Overlay, Change Path, and Find and Replace coverage.
2026-09-15 23:56:31 +01:00
Karim Jerbi e9151ea2f4 feat(xref): wider panel default, Attach DWG/Image/PDF menu, status icons
External References dock default 360 to 460 for the column-rich table. Attach split button reads Attach DWG with Attach Image and Attach PDF options, all menu rows full width. List view shows one distinct glyph and theme color per reference status.
2026-09-15 23:56:31 +01:00
Karim Jerbi 22a9bd602c feat(xref): row-level context menu actions and unified split-button toolbar
Right-click actions bound to the row under the cursor, split-button toolbar groups with shared borders and hover states, and a notice when an operation needs a selection first.
2026-09-15 23:56:31 +01:00
Karim Jerbi 494a872e8d feat(xref): row selection, resizable columns, tree view, and find-replace
Single, multi, and range row selection, resizable table columns, hierarchical tree presentation, and find-and-replace through the command line.
2026-09-15 23:56:31 +01:00
Karim Jerbi 019422d220 feat(xref): docked External References panel with previews and translations
Docked External References panel with host row, thumbnail previews, and translated interface strings.
2026-09-15 23:56:31 +01:00
Karim Jerbi d0d946a568 feat(xref): detach, unload, reload, bind, overlay, and path operations
Detach, unload, reload preserving host layer overrides, bind, overlay, and saved-path editing, with per-tab session state and a read-only web list.
2026-09-15 23:56:31 +01:00
Karim Jerbi 42219a4b8c feat(xref): reference list with stale and orphaned status detection
Reference list rows showing stale and orphaned states with handle-based identity.
2026-09-15 23:56:31 +01:00
Karim Jerbi 37e2b50e1c feat(xref): XREF command options and guided XATTACH
XREF command with status, reload, unload, detach, path, pathtype, bind, overlay, and attach options, plus guided XATTACH with unique naming and placement prompts.
2026-09-15 23:56:31 +01:00
Karim Jerbi f56d8a948e feat(xref): reference model with lexical paths, pathtypes, and statuses
Path normalization with stable keys, relative/absolute/none pathtypes, wildcard matching, and reference entries with loaded, stale, missing, and unreferenced states.
2026-09-15 23:56:30 +01:00
Christopher OverbeckandClaude Fable 5.1 8e14b10104 fix(io): keep zero-radius circles and arcs on open
Problem

The open guard rejects circles and arcs with a radius below 1e-10. A normal
open fails when a drawing contains one. The user gets the recovery prompt.
AutoCAD and nanoCAD open these drawings.

The check came from ace99541. Its comment says the tessellator cannot sample
a degenerate curve. That was true of truck's parameter_division. Commit
8c7ebdc9 removed truck. Commit 96be8214 made the kernel sample circles and
arcs by sweep angle with a floored segment count. The reason for the check
no longer exists.

Change

- Remove the near-zero radius check for circles and arcs.
- Keep the checks for non-finite values and radii above 1e10.
- Update the guard comments. The purge rejects parser desync. It does not
  reject degenerate geometry. Be generous in what you accept and strict in
  what you produce.
- Add tests: a zero radius passes the guard, an absurd radius does not.
- Change the automation purge test sample from radius 0 to radius 1e11.

Behavior

- Zero-radius circles and arcs load. They render as dots.
- Tessellation, hit testing, snapping, and hatch boundaries accept a zero
  radius.
- The DXF writer does not change.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-15 16:17:29 -05:00
Christopher Overbeck 4816652c1f Remove comments that repeat association operations 2026-09-15 16:03:17 -05:00
Christopher Overbeck 27967e0433 Integrate viewport dimension creation fixes
# Conflicts:
#	docs/viewport-dimensions.md
#	src/app/update/viewport_snap.rs
#	src/scene/viewport_dimension_pick.rs
#	src/snap.rs
2026-09-15 16:01:02 -05:00
Christopher Overbeck 5424a19482 Track mixed paper and viewport dimension references 2026-09-15 16:00:11 -05:00
Christopher Overbeck 6de4ed5a06 Support paper centerline dimensions through viewports 2026-09-15 15:56:33 -05:00
Hakan Seven cdf8bfe3ad Fix connected constraint grip previews and preserve anchored endpoints 2026-09-15 23:26:58 +03:00
Christopher Overbeck bd00d679a9 Integrate updated creation branch and upstream constraint fixes 2026-09-15 14:56:10 -05:00