Commit Graph
69 Commits
Author SHA1 Message Date
Hakan SevenandClaude Opus 5.5 de1e49a4c5 feat(plot): PDF output carries drawing layers
Every plotted wire and hatch resolves to its entity's layer, and the PDF
wraps each run of same-layer items in an optional-content group, so a
viewer's layer panel lists the drawing's layers and can hide them. Draw
order is unchanged; images stay outside any group. Expanded block
geometry goes with its INSERT's layer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 13:04:39 +03:00
Hakan SevenandClaude Opus 5.5 74df9ff84a plot styles: the CTB/STB model and codec come from the codec crate
Cargo: codec d36331d, kernel 60f086b, graph 74aac56.

The table model and its file codec now live in `codec::plot_style`
(opencadcodec#53) and are re-exported here. What stays is where tables
come from: the plot styles folder, the session registry, the shipped
tables, and saving to disk, as the `PlotStyleTableExt` trait.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 10:58:26 +03:00
Karim Jerbi 6025d8be44 style: rustfmt the tree so the CI lint check passes 2026-10-15 04:10:06 +01:00
Hakan SevenandClaude Opus 5.5 072aeb9dbf PDF: cut sub-point dash patterns into their dashes (#1739)
PDF dash entries are whole points in the plot's user space; on an inch
sheet a 0.1 in dash rounded to the 1-unit floor, so every short pattern
plotted as 1 in on, 1 in off.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 13:01:55 +03:00
Hakan SevenandClaude Opus 5.5 088dec4ab6 fix(pdf): plot wide polylines with square ends and mitred corners
A polyline band was stroked like a pen line, with round caps and round
joins, and each segment as its own path, so corners came out rounded
and overlapping. Bands now use butt caps and mitre joins in one path,
and a tapered band fills each segment's quad so a zero-width segment
stays a thin line.

Fixes #1721

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 10:04:25 +03:00
Afonsop 69fa7cae4f web: fix red-team breaks in restore, drop-open, and plot paths
Three attack agents (state-machine tracing, executable input fuzzing,
browser-API review) found two breaks and several degradations; all are
fixed here, with the fuzzer's 22 tests kept as regression suites.

Breaks:
- Untitled tabs (and dot-names like ".dxf") autosave as DXF, but the
  restore name defaulted to .dwg — the worker dispatches its reader by
  the name's extension, so the only copy of unsaved work could never
  be restored and was re-offered forever. recovered_name now uses the
  worker's rsplit('.') convention and defaults extensionless names to
  dxf, matching new-document serialization.
- " (recovered)" stacked one suffix per crash-restore cycle; the
  marker is now stripped idempotently before appending.
- Opening a file (Ctrl+O / OPEN / automation) while a web open was in
  flight clobbered it: the in-flight open's bytes were lost and every
  queued restore prompt stalled for the session. on_open_file now
  refuses while an open is running (web only).

Hardening:
- Escape on the Recover Drawing modal defers instead of deleting the
  only snapshot; the Discard button still removes it.
- A cap-rejected restore enqueue warns in-app and re-offers the next
  snapshot; the drop queue cap rises to 32.
- Exiting mid-round no longer races snapshot removals (deferrals are
  drained, the sweep skips while a round is in flight); closing a tab
  with "Don't save" now also removes its web snapshot; the snapshot
  key derivation is shared via web_autosave_key.
- The plot-preview overlay no longer leaks a full PDF copy per preview
  (the Download closure lives in a replaceable registry).
- A corrupt autosave index.json fails the round/boot instead of
  silently resetting every row; plot pages with non-finite or non-
  positive sheet dimensions error instead of emitting a NaN MediaBox.
- The drop filter accepts dot-less "DWG"/"dxf" names the worker
  parses (same rsplit convention on both gates).

(cherry picked from commit 3eab00bfbf)

Ported onto main (#1717 review): the five standalone tests/*_redteam.rs
files stay out — no test target builds them and they exercised copies of
the functions rather than the code itself.
2026-10-12 12:02:04 +03:00
Afonsop 112060e370 web: harden plot preview after adversarial review
Three reviewers (security, correctness, performance) converged on:

- Download PDF died on the second click: Closure::once_into_js throws
  when invoked twice. The handler is now a plain FnMut kept for the
  overlay's lifetime.
- Rasterisation was bounded by page count, not pixels: 12 A0 sheets at
  150 DPI peaked near 1.8 GB of RGBA plus ~1.7 GB of decoded images,
  and a drawing declaring absurd paper sizes made the rasteriser
  saturate its u16 dimensions into a ~17 GB allocation that aborts the
  tab. Preview now computes a uniform DPI under a 64-Mpx total budget
  (floor 24 DPI) from the page tree before allocating, with a per-page
  4096-px edge clamp.
- Overlays stacked when previewing twice and their blob URLs were only
  revoked via Close. The overlay is now single-instance (id-tagged);
  a replacement or Close revokes every URL through a shared registry.
- emit_image resampled before probing the XObject cache, so a title
  block placed on 12 layouts ran 12 Lanczos passes to embed once.
  The cache is now probed with the target dimensions first.
- Preview downloads are named {stem}_preview.pdf instead of a constant
  plot_preview.pdf, and the page label says 'first N of M' when the
  preview is capped while the PDF keeps every page.

(cherry picked from commit 2a05479d69)
2026-10-12 12:02:04 +03:00
Afonsop 978000d37c io: enable the PDF pipeline on wasm32 and add plot quality presets
- pdf_export: drop the stale wasm32 gates (printpdf 0.9.1 compiles for
  wasm; the memchr/lopdf incompatibility is gone with memchr 2.8.3).
  Rendering is portable via render_pdf_bytes; only persistence differs:
  atomic temp-file write on desktop, browser download on the web.
  pick_pdf_path_owned on wasm returns a virtual path so the existing
  message flow works unchanged.
- printpdf moves from the native-only dependency table to the shared one.
- print_to_printer: preview_page_pdf / preview_pages_pdf render the same
  bytes and open them in a browser tab on the web (the browser's print
  dialog takes over); desktop keeps the temp-PDF + OS-viewer flow.
- sys: open_bytes_in_new_tab (blob URL, popup-blocked falls back to a
  download).
- New PlotQuality preset caps embedded raster resolution (High = native,
  Normal = 300 DPI, Low = 150 DPI effective); vector output is untouched.
  The image resource cache keys on the post-resample dims so one pixels
  Arc placed at different effective DPIs embeds per-placement XObjects.

(cherry picked from commit 4812bc775d)

Ported onto main (#1717 review): the plot model lives in io::plot; Normal
keeps native pixels like High (only Low caps images at 150 DPI, so desktop
output is unchanged); the searchable TrueType text layer and its allsorts
subsetting now build on the web too; the plot stamp reads the time through
js_sys on wasm.
2026-10-12 12:02:04 +03:00
Hakan Seven fb474eb77c Merge pull request #1701 from hvfrancesco/main
added SVG export feature

# Conflicts:
#	src/io/mod.rs
#	src/io/pdf_export.rs
2026-10-12 00:17:35 +03:00
Karim Jerbi 9cf9ff2c5c style: apply cargo fmt across workspace 2026-10-11 03:14:29 +01:00
francesco fantoni 666b5d561a added SVG export feature 2026-10-10 14:41:31 +02:00
Hakan SevenandClaude Opus 5.5 178c7dff41 fix: open-issue sweep — drawing, plot, snap, layout and UI fixes
Fixes:
- Font prompt no longer lists bundled ltypeshp/qcadshp shape files (#1626)
- Wide polylines step at a discontinuous segment width; PEDIT marks the
  current vertex; keyword steps refresh the command preview (#1628)
- Radius-0 fillet drops the zero-length segment it left, so the corner
  fillets again (#1422)
- FILLET Trim / No trim option (#1558)
- True-colour wires plot in their own colour; colour picker stores the
  value it shows (#1621)
- Model tab keeps its page setup; "Save changes to layout" in Model (#1620)
- QNEW default template in Options > Files; .dwt in the open dialog
  (#1134, #1113)
- GRIDUNIT / GRIDMODE / PERSPECTIVE variables (#1618, #1524)
- PTYPE (#1433)
- ZOOM nX / nXP (#1465)
- CHSPACE between model and paper space through a viewport (#1428)
- Moving a dimension keeps its automatic text placement
- Shell icon; "&&" button labels (#1554)
- LINETYPE Load from a .lin file (#1588)
- XLINE / RAY hide the crosshair arms (#1437)
- Dynamic-input boxes keep clear of the crosshair and each other (#1546)
- Snap marker colour setting, dark default on light canvases
  (#1497, #1229, #1128)
- Dimension style precision as a 0.00 pattern dropdown (#1426)
- Node graph nodes left of the origin no longer clip away (#1592)
- Collapse button in the command history header (#1094)
- Freeze-in-current-viewport toggle in the ribbon layer list (#1466)
- Geometric Center object snap for closed polylines (#1369)

New strings translated in all 21 locales.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 15:59:30 +03:00
Hakan SevenandClaude Opus 5.5 fafb1758c1 fix: settle the Count and Sheet Set merge
- Both PRs registered "Requires an integer between {min} and {max}." under
  their own key; keep the sheet set one, which every locale translates.
- Pin the MCP tool schema digest with the sheet set actions added.
- searchable_layer_coexists_with_outlines read glyph outlines from the
  shared atlas while other tests could re-bake it, and failed now and
  then; lay out and export under one atlas generation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 09:49:38 +03:00
Hakan SevenandClaude Opus 5.5 f14b675ff7 fix(web): gate native-only code out of the wasm build
The wasm check broke on the MCP `tools` op, the block library's folder
picker and DWG thumbnails, and the PDF export-window culling helpers.
Gate each one like the code around it; `read_handle` needs no gate.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 20:53:11 +03:00
Hakan SevenandClaude Opus 5.5 440adec834 fix(pdf): leave out what the export window clips away
Everything was written and only clipped at view time, so a window over a
corner of a large drawing produced a near-empty page of several MB.
Wires and hatches whose sheet bounds miss the window are now skipped.

Fixes #1568

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 20:44:08 +03:00
Hakan Seven c492539fde Merge PR #1580 from Chrisyeh1983/fix/pdf-embed-truetype-text: export TrueType text as embedded subset fonts
Conflicts with 02c470aa (invisible searchable text layer): main already
depends on allsorts 0.16 with the same features, so its line stays. Both
layers would put the text into the PDF twice, so a run drawn wholly in
faces the PDF can embed now goes out as embedded-font text and skips the
invisible layer; any other run (stroke fonts, mixed scripts) keeps its
outlines and the invisible layer. Faces only probed for such a run are
not installed. The PR's test follows layout_glyph_quads' new tuple.
2026-10-02 12:16:38 +03:00
Karim Jerbi 02c470aac7 feat(pdf): searchable text layer with per-style subset font embedding
Real BT/Tj text objects ride alongside the vector outlines (Tr 3,
zero visual change): runs preserved at layout time, TTF styles embedded
as allsorts subsets with ToUnicode, width-matched Tm, clip-culled.
WireModel literals moved to ..Default::default() tails.
2026-10-01 23:30:35 +01:00
Chris YehandClaude Opus 5.5 a8dc6534f9 fix(pdf): export TrueType text as embedded subset fonts, not triangles
PDF export filled every TrueType glyph's tessellated outline, one triangle
per triple. A stroke-heavy CJK face such as DFKai-SB tessellates into
hundreds of triangles per character, so a 28-layout schematic set
exported at 320.9 MB and viewers crawled through it. The atlas export
table was also rebuilt for every text wire, which made the same export
take 566 s.

- ttf_glyph: GlyphSource records the face, glyph id and font-unit scale a
  filled outline came from; glyph_source / fallback_source resolve the
  same face as glyph / fallback_glyph (fallback picks both in one search).
- Face::glyph_source mirrors Face::glyph; stroke glyphs (LFF, SHX, big
  font) return None and keep their polyline export.
- GlyphExport carries the char and the source (filled glyphs only, so
  TEXTFILL 0 still exports hollow outlines).
- pdf_export draws a sourced glyph as text (Tf 1 + a Tm that maps its em
  onto the SDF quad), subsets each face with allsorts after all pages
  (keeping cvt/fpgm/prep for tricky fonts), renumbers glyph ids, and
  snapshots the glyph table once per export.

Same set: 566 s / 320.9 MB -> 27 s / 1.42 MB; text is searchable and
lands on the same pixels as before.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-01 23:07:15 +08:00
Hakan SevenandClaude Opus 5.5 60f35e2b1d fix(color): only colour 7 swaps with the background; true colours draw as authored
Every near-white colour turned black on a light background (and near-black
white on a dark one), including true colours. A 255,255,255 solid used as a
white mask became a black block. Now only colour 7 swaps: true colours and
ACI 255 resolve a hair off pure white/black and keep their value on screen
and in plots.

Discussion #1500

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 06:16:18 +03:00
Hakan SevenandClaude Opus 5.5 38fe2b0b08 fix(plot): text and leader background masks plot paper-white, not black
The mask is filled with the canvas colour; plotting carried that dark
colour (or the light-to-black rule) onto the sheet.

Fixes #1072

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 19:01:56 +03:00
Hakan SevenandClaude Opus 5.5 ac8a9c38db fix(plot): true-color hatch fills plot in their own colour, not black
Fixes #1417

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 18:29:00 +03:00
ramox81andClaude Opus 5.5 5ca7becd97 Raster images: transparency off draws pixels opaque; TRANSPARENCY command
An image's transparency flag decides whether transparent pixels show what
is behind the image or draw in their stored colour: the image pass and PDF
plots now follow it (it was ignored, so every PNG alpha showed through).
TRANSPARENCY selects images and asks for the mode, defaulting to the first
image's current one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 11:23:19 +03:00
Hakan SevenandClaude Opus 5.5 f537aff75c feat: node graph overlay; move to opencadcodec/opencadkernel/opencadgraph
The codec and kernel repositories and crates are renamed opencadcodec and
opencadkernel. Inside OCS they are depended on under short keys, so code
reads `codec::`, `kernel::` and the new `graph::` (opencadgraph, the node
graph engine). File-format and protocol spellings stay as they were: the
ACIS product id `acadrust`, the ACADRUST_* switches and the plugin
version keys `acadrust_version` / `acadrust_source`.

A button left of MCP on the command line opens a translucent node graph
over the viewport, with a palette of object, input, math, logic, list,
text and geometry nodes added by click or drag. An object node owns
drawing entities and its rows are the Properties panel's own rows for
them: the single-object page is extracted from refresh_properties as
entity_property_sections, values use the control protocol's
property_json, and writes go through set_property_value with a property
target override, so the panel, MCP and the graph share one read/write
path. A list reaching an object row makes one entity per element. Each
graph action is one undo step; the canvas pans and zooms.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 07:34:23 +03:00
huanldandClaude Opus 5.5 279a87418e feat(automation): entity, block, publishing and REST operations from the fork
The operations docs/automation/API-SPEC.md (PR #1383) describes, brought
over from huaninstratech/OpenCADStudio so the specification no longer runs
ahead of the code:

- entity CRUD: entities_create, entities_delete, entities_transform,
  entities_copy_to, and `where` filters on query
- blocks and export: block_define, block_delete, a normalised wblock
- publishing: layout_create, page_setup_set, plot (per_page included)
- metadata: sysvar, xdata_set / xdata_get, file_identity
- collections: group_create, selection_set_save / load
- control plane: batch, events, view_focus, close
- the REST transport: `--http <port>`, the /api/v1 routes and their
  OpenAPI 3 description
- person-in-the-loop picks: user_select and getpoint, hosted by the GUI
  over the same REST routes, with on-screen pending signals

Taken from the fork's commits b7a7ed80, 69396b42, 64f1cf6a, c3aafc8e,
bb5a7bfa, 52317a5c, 50d293ba, b90e194f, 517c6397, 53a5c4c9, a49ac045,
37de5a46, a78b1822, 6d9aed2a, 33f522da, 5b5cafe2, 02a7e78d, 94df40dc,
fd5bc14d, 485fac61 and 2c5fc994.

Left out on purpose: 37de5a46 also removed the donation surface (the
Patreon fetch, the donation prompt, the Start-page supporters rail, the
DONATE command and its locale strings) and replaced the About dialog's call
to action; that is the fork's own product decision and stays out. The
fork's version bump and its unrelated IFC/BIM work are not part of this.

Adapted while porting: the REST server and the GUI bridge are desktop-only
and a template start is refused in the web build, so the wasm target still
compiles; the two plot tests read the PDF through the shared stream helper,
because exported streams are Flate-compressed; the benches set the new
crosshair field; comments and docs describe each operation in its own
terms rather than by another product's API names.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 13:41:07 +03:00
Chris YehandClaude Opus 5 4826cd7989 fix(pdf): Flate-compress the exported PDF streams
printpdf 0.9's `PdfSaveOptions::optimize` is a no-op — its `doc.compress()`
call is commented out — so every page's content stream (megabytes of vector
operators for a CAD sheet) was written uncompressed: a 16-sheet drawing set
exported as 280 MB. Serialise through `printpdf::to_lopdf_doc` and run
lopdf's `compress()` before writing; the same export is now 49 MB and
readers see ordinary FlateDecode streams.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-21 22:02:13 +08:00
huanld 36d5c4db79 fix(render): compose PLOTSTYLE wire-fill depth like the wire pipeline
When a display plot style maps an ACI to a fill pattern, wire fill
triangles are re-emitted as PLOTSTYLE hatches. Those took
depth_override raw — a per-block child label for block wires and 0.0
for top-level ones — while everything else in the hatch/wipeout pass
sorts at the composed depths[insert] + label * half. The fill could
land outside its host's band and get buried under its own block's
masks (same shape as the block-text bug).

Both the display and PDF paths now travel through wire_draw_depth /
the PlotWire's composed depth, and the display cache key rides the
depth generation so a DRAWORDER edit re-ranks the fills without
needing a wire rebuild.
2026-09-18 08:38:35 +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
Christopher Overbeck c93cc17592 Include bitmap images in PDF plots, preview, and printing
Include decoded IMAGE/OLE content in the shared PDF plotting path,
with clipping, transforms, transparency, draw order, and resource reuse.
Use named page content for export and printing.

Fixes #1266
2026-09-14 17:07:57 -05:00
ramox81 6272722baa Carry hatch origin through creation and pattern editing 2026-09-11 13:40:40 +03:00
Hakan Seven 5b663bfe38 Fix issues found while integrating contributor PRs 2026-09-08 12:14:28 +03:00
JonathanandCopilot 92ac3f60e5 Fix crash when overwriting an existing PDF file
Use atomic file operations (write to temp file, then rename) instead of
direct File::create() to avoid crashes when the target PDF is locked by
another process (e.g., open in PDF reader). The new write_pdf_atomically()
function ensures the file is either fully written or left unchanged, with
a clear error message if the file is in use.

Fixes #1062

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-09-08 09:04:52 +02:00
Hakan Seven d66e89ca19 Complete application localization across all supported languages 2026-09-07 01:05:02 +03:00
Hakan Seven 8c61d89b1e fix(layout): complete paperspace integration
Apply each layout's embedded page setup and plot style consistently across display, PDF, printing, and multi-layout output.\n\nRefs #844
2026-08-26 08:58:44 +03:00
Hakan Seven 4209c35ba3 fix(polyline): render fill mode boundaries
Use kernel-produced band outlines when FILLMODE is off. Preserve centerline linetype stations through inserts, clipping, projection, and PDF export.
2026-08-24 22:18:44 +03:00
Karim Jerbi 7215faae44 feat(properties): make inherited properties editable, align dropdowns, and switch transparency to EditChoice
Enable in-place editing of inherited properties in the Properties panel:
- Transparency: Switch to PropValue::EditChoice with ByLayer and ByBlock presets to allow direct typing of any numeric percentage value (0..90%) without combo_box autocomplete interference.
- Select-all-on-click: Integrate EditChoice text inputs into build_field_key_map with dedicated widget IDs, preserving click-to-select-all across editable fields.
- Material: Provide bounded preset choices (ByLayer, ByBlock, Global, and active custom material) to avoid scanning large drawing dictionaries.
- Plot style: Implement mode-aware behavior with interactive Choice in STB mode and ReadOnlyWithTooltip in CTB mode.
- Read-only tooltips: Introduce PropValue::ReadOnlyWithTooltip to provide contextual explanations for locked fields while preserving mouse text selection and clipboard copying.
- Dropdown alignment & unified borders: Fix EditChoice internal input/caret background clipping so the container's 1px neutral/active border surrounds the entire control identically to Lineweight and text inputs.
- Document defaults & aggregation: Synchronize document header defaults when editing with No selection, and aggregate heterogeneous multi-selections (*VARIES*).
2026-08-23 23:20:34 +01:00
Hakan Seven 339d9afcfe Merge pull request #857 from ramox81/codex/align-point-behavior
Align point command, properties, and display behavior
2026-08-22 22:58:42 +03:00
Hakan Seven 7293bec1b9 fix(point): preserve relative marker sizing
Keep rendering, picking, block transforms, and plotted output on the
same viewport-relative PDSIZE geometry without overloading wire width
fields.
2026-08-22 22:22:01 +03:00
Hakan Seven e5b84ab8de fix(plot): honor wipeout draw order 2026-08-22 15:33:43 +03:00
Hakan Seven f6b9d6514e feat(plot): add Print All workflow 2026-08-04 11:29:11 +03:00
Hakan Seven 6c62daf260 fix(plot): match PDF output to viewport
Refs #618
2026-08-01 20:05:38 +03:00
Hakan Seven 380cc4c9a8 fix(plot): align layout output with viewport
Keep nested model hatches, PAT origins and dots, and Layout lineweight scaling consistent across screen and vector output.\n\nRefs #618
2026-08-01 19:29:57 +03:00
Hakan Seven f0c1be0db1 fix(plot): correct layout hatch output
Keep Layout output on the selected physical sheet and preserve hatch lineweights and plot styles through paper, viewport, and nested block paths.\n\nRefs #607
2026-07-31 23:08:41 +03:00
Hakan Seven 325cd2474c feat(plot): complete plot configuration
- unify Model and Paper Space plot area behavior
- add CTB discovery, read/write, and bundled defaults
- apply scale, render mode, and output options consistently
2026-07-31 13:41:34 +03:00
Hakan Seven bd1b5b4293 feat(plot): complete plot workflow 2026-07-31 12:06:12 +03:00
Hakan Seven eb0861cf6e fix(plot): align paper space output
Use the same area pipeline as model space while keeping Layout bound to the physical sheet and printable margins. Share scale, rotation, clipping, and viewport fills across preview, PDF, and printer output.
2026-07-31 11:16:14 +03:00
Hakan Seven 99dbc8254d fix(plot): parent PDF save dialog
Remove the temporary EXPORTPDF <path> fallback now that native save requests are tied to the main window.\n\nCloses #537
2026-07-28 19:23:29 +03:00
Hakan Seven bca65600cd fix: stabilize web loading and paper rendering 2026-07-25 21:34:29 +03:00
Hakan Seven ece5598372 fix: correct viewport stretch and SHX plots
Anchor the opposite viewport corner during grip and STRETCH resizing.
Match plotted stroke-font pen widths to the SDF atlas unless CTB overrides.

Closes #435
2026-07-24 19:26:10 +03:00
Hakan SevenandClaude Fable 5 e78ad7884d feat(dialogs): reopen file pickers in the last-used directory
Every rfd dialog result funnels through sys::handle_path, which now
records the picked file's folder (persisted to the config dir), and all
pickers are built via sys::file_dialog(), seeded with that folder.
Save-As keeps the current tab's own directory as the first choice and
falls back to the remembered one.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 09:27:44 +03:00
Hakan SevenandClaude Opus 4.8 298bfd4803 feat(pdf): stroke the wide-polyline band at its world width
The shader-band change stopped emitting a hatch fill for wide polylines, so
PDF export — which drew the band from that HatchModel — lost it and plotted
only the thin centre-line.

Stroke the centre-line wire at the band width instead. In `build_pdf`, a wire
carrying `world_width` sets the pen to `world_width * MM_TO_PT` with no
`/ scale`: a lineweight is absolute on paper (hence the divide), but a band is
drawing-unit geometry and must scale with the plot. The CTM's scale then
renders the band at `world_width * scale` on the sheet, matching the geometry,
and the linetype dash pattern strokes it dashed. Overrides any CTB pen weight
(the width is geometry, not a lineweight).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 14:59:41 +03:00