- acadrust 7ea4247: clamped-knot degree and MINSERT reservation fixes
(cadcodec #47). cadkernel a0b962a: dogleg fails on a non-finite
Jacobian (cadkernel #66) and pins the same codec rev, so one acadrust
stays in the graph.
- The axis re-alignment from #1361 retains its transformed length through
retain_segment_length, which holds a zero-length segment with per-axis
differences instead of a P2PDistance whose gradient is NaN there.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
A minimized window has a 0x0 surface; the renderer's screenshot path
panicked on the empty read-back buffer and took the whole application
down. The capture op now checks the window size first and answers with
an error instead of requesting the screenshot.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
The first empty-space click of the 2Points flow was only resolved against
the document together with the second one, so "No valid constraint point
found." appeared one pick late. The command now hands the first pick to
the host (`CmdResult::CheckHorizontalPoint`), which resolves it right away:
a miss reports and re-asks for the first point, a hit moves on to the
second point.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
The temporary end-point pin of a transformed Horizontal/Vertical entity is
paired with the length the transform left it, so a scaled vertical line
stays scaled while a rotated one stays vertical at its rotated length.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
10) A transformed entity with a Horizontal or Vertical relation keeps only
its end point where the transform put it; the rest re-aligns to the
axis at the retained length, so a rotated vertical line stays vertical
below its moved end instead of the whole-entity pin contradicting the
axis and leaving the constraint unmet.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
9) When an edit contradicts a fixed point together with another constraint
so that the only solution collapses the entity (a rotated line with a
fixed start and a Vertical relation), the entity returns to its pre-edit
shape instead of degenerating, as the reference does.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Tables copied from other applications into the plot styles folder were
listed but refused on selection, showing as "missing" with the reason
lost on a console: the loader failed hard on a checksum or a text length
that did not add up and on any non-UTF-8 byte — and those files carry
their descriptions in Windows-1252.
- decompress_ctb reads the file as it is: a checksum or length mismatch is
reported and read past (a genuinely cut-off file is still an error), a
zlib stream with a bad trailer is retried as raw deflate, and text that
is not UTF-8 is read as Windows-1252 (pens and colours are numbers and
unaffected; other code pages only show wrong characters in descriptions).
- PlotStyleTable carries load_warnings; every load site reports them on the
command line, so a table that needed tolerance says so.
- load_named explains itself: a .stb name says named tables are not
supported yet, a .ctb missing from the folder says which folder to copy
it into (instead of "Unknown built-in plot style").
- The Plot dialog shows the reason under the Table row (style_error) —
from a selection, from a page setup that names a table, and from the
Load… picker, whose error used to be swallowed.
- A table picked with Load… from outside the plot styles folder is copied
into it (unless a file of that name is already there), so it is listed
from then on and page setups naming it resolve after a restart.
Tests: flipped checksum, text length off by one, a short payload field,
Windows-1252 descriptions, a truncated stream, .stb and missing names.
Co-Authored-By: Claude Opus 5 <[email protected]>
- #1352 pinned cadkernel/cadkernel-constraints to ramox81's fork. Its one
extra commit (cadkernel #67, SymmetricLineDirections) is now on
HakanSeven12/cadkernel main as the same SHA, so the manifests and lock
point back at the upstream repo at rev 0493b59.
- SYCONSTRAINT reports a repeated relation with the same message Fix and
Vertical use, as an error instead of plain output.
- The knot-less spline test consumes the add_entity results.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
8) A moved entity that a Fixed holds only in part no longer pins its free
points as hard anchors: they stay where the edit put them unless another
constraint on the entity (e.g. Vertical) moves them, so the fixed point
holds and the solve no longer fails when the two disagree.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Follow-up to #1341:
- interactive UCS offers Face / OBject; bare UCS OBJECT starts an entity pick
- one UcsPickCommand serves both FACE and OBJECT
- ucs_from_normal calls the existing arbitrary-axis helper instead of a copy
- prompt catalogue key and en-US text follow the new option list
Co-Authored-By: Claude Fable 5.1 <[email protected]>
The plot dialog asks CUPS printers for their sheets and margins; on Windows
the query was a stub, so every printer showed the paper catalogue with
unverified margins. The driver is now asked the way the plot dialog expects:
- windows_media (compiled and tested everywhere): the three parallel
DeviceCapabilities tables (ids, sizes in tenths of a millimetre, 64-WCHAR
names) become one PrinterMedia per distinct size — a rotated or
borderless twin folds onto its sheet, catalogue sheets keep their name,
unknown sizes carry the driver's — with the device's margins on every
entry and the driver's default sheet found by id or by user size.
- print_to_printer (Windows): DeviceCapabilitiesW for the tables, the
default DEVMODE for the default sheet, one portrait printer DC for the
unprintable margins (physical offsets and extents, per device — a
documented approximation). The DEVMODE fetch is shared with the print
path (with_printer_devmode).
- A direct print now asks the driver for the plot's own sheet (by id, or
as a user-defined size), so an A3 plot prints on A3 rather than shrunk
into the driver's default; a driver that refuses the sheet is asked for
the orientation alone.
- The capability cache remembers printers that could not be asked, so a
slow failing query runs once per session, not on every dialog open.
- PRINTERS <name> reports a printer's sheets, margins and default sheet.
Tests: names (NUL trim, full slot, lossy), media folding and dropping,
default by id / user size / none, DC margins, paper id lookup.
Co-Authored-By: Claude Opus 5 <[email protected]>
1) VCONSTRAINT (and the new GCVERTICAL name) uses the axis constraint flow:
"Select an object or [2Points] <2Points>:", 2Points mode with the
reference's re-prompts and messages, and the same object types as
Horizontal — line, polyline segment, text, MText, ellipse axis.
2) Object mode turns the object about its first vertex; a two-point relation
across two objects slides the second object rigidly onto the axis.
3) Re-applying an axis constraint reports that the constraint already
exists; Vertical follows the UCS Y direction.
4) The constraint bar draws Vertical as the reference's axis mark, with the
point marker for a two-point relation.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Collapse the triplicated send/timeout/deadline/nested-request loop in interactive_event, get_prompt and needs_entity_pick into PluginProcess::call_simple. Timeout floors, error strings and UnexpectedResponse behavior preserved exactly. Net: +64 / -72 in one file, no behavior change. Verified: cargo check clean, cargo test -p ocs_plugin_api --lib --features host (92 passed), clippy shows only pre-existing warnings.
7) The constraint bar draws Fix as a padlock instead of the letter F: a
white lock with a small orange point marker when one point is held, a
red lock when a whole curve or polyline segment is held.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Delete the byte-identical 0.68 muted_style copies across 13 window modules and import crate::ui::style::common::muted_style instead. print_all keeps its local name via muted_style as muted so call sites are untouched. Divergent alphas (0.60/0.62/0.65/0.72) and missing_fonts weak.text left alone to avoid visual changes. Net: +13 / -78, no visual change. Verified: cargo check --all-targets clean, cargo test --lib ui::style (3 passed).
On Windows a plot with no printer chosen went to the PDF application's
bare "print" verb — whatever that application considered its default —
and a viewer without a "printto" verb (Edge, store readers) silently
dropped the printer the dialog had chosen. The dialog also never named the
system default, and a failed printer enumeration left only "Default" and
"PDF" with the reason written to a console nobody sees.
- The default printer is looked up by name (GetDefaultPrinterW) both for
the dialog's "System default printer (…)" entry and before every job.
- A pure route decision (plan_print_route) resolves "Default" to that
name and uses the PDF application only when it registered a "printto"
verb for .pdf (AssocQueryStringW); otherwise the job goes straight to
the spooler through the existing GDI path. The report says which:
"Sent to printer: NAME (direct print | via the PDF application)".
- list_printers reports the system's own error; the plot dialog shows it
under the printer row and the command line warns once. A desktop without
CUPS is an empty list, not an error.
- PRINTERS command: default printer, listed printers (or the error) and,
on Windows, the print route — a report to paste into an issue.
- Properties… on the Default entry opens that printer's preferences sheet.
- GDI path: the driver's dmSize is kept (its private data lives behind
it), the print raster is no longer memoised for the session, and a
spooled temporary PDF is removed.
Tests: route planning (named / blank / no default / printto or not), the
PRINTERS command; the two Windows-only GDI tests pass the resolved name.
Co-Authored-By: Claude Opus 5 <[email protected]>
Deduplicate the byte-identical 1px divider helpers previously copy-pasted across 6 modules. form::{hdivider, vseparator} is now canonical, with a form::vsep alias for legacy call sites. style_manager re-exports both so scale_manager and anno_object_scale imports keep working unchanged. Delete locals in style_manager, plotstyle, dimstyle, layout_manager, attribute_editor. Replace thin wrappers in window/plot with direct imports. no visual change.
1) FXCONSTRAINT (and the new GCFIX name) prompts "Select point or [Object]
<Object>:" — a pick fixes that constraint point; Enter or O asks for one
line, polyline segment, circle, arc, ellipse or spline; misses and
unsupported objects report the reference messages and re-prompt.
2) Point, block, text, MText, attribute and table insertion points are
addressable constraint points.
3) Re-applying Fixed to the same point or object reports that the constraint
already exists instead of adding a duplicate.
4) A persistent Fixed holds its pre-edit geometry through MOVE, ROTATE,
SCALE, STRETCH, grip and Properties edits: fixed points stay, free points
of a partly fixed entity follow the edit, and size retention skips fixed
entities.
5) Object mode on a polyline fixes the picked segment (natively persisted)
instead of the whole polyline; arc segments pin endpoints, center and
radius.
6) Ribbon label "Fix" with a padlock icon.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
[SystemFolder] resolves to SysWOW64 on x64, where ie4uinit.exe
does not exist (only System32). This logged MSI 1721 on every
silent install. Icon associations via ProgId/Extension need no
manual refresh, so drop the action instead of switching to
System64Folder.
The Options window used to commit every control the moment it was
touched, with no way back but re-editing. It now works like the Drafting
Settings window: changes still show at once (a theme, a cursor size or a
language is seen immediately), but nothing is committed until Apply or OK.
Close — and the window's × or Esc — puts everything back the way it was
when the window opened or Apply was last pressed, asking first when there
is something to lose.
The commit point is a snapshot of the persisted configuration plus the
drawing variables the 3D Modeling page edits (with the drawing's modified
flag), so every control the window has or gains is covered without being
registered; reverting re-applies the snapshot the way start-up does and
re-bakes text or regenerates solids when those settings moved.
The "unsaved changes" guard is now a shared modal helper used by both
windows.
Co-Authored-By: Claude Opus 5 <[email protected]>
- PSETUPIN / -PSETUPIN: with no arguments a file picker offers the chosen
drawing's named page setups in the Plot dialog; `PSETUPIN <file>` opens
the same chooser on that file; `PSETUPIN <file> *` or
`PSETUPIN <file> name,name` import straight away. Same-named setups are
replaced, the import is one undo step, and the report counts both.
- The Plot dialog's page-setup list gains "Import…": the chooser shows the
source drawing's setups with a tick each, All, Import and Cancel, and
selects the first imported setup afterwards. The source is read off the
UI thread with the same reader the editor uses for its own setups
(`scene::document_page_setups`), and handles that only meant something
in the source drawing (plot view, visual style) are dropped on import.
- Options → General → Plotting: "Show the page setup for new layouts"
opens the Plot / Page Setup dialog whenever a layout is created
(persisted with the plot preferences).
Tests: the document reader, the command (all / named / unknown / missing
file / undo) against a drawing saved by the app, the chooser flow, and the
new-layout option. Nine new strings in all 21 locales.
Co-Authored-By: Claude Opus 5 <[email protected]>
Plot dialog:
- "Units" (millimetres / inches) is the page setup's own unit: the offsets
and the custom scale are shown in it, the stored ratio converts with it
so the plotted result and the paper space's unit stay the same
- "Custom: [paper] mm = [drawing] units" spells the picked scale in that
unit and accepts a typed ratio, which selects the list's name for it or
becomes a ratio entry of its own
- "Hide paperspace objects" is the page setup's plot-hidden flag; it is no
longer derived from the "Hidden Line" shade mode
- "Save changes to layout" (paper layouts, on by default) writes the dialog
into the layout when a plot is sent; previews never touch it
- offsets are labelled in the page-setup unit and kept in millimetres in
the file
System variables (typeable, through SETVAR, listed by SETVAR ?):
- PLOTOFFSET, PAPERUPDATE, PLOTROTMODE, PLOTTRANSPARENCYOVERRIDE and
BACKGROUNDPLOT live with the persisted plot preferences: the plot origin
counts from the printable corner unless PLOTOFFSET says the paper edge;
a printer that does not list the sheet either warns or switches to its
default sheet; transparency can be forced on or off; BACKGROUNDPLOT bit 1
is the dialog's background switch and bit 2 drives batch plots
- CTAB and TILEMODE read and switch the current layout
Tests cover every new control and variable; six new strings in all 21
locales; the Plot dialog grows to 940×690 for the two extra rows.
Co-Authored-By: Claude Opus 5 <[email protected]>
Older GPUs without usable DirectX 12 Feature Level 12_0 or working
Vulkan support (e.g. legacy Intel iGPUs and other old parts), and old
GLES drivers whose shader compiler rejects iced's own shaders, crash
at startup or on the first drawing viewport: StagingBelt aborts in
Buffer::get_mapped_range (panic=abort, silent exit) on the DX12 path,
and shader compilation fails inside iced's gradient pipeline on the
GLES path. Selecting a working backend via WGPU_BACKEND before iced
boots avoids both classes.
- Probe each candidate backend (Windows: dx12,vulkan,gl; Linux:
vulkan,gl) in an isolated --gpu-probe child: device request,
staging-style mapped upload, render pipeline creation (its fragment
shader reads a private vec4 array, catching old-Mesa compile
failures), offscreen render and readback. First fully-passing
backend wins; explicit --backend / WGPU_BACKEND / --safe-mode
always win, and Windows keeps preferring DX12/Vulkan (#55).
- Software adapters (WARP/llvmpipe/SwiftShader) are the last resort
before a best-effort GL attempt: slow but alive.
- The crash sentinel names the attempted backend so only implicated
backends are skipped next launch.
- Winning probes report adapter limits; GPUs without shader storage
buffers get the packed compatibility renderer automatically, with
a startup command-line notice so the switch is never silent.
On the web build, {"op":"open","path":…} resolves the name against the
browser's recent-files cache, so a file that is not already there cannot be
opened by the control channel. Accept {"op":"open","name":…,
"data_base64":…} instead: the bytes go through the same parse, caching
and recovery path as a file chosen in the browser picker
(io::open_bytes_web, now shared with pick_and_load_web).
Native builds keep path-based open and reject data_base64 with
invalid_request.
Refs #1349
serde_json keeps 10 and 10.0 as different Numbers, so an expected of 10
never matched a stored whole-number float, and a JavaScript client cannot
send 10.0 at all. Compare numbers by value (recursively through arrays and
objects); everything else keeps structural equality.
Fixes#1348