Commit Graph
3097 Commits
Author SHA1 Message Date
Hakan Seven 7490b2bebd Merge pull request #1415 from ramox81/codex/aligned-constraint-parity
Aligned dimensional constraint: Point & line, 2Lines, value and property parity

# Conflicts:
#	src/app/command_driver.rs
#	src/app/update/viewport.rs
#	src/entities/dimension.rs
#	src/scene/parametric_constraints.rs
2026-09-21 22:41:42 +03:00
Hakan Seven 0ee8b15511 Merge pull request #1413 from ramox81/codex/linear-constraint-parity
Linear dimensional constraints: point flow, dynamic dimension, driving parameter, persistence

# Conflicts:
#	src/scene/parametric_constraints.rs
2026-09-21 22:36:20 +03:00
Hakan Seven 2208be9506 Merge pull request #1409 from ramox81/codex/equal-followups
Equal follow-ups: one glyph per object, unshown Multiple bars, typed object picks
2026-09-21 22:35:00 +03:00
Hakan SevenandClaude Fable 5.1 e537a495c6 fix(constraints): point symmetry converges from any start
Symmetric held the connecting direction perpendicular to the axis with
the kernel's angle-based Perpendicular, which locks its turn side at
construction: a point starting far from its mirror image had to swing
the pair through the axis direction, the residual wrapped, and the
solver stalled with the point unmoved. The perpendicularity is now the
projection of the pair onto the axis direction being zero, a polynomial
residual the solver follows from anywhere. Circle centers and ellipse
centers use the same equation. tests/parametric_constraints_solve.rs
symmetric_constraint_mirrors_one_circles_center_across_the_axis_line
passes again.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-21 22:21:19 +03:00
Hakan SevenandClaude Fable 5.1 ececb0ef8c ci: run the workspace tests on every change; drop the unused flake
- .github/workflows/ci.yml runs `cargo test --workspace --locked` on
  pushes to main and on pull requests, with the Linux libraries the
  release build installs. No formatter check: the tree is not
  rustfmt-clean and stays that way.
- flake.nix, flake.lock and the direnv hook are removed. Nothing used
  them, and their pinned dependency hashes were already stale after the
  codec and kernel bumps.
- Under cfg(test) the "system" language resolves to en-US. The unit
  tests compare English text through one process-wide loader, and every
  apply_config of a default config asked for the system language, so a
  Turkish locale failed 22 tests and parallel tests raced each other
  through a language switch (the thickness-row test found its section
  under one language and looked it up under another).
- The arc grip test follows #1352: the start, end and midpoint grips
  drive the whole arc.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-21 22:21:19 +03:00
ramox81andClaude Fable 5.1 8e83b2f843 Aligned constraint: 2Lines turns the second line with the plain Parallel solve
Only the first line's ends are pinned while the second line is made
parallel, the way the Parallel constraint itself moves it; the distance
is then measured on the solved geometry.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-21 16:38:26 +03:00
ramox81andClaude Fable 5.1 5fab97a7d0 Aligned constraint: axis lines, zero collapse, Properties form/reference/description, screen-sized text
Point & line and 2Lines take a text baseline or an ellipse axis as the
line; a zero value folds the points onto the first one; 2Lines turns the
second line about its start. The Properties Constraint section edits
Constraint Form (Dynamic on the *ADSK_CONSTRAINTS layer, Annotational on
the current layer), Reference (driven constraint in parentheses whose
parameter follows the measurement) and Description (stored with the
parameter and the native variable). Dynamic dimensions keep a 12 px text
and 8 px arrows at any zoom, drop trailing zeros and show formulas as
`fx: len=d1*2`; the hidden constraints layer stays out of the layer lists.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-21 16:04:26 +03:00
ramox81andClaude Fable 5.1 3e28604752 Dimensional constraints: DCFORM, DIMCONSTRAINT options, -PARAMETERS, value prompt, save without display overrides
DCFORM sets the annotational or dynamic form and continues into the
DIMCONSTRAINT option prompt, whose wording and last-used default match the
reference. -PARAMETERS manages parameters from the command line; a
double-clicked constraint dimension opens its value prompt. Dynamic
dimensions rescale on every camera change and their display overrides stay
out of the saved file. A driving dimension between an entity's own ends no
longer has its length retained, so a new value moves the second point along
the dimension axis; parameter edits hold the first constraint point.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-21 15:08:44 +03:00
ramox81andClaude Fable 5.1 6969c19746 Aligned dimensional constraint: Point & line, 2Lines, value and property parity
DCALIGNED opens with `[Object/Point & line/2Lines] <Object>`. Point & line
asks `Specify constraint point or [Line] <Line>:` then `Select line:` (or the
line first and `Select constraint point:`), measures perpendicular to the
line from the constraint point to the line end nearest to it, and stores a
directed distance with the line as direction reference. 2Lines asks
`Select first line:` and `Select second line to make parallel:`, adds a
Parallel constraint solved with the first line pinned, then measures on the
solved geometry between the nearest ends. Unsupported line picks report the
reference's message; the same measurement again reports `The constraint
already exists on the selected objects.` and ends the command; an invalid
expression reports both reference lines and asks again.

The offered default and seeded expression carry twelve significant digits;
a typed value moves the second point (or the other object) while the first
point and its measured line stay, negative values keep their sign in the
parameter and use their magnitude, zero folds the points together, and the
dynamic dimension's origins follow every solve. The lock mark sits after the
text, a selected dynamic dimension shows triangle grips at its points and the
text square, and its Properties show the Constraint section (Name and
Expression editable) plus Text rotation.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-21 14:52:37 +03:00
ramox81andClaude Fable 5.1 aa51765a62 Dynamic dimensions: reference text format, horizontal text, lock after the text
A plain number shows as typed (d1=100), an expression under the fx: prefix
(fx: d2=d1*2); the text stays horizontal through DIMTIH/DIMTOH overrides
and the lock mark follows the text.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-21 13:57:06 +03:00
ramox81andClaude Fable 5.1 0b5c686371 Dynamic dimensions: constant screen size, transform keeps the second constraint point
Every dynamic dimension gets a DIMSCALE override for 12 px text, refreshed
per zoom band, at creation and after load. A SCALE/ROTATE of an entity whose
own end points a driving dimension measures now pins its second constraint
point so the dimension moves the first end, as the reference does.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-21 13:36:01 +03:00
ramox81andClaude Fable 5.1 971abe64a4 Dimensional constraints: dynamic dimension persistence, lock mark, display variables, DIMCONSTRAINT
The dynamic dimension of a dimensional constraint is now linked in the
drawing file (AcDbAssocDependency + AcDbAssocDimDependencyBody on the
constraint node), reread on load, hidden by DCHIDE/DYNCONSTRAINTDISPLAY
and never plotted; it carries a lock mark before its text. New
CONSTRAINTNAMEFORMAT and DYNCONSTRAINTDISPLAY variables and the
DIMCONSTRAINT option front end. A transformed entity whose own end points
a driving dimension measures keeps only the first constraint point, so a
scaled line returns to its dimension value.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-21 12:13:36 +03:00
ramox81andClaude Fable 5.1 72fd3fd35b Linear dimensional constraints: point flow, dynamic dimension, driving parameter
DCLINEAR, DCHORIZONTAL, DCVERTICAL and DCALIGNED follow the reference flow:
`Specify first constraint point or [Object] <Object>:`, `Specify second
constraint point:`, `Specify dimension line location:`, then `Dimension
text = …` and `Enter value or name and value <d1=100>:`. Linear reads
horizontal or vertical from the dimension line location the way a linear
dimension does; Object takes a line's, an arc's or a polyline segment's
ends. A miss reports `No valid constraint point found.` / `No object
found.` and asks again; another object type reports `Invalid selection for
Linear. Select a line, polyline segment or arc.`.

Each constraint creates a drawing parameter (`d1`, `d2`, …, or the typed
`name=expression`), drives the constraint through it, and draws a dynamic
dimension in constraint gray whose text follows CONSTRAINTNAMEFORMAT
(`d1=100.0000`); the dimension is associated with the constrained objects
and its text is refreshed after every solve. A typed value other than the
measured one moves the second point while the first stays, and so does a
later parameter edit. Deleting the constraint removes its dimension and,
when nothing else reads it, its parameter.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-21 11:53:19 +03:00
ramox81andClaude Fable 5.1 959d0011d6 Equal: show the bar of a Multiple pick at once, like the two-object flow
A fresh reference session shows the "=" bar of every object made equal
through Multiple right away; the earlier hidden state was not the rule.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-21 09:58:57 +03:00
ramox81andClaude Fable 5.1 842ae461fc Equal: ask for the second object again after a refused pick, name the kind it needs
A second object of the wrong kind (a circle after a line, a line after a
circle) or a pair that already carries Equal now reports and asks for the
second object again instead of ending the command. The mismatch message
names what the first object asks for — `Select a line segment, polyline
segment, text, MText, major or minor axis of ellipse or elliptical arc.`
after a length object, `Select a circle or arc.` after a radius object —
and the same-pick message carries the reference's double space.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-21 09:46:13 +03:00
ramox81andClaude Fable 5.1 ad6f902ed7 Equal follow-ups: one glyph per object, unshown Multiple bars, typed object picks
- An object that carries several Equal relations shows a single "="
  badge, as the reference does, instead of one stacked badge per relation.
- A pick made in the Multiple flow leaves its new constraint bar unshown
  until the object is selected or bars are shown, matching the reference;
  the single flow still shows the bar at once.
- A typed coordinate at the Fix `Select object:` prompt and at the
  Horizontal/Vertical `Select an object or [2Points]` prompt picks the
  object under that point, like a click, instead of being read as a point.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-21 09:18:40 +03:00
Hakan SevenandClaude Fable 5.1 fd2062bdec fix(insert): attribute grips follow ATTMODE 2 and annotative scale
Follow-up to the block-attribute grips picked from #1386.

- Movability no longer includes the invisible flag: an attribute ATTMODE 2
  displays is grippable, so the grip the display-aware list shows can be
  dragged. The document-less grips() still skips invisible attributes,
  since it cannot consult ATTMODE.
- The grip sits on the displayed attribute, which an annotative insert
  scales about its insertion point; Scene::apply_grip now unscales the
  dragged target the same way before the attribute stores it, so the grip
  no longer jumps to twice the drag at scale 2.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-20 21:31:54 +03:00
copilot-swe-agent[bot] 2b92fc5b09 Fix missing brace in insert attribute visibility filter
Co-authored-by: dasmatus <[email protected]>
(cherry picked from commit 6cf16d8621)
2026-09-20 21:29:15 +03:00
dasmatus 4559c8a2d8 Refactor attribute filtering logic in insert.rs
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
(cherry picked from commit a8f75e969d)
2026-09-20 21:29:15 +03:00
copilot-swe-agent[bot] bd89507a6c fix insert attribute grip visibility
Co-authored-by: dasmatus <[email protected]>
(cherry picked from commit 68cc414e4a)
2026-09-20 21:29:15 +03:00
Claude 9af327ed0b feat(insert): grip each block attribute
Selecting a block showed one grip, at its insertion point, so there was
no handle to pick an attribute up by: an attribute could only be moved
by moving the whole block.

Give the INSERT one grip per attribute, taken from the attribute's own
`Grippable` implementation, at ids `1 + index`. A drag on one moves that
attribute alone, through the same `apply_grip` the attribute already has
(which carries `alignment_point` along, so non-left alignments stay put
relative to the text). Grip 0 keeps translating the block and every
attribute with it (#255).

A constant attribute belongs to the block definition and an invisible one
is not drawn, so neither offers a grip; a locked-position attribute
declines on its own.

Fixes HakanSeven12/OpenCADStudio#1259

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01TQzYZsXBwPZ5HwBaGitEUV
(cherry picked from commit 7eb966f6a2)
2026-09-20 21:29:15 +03:00
copilot-swe-agent[bot] 5d4b707214 fix review feedback for OTRACK projection and OtrackHit API
Co-authored-by: dichhead <[email protected]>
(cherry picked from commit 97f94a2bfe)
2026-09-20 21:29:15 +03:00
Claude 033319a4e3 feat(otrack): draw both vectors of an intersection lock
An OTRACK crossing is the meeting of two tracking vectors, but
`OtrackHit` carried only the one a typed distance is measured along, so
the overlay had a single guide to draw. Snapping to the crossing of two
vectors worked and looked like an unexplained point on one line.

Carry the crossed ray out of `otrack_snap` as `OtrackHit::cross`, keep it
on the app beside `otrack_active`, and let the overlay take a list of
guides rather than one. `otrack_active` still drives typed-distance
entry on its own, so distance entry is unchanged.

Fixes HakanSeven12/OpenCADStudio#1313

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01TQzYZsXBwPZ5HwBaGitEUV
(cherry picked from commit 2f6caacece)
2026-09-20 21:29:15 +03:00
copilot-swe-agent[bot] 41101efaa5 fix(trim): skip empty preview polyline segment samples
Co-authored-by: dasmatus <[email protected]>
(cherry picked from commit fb13a7aaa6)
2026-09-20 21:29:15 +03:00
Claude e83c8a28a5 fix(trim): skip polyline segments with no plan-view shape
`sample_entity_xy` walks a polyline's exploded segments and drops the
vertex each segment shares with the previous one. A segment whose curve
plane is upright — any non-horizontal run of a 3D polyline — has no XY
curve, so `entity_curve_xy` declines it and the segment samples to
nothing. With nothing accumulated yet, the seam test compared the two
empty ends as equal and then sliced the empty sample from index 1:

    panicked at src/modules/draw/modify/trim.rs:3982:42:
    range start index 1 out of range for slice of length 0

On the web build that panic unwinds through winit's event-loop runner
and leaves its state borrowed, which is the "RefCell already borrowed"
follow-on in the same report.

Skip an empty sample instead, which leaves the seam handling to the
segments that do have a plan-view shape.

Fixes HakanSeven12/OpenCADStudio#1318

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01TQzYZsXBwPZ5HwBaGitEUV
(cherry picked from commit ac9a6ce91a)
2026-09-20 21:29:15 +03:00
Hakan SevenandClaude Fable 5.1 a1629fd073 fix: closing-segment markers on closed polylines; case-insensitive page-setup names
- resolve_point, set_polyline_vertex and the solver's point_for_marker
  treat the marker one past the last vertex of a closed polyline as
  vertex 0, the way line_segment already did. Equal (#1366), the axis
  pre-alignment (#1365) and the transform pin (#1361) address a picked
  segment's end that way, so on the closing segment they either refused
  the pick or pinned nothing.
- Page-setup dictionary keys compare case-insensitively: page_setup_save
  replaces "site" when "Site" exists instead of adding a second entry
  (PSETUPIN counted it as replaced, #1344), delete and rename match the
  same way, and a rename that only changes case is allowed.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-20 21:12:07 +03:00
Hakan SevenandClaude Fable 5.1 8845095432 fix: DXF attribute rotation converted once; plugin layers refuse unknown linetypes
- The acadrust DXF reader has converted ATTRIB/ATTDEF rotation to radians
  since f226110 (in every codec rev OCS pinned from 2026-08-08 on), while
  fix_dxf_dimension_rotations still applied to_radians a second time on
  load. Only Shape needs the conversion here. Surfaced by #1391's hunk.
- Shape-file text styles are found by their is_shape_file flag instead of
  an empty name (also from #1391).
- #1393's add_layer/modify_layer wrote an unresolved linetype name into
  the LAYER record; a name the drawing (plus the standard set) cannot
  supply is now refused, through one resolve_linetype helper.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-20 20:18:18 +03:00
Hakan Seven 8075caa744 Merge pull request #1393 from yztink/feat/plugin-layer-properties
feat(plugin): add layer creation and modification host API with GUI refresh
2026-09-20 20:14:10 +03:00
Hakan Seven 871b0ab2ec Merge pull request #1392 from buyun14/fix/batch-line-tail
fix(automation): consume and report the tail of a batch command line
2026-09-20 20:14:10 +03:00
buyun14 899af80c2f fix(automation): consume and report the tail of a batch command line
`run_command_line` feeds the tokens after the command verb to the interactive
command and then terminates it as if Enter were pressed. Two gaps left a
headless caller unable to tell what actually happened.

In-place text editor takes over, remaining tokens were dropped
----------------------------------------------------------------
The `TEXT` content step hands over to the in-place editor, at which point the
command has already ended (`active_cmd` is `None`). The feed loop stopped
there, so the rest of the line — including the text itself — vanished:
`TEXT 0,0 5 0 hello` reported `completed` with `added: 0` and created nothing.
The tail is now typed into that editor and committed, and the commit is done
synchronously so its result is observable: `text_inline_commit()` returning
false leaves the tokens in `unconsumed` instead of reporting a successful line.
Dispatch the commit as a queued message instead and a failed commit would look
exactly like a good one — the text dropped, `added: 0`, `unconsumed: []`.

Only an editor this line opens is taken over, and after a successful commit the
line is closed with an escape: `TEXT` re-arms for the next line
(`open_next_line`), which would otherwise let the *next* batch line be eaten as
the next text position.

Leftover tokens are dropped
---------------------------
Any token no prompt ever asked for is recorded in `CommandLine::unconsumed` and
surfaced by the automation `run` response, so over-typed or misplaced input is
visible instead of silently ignored: `CIRCLE 0,0 5 9` reports
`"unconsumed": ["9"]` while a fully consumed line reports an empty list.

Pending surfaces are reported instead of `completed`
----------------------------------------------------
`run` now carries `blocked_by` — `"command"`, `"text_editor"`,
`"mtext_editor"`, `"modal:<Kind>"`, or `null` — and answers `waiting_input`
when something is still open rather than claiming `completed`.

`blocked_by` is attributed to the line that opened the surface: a condition and
its snapshot are taken before the command runs, so an editor left open by an
earlier line, another tab, or a startup dialog does not turn a finished command
into `waiting_input`. Without that attribution a caller polling for `completed`
would wait forever on someone else's editor. `docs/automation` documented
`waiting_input` as "more input is required", which is exactly what a pending
surface is; the two new fields are documented there as well.

Tests
-----
* `batch_text_line_creates_text_and_consumes_every_token` — the regression case
  creates exactly one `Text` entity and leaves nothing unconsumed.
* `multi_word_text_keeps_the_spaces` — asserts the committed string, so an
  off-by-one in the consumed index or a wrong join cannot pass.
* `run_reports_leftover_tokens_instead_of_dropping_them`.
* `text_without_content_reports_the_open_editor`.
* `a_stray_editor_is_not_hijacked_by_the_next_line` — the next line neither
  types into the stray editor nor inherits its blocker (`blocked_by: null`,
  `status: completed`).
* `a_command_still_waiting_is_named_as_the_blocker`.

Verified over the `--serve` protocol: `TEXT 0,0 5 0 hello world` → `completed`,
`added: 1`, and the entity really holds `hello world`; `TEXT 40,0 5 0` →
`waiting_input` + `blocked_by: "text_editor"`; the following `CIRCLE 0,0 5 9` →
`completed`, `blocked_by: null`, `unconsumed: ["9"]`; `LINE` → `waiting_input`
+ `blocked_by: "command"`.

Full lib suite: 1497 passed, 2 failed — both failures
(`io::plot_style::…named_tables_and_missing_files_get_a_reason`,
`scene::parametric_constraints::…arc_grips_drive_center_start_and_end_but_not_midpoint`)
reproduce on the unmodified tree; run with `LC_ALL=C` since several xref tests
otherwise fail on a non-English locale.

Known remaining gap, unchanged here: `MTEXT` / `HATCH` still answer `completed`
with `added: 0` in this path (they need interactive surfaces the feeder has no
tokens to fill). Reported separately in #1390.
2026-09-20 19:15:55 +08:00
Karim Jerbi 70d7e9a31f perf(plotstyle): extract and speed up layer-usage table rebuild
view_window() rebuilt the 256-bucket ACI layer-usage table inline on every
modal view: unconditional 256-Vec allocation plus sort_by_key (lowercase key
recomputed per comparison). Extract pure build_layer_usage(), build it only
when the CTB path needs it (STB path now allocates nothing), and sort with
sort_by_cached_key while skipping trivial buckets.

Tests:
- build_layer_usage_buckets_index_colors: ACI bucketing + case-insensitive order
- build_layer_usage_ignores_non_index_colors: truecolor layers excluded

Bench (cargo bench ui_plotstyle_layer_usage, 200 layers): ~13us median, PASS.
A/B vs pre-change inline code: ~15.7us -> ~12-13us (~22% faster).
2026-09-20 11:17:05 +01:00
Helen Kwok cf004107b2 Keep the task a dispatched command returns
CmdResult::Dispatch and CmdResult::Relaunch end the active command and run the
assembled line through dispatch_command, then discarded the Task it returned
(`let _ =`). A command whose effect is a message carried by that Task was
announced but never applied. VSCURRENT's keyword picker is one: choosing
"Gouraud Shaded" printed "Visual style: Gouraud Shaded." and left the
drawing in wireframe, because SetRenderMode travels in that Task.

Hold the Task and batch it with the focus task that apply_cmd_result_inner
returns. A regression test drives both results through VSCURRENT and checks the
tab's render mode.
2026-09-20 13:17:05 +09:30
Hakan SevenandClaude Fable 5.1 768ce2ca82 chore: pick up cadcodec 5b682ed (upstream acadrust sync) and cadkernel 6f046af
acadrust follows hakanaktt/acadrust main through #107, entity-record
passthrough included; cadkernel pins the same codec rev so one acadrust
stays in the graph. Upstream added BlockFlags::is_xref_unloaded, which
XATTACH now sets to false for a freshly attached reference.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-20 06:22:19 +03:00
yztink 929f185ba5 feat(plugin): add layer creation and modification host API
- Add LayerConfig struct and add_layer / modify_layer methods to HostApi trait
- Implement IPC request/response serialization for AddLayer and ModifyLayer
- Implement HostSession methods with CAD property defaults and selective modification
- Refresh layer panel UI and invalidate scene layer dependencies upon layer changes
- Add unit tests for add_layer with defaults and partial modify_layer
2026-09-19 16:40:41 -07:00
Hakan Seven fbdc97af4a Merge pull request #1381 from huaninstratech/pr/isoplane-session-only
fix(settings): keep isometric drafting session-only
2026-09-19 23:06:51 +03:00
Hakan Seven 7204d4f98d Merge pull request #1380 from huaninstratech/pr/io-locked-drawings
fix(io): open locked, shrinking and cloud-placeholder drawings without crashing
2026-09-19 23:06:51 +03:00
Hakan Seven 97596de147 Merge pull request #1377 from helenkwok/fix/control-accepts-point-with-keywords
Control: a point step that takes keywords accepts points
2026-09-19 23:06:51 +03:00
Hakan SevenandClaude Fable 5.1 92ce142c03 fix: drop the stray lock fixture; align merged plot code across targets
- tests/fixtures/plot/.page-setups-metric.dxf.ocs.lock was the app's own
  single-instance lock file, committed by accident in #1343; remove it and
  ignore *.ocs.lock.
- load_plotsettings_into_dialog: #1343's refresh_custom_scale_fields borrowed
  self while #1360 still wrote through the plot_dialog borrow; write the
  style error first.
- The wasm list_printers stub returns the Result #1358 gave the native one.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-19 23:06:09 +03:00
Hakan Seven 829a69ae6a Merge pull request #1367 from ramox81/codex/axis-hover-markers
Hover an object-mode Horizontal/Vertical glyph without endpoint markers
2026-09-19 23:01:01 +03:00
Hakan Seven 3ba370bcd1 Merge pull request #1366 from ramox81/codex/equal-constraint-parity
Bring the Equal constraint to reference parity

# Conflicts:
#	src/command.rs
2026-09-19 23:01:01 +03:00
Hakan Seven b131102784 Merge pull request #1365 from ramox81/codex/axis-align-perpendicular
Turn an object onto its Horizontal/Vertical axis before solving
2026-09-19 23:00:46 +03:00
Hakan Seven f20c823ffe Merge pull request #1360 from HakanSeven12/plot/b4-ctb-leniency
fix(plot-style): load plot style tables written by other applications

# Conflicts:
#	src/app/update/file.rs
#	src/ui/window/plot.rs
2026-09-19 23:00:19 +03:00
Hakan Seven 996412c405 Merge pull request #1359 from HakanSeven12/plot/b4-windows-printer-media
feat(plot): Windows printer media and printable areas

# Conflicts:
#	locales/ar-SA/opencadstudio.ftl
#	locales/bg-BG/opencadstudio.ftl
#	locales/cs-CZ/opencadstudio.ftl
#	locales/de-DE/opencadstudio.ftl
#	locales/el-GR/opencadstudio.ftl
#	locales/en-US/opencadstudio.ftl
#	locales/es-ES/opencadstudio.ftl
#	locales/fi-FI/opencadstudio.ftl
#	locales/fr-FR/opencadstudio.ftl
#	locales/hi-IN/opencadstudio.ftl
#	locales/hu-HU/opencadstudio.ftl
#	locales/it-IT/opencadstudio.ftl
#	locales/ja-JP/opencadstudio.ftl
#	locales/ko-KR/opencadstudio.ftl
#	locales/nl-NL/opencadstudio.ftl
#	locales/pl-PL/opencadstudio.ftl
#	locales/pt-BR/opencadstudio.ftl
#	locales/ru-RU/opencadstudio.ftl
#	locales/tr-TR/opencadstudio.ftl
#	locales/zh-CN/opencadstudio.ftl
#	locales/zh-TW/opencadstudio.ftl
#	src/locale_catalog.rs
2026-09-19 23:00:18 +03:00
Hakan Seven 377f551b48 Merge pull request #1358 from HakanSeven12/plot/b4-windows-printer-routing
fix(print): send Windows plots to the chosen printer, name the default, report failures

# Conflicts:
#	locales/ar-SA/opencadstudio.ftl
#	locales/bg-BG/opencadstudio.ftl
#	locales/cs-CZ/opencadstudio.ftl
#	locales/de-DE/opencadstudio.ftl
#	locales/el-GR/opencadstudio.ftl
#	locales/en-US/opencadstudio.ftl
#	locales/es-ES/opencadstudio.ftl
#	locales/fi-FI/opencadstudio.ftl
#	locales/fr-FR/opencadstudio.ftl
#	locales/hi-IN/opencadstudio.ftl
#	locales/hu-HU/opencadstudio.ftl
#	locales/it-IT/opencadstudio.ftl
#	locales/ja-JP/opencadstudio.ftl
#	locales/ko-KR/opencadstudio.ftl
#	locales/nl-NL/opencadstudio.ftl
#	locales/pl-PL/opencadstudio.ftl
#	locales/pt-BR/opencadstudio.ftl
#	locales/ru-RU/opencadstudio.ftl
#	locales/tr-TR/opencadstudio.ftl
#	locales/zh-CN/opencadstudio.ftl
#	locales/zh-TW/opencadstudio.ftl
#	src/locale_catalog.rs
2026-09-19 23:00:18 +03:00
Hakan Seven 1c0ef9d7a0 Merge pull request #1353 from HakanSeven12/ui/options-ok-apply-close
feat(options): OK / Apply / Close with a discard guard

# Conflicts:
#	src/app/view/modal.rs
#	src/ui/window/options.rs
2026-09-19 22:59:56 +03:00
Hakan Seven b1080e02ca Merge pull request #1344 from HakanSeven12/plot/b3-psetupin
feat(plot): PSETUPIN, page-setup import and page setup for new layouts
2026-09-19 22:59:36 +03:00
Hakan Seven 879bb70c12 Merge pull request #1343 from HakanSeven12/plot/b2-dialog-options-sysvars
feat(plot): page-setup units, custom scale, dialog options and plot sysvars
2026-09-19 22:59:36 +03:00
Hakan Seven 10827283ee Merge pull request #1339 from mechpanos/snap/line-endpoint-lookup
fix(snap): keep the key-vertex lookup linear and pin the vertex layouts
2026-09-19 22:59:36 +03:00
huanld 8cabadd147 fix(settings): keep isometric drafting session-only
A persisted ISODRAFT flag turned every drawing's crosshair into the
isoplane pair (one vertical, one diagonal arm) on every launch, with no
visible control to switch it back off — F5 (ISOPLANE) only cycles the
plane. Drop the flag when saving and ignore it when an old settings
file still carries it; turning it on stays a per-session choice.
2026-09-19 16:52:25 +07:00
huanld dc23d4073a fix(io): survive locked, shrinking and cloud-placeholder drawings
Opening a drawing that another program or machine holds without read
sharing used to fail with a raw OS error, and the memory-mapped fast
path could kill the process outright: a mapped file that shrinks
mid-parse (a writer saving over it) or a cloud placeholder that cannot
page in raises an in-page exception no Rust code can catch.

Read the DWG through a guarded fast path instead: mmap when possible,
and fall back to one in-memory snapshot read — opened with the most
permissive share mode Windows offers (FILE_SHARE_READ | WRITE |
DELETE) — whenever the map fails or an I/O error surfaces mid-parse.
A snapshot can never fault: a concurrent writer just ends the read
early. Sharing violations (os error 32/33) now answer with a message
that names the file and the remedy, and OneDrive-style placeholder
attributes skip mmap entirely.
2026-09-19 16:52:24 +07:00