Commit Graph
66 Commits
Author SHA1 Message Date
Karim Jerbi 7aafd9c710 refactor(selection): split 31-field SelectionState into five sub-structs
SelectionState now holds view, gesture, input, menu and orbit sub-structs; all 450 access sites updated mechanically with no behavior change. Deletes three write-only dead fields (box_last, box_last_crossing, poly_last_crossing). Hand-rolled clears in commands and dim_viewport route through the new clear methods; bench fixture updated. Full suite: 1976 passed / 0 failed / 25 ignored.
2026-10-06 20:22:04 +01:00
ramox81andClaude Opus 5.5 a735b10b34 feat(field): Formula, Hyperlink and plot fields; local-time field dates, file times and display name; header dates on save
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 12:38:49 +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
Hakan SevenandClaude Opus 5.5 163763c42a fix(xref): follow-ups to the xref attach parity merge
- `XREF <args>` runs whole: probing the bare verb first now opens the
  External References palette, which refreshed every entry and toggled
  the palette before `XREF Reload A` / `XREF ?` ran.
- Update the two tests that encoded the old behaviour: `-XREF ?` prints
  the reference table, and attaching a missing file is rejected.
- Drop the duplicate "Specify On-screen" catalog entry that shadowed the
  translated common key, with its unused ftl keys.
- Move `remove_pipe_symbols`' doc comment back above its function.
- Note in `document_for_save` that resolved xref content stays out.
- Gate the desktop-only preview cap and tab index for wasm.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 15:37:00 +03:00
ramox81andClaude Opus 5.5 6bd55bc32e Xref attach: Attach dialog, reference prompts, and xref drawings other applications can open
Attach External Reference dialog after XATTACH / ATTACH; ATTACH routes
drawings, PDFs and images; placement prompts and messages follow the
reference (presets, Corner/XYZ, nonzero check, existing definition reuse,
missing file, self-reference); name keeps the file's case; overlay and
path type at attach; one undo step for definition and INSERT; -XREF option
prompt and `?` table; XREF opens the palette; ER alias; xref Properties
rows; dependent symbols flagged and remapped and resolved content left out
of the saved file; dialog_ok automation action; localized labels.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 14:44:12 +03:00
Hakan SevenandClaude Opus 5.5 f2d534bf71 fix: review fixes for the Aligned 2Lines placement and DCCONVERT
The 2Lines placement (#1459) wrote the second line's new ends back with
`set_resolved_point`, which was not the inverse of the `resolve_point` it
paired with. `resolve_point` reads polyline vertices in WCS through the
polyline's OCS; the writer put that world point straight into the OCS
vertex, so a mirrored polyline (normal -Z, common in real drawings) had
its vertex flipped, and the closing segment's end marker — which names
vertex 0 on a closed polyline — found no vertex and the placement was
silently dropped. The writer now converts back into the OCS, keeps the
polyline's own elevation, and wraps the closing marker the same way.

The same arm pushed `test_pline_line_then_arc` past the default test
thread's stack: its locals, a cloned entity among them, sat in the frame
of the command-result dispatcher, which is on the stack of every click.
The placement is built out of line and handed over boxed.

Merging #1447 had left nothing setting DIMCONSTRAINT's default to
Diameter; the Dispatch arm #1461 turned into a match now covers it with
Radius and Convert. DCCONVERT's result lines go through the translation
macros.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 13:00:28 +03:00
ramox81andClaude Opus 5 48b8689fc3 Aligned 2Lines: place the second line where the reference leaves it
The second line kept its midpoint and turned around it, so it settled at a
different offset than the reference, which keeps the line's start along the
first line and moves it to the distance the picked point had from it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-23 09:47:56 +03:00
Hakan SevenandClaude Opus 5 889a19c362 Merge pull request #1447 from ramox81:codex/diameter-constraint-parity
#1447 branched from the same commit as #1443 and rewrote the radial
dimensional constraint a second time, so the two designs had to be
reconciled rather than stacked. #1447's is the one kept: it covers
DCRADIUS and DCDIAMETER through one command, places the dimension by the
direction the location was picked in rather than storing a text point,
and names the parameters `radN` / `diaN`. #1443's radial command result,
its entity builder call and its follow-up code are gone; its own
independent work stays — the ribbon's small-button grid and tool
descriptions, the magnitude reading of a negative radius, and the centre
anchor a parameter edit resizes a circle about.

The DIMCONSTRAINT default follows #1443: running DCRADIUS or DCDIAMETER
directly leaves it alone, and the Dispatch arm sets it when DIMCONSTRAINT
is what asked for the command.

The second commit's radial drawing — the dimension line broken around the
text, the elbowed leader, the centre-mark and arrowhead rules — applied to
every radius and diameter dimension, not just a constraint's, and three
layout-parity tests said the old layout was the measured one. It is now
scoped to a dimensional constraint's own dimension, as #1443 scoped its
version, and ordinary radial dimensions draw as they did.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 17:51:16 +03:00
ramox81andClaude Opus 5 368aa69f4e Radial dimensions: text on the line, a short leader when it moves out
The text of a radius or diameter constraint sits on its dimension line,
which breaks around it, and no centre mark is drawn while that line is
there. Text that no longer fits inside moves beside the circle at the end
of a short leader that leaves the rim, elbows and hooks under the text,
with the arrowheads keeping the circle. A dynamic dimension now keeps
only its text at a constant screen size; arrowheads and extension lines
keep the style's size in drawing units.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 17:11:09 +03:00
ramox81andClaude Opus 5 19204d1b2c DCDIAMETER/DCRADIUS: the reference flow with a real radial dimension
The commands ask for the circle or arc themselves, report the measured
size, take a dimension line location and then the value or name and
value, creating a radius or diameter dimension as the constraint's
dynamic dimension with a radN/diaN parameter, refusing a second radial
constraint on the same object and any non-positive value.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 15:21:11 +03:00
Hakan SevenandClaude Opus 5 4bef410abb fix: review fixes for the metric template and the radial constraint
A new drawing (#1441) recorded ISO-25 as the current dimension style by
name only. Every other place that changes it sets the header's handle as
well, and a DWG carries the current style by handle alone, so a saved new
drawing reopened on Standard. The style's handle now comes back from the
helper that adds it.

A radius constraint (#1443) anchored the circle's centre from the shape of
its references — one whole entity — but a single whole reference is also a
line's length, whose start is what stays. The entity decides now.

The two tests that encoded the replaced rules follow them: a negative
radius validates by its magnitude, as a negative distance already did, and
only zero is refused; a new drawing's dimension text reads at ISO-25's
comma separator.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 13:46:49 +03:00
ramox81andClaude Fable 5.1 aab42e2aa9 DCRADIUS: reference radial dimensional constraint with a dynamic radial dimension
Select arc or circle / Dimension text / dimension line location / value or
name prompts with a radN parameter, invalid-selection, miss, duplicate and
invalid-expression messages, negative values as magnitudes, a dynamic radial
dimension on the constraints layer drawn as the reference does (mid-radius
text on the center-to-rim line, no hook, no center mark, one text grip), the
stored text position following the radius, center-anchored resizing, the
Properties title and Constraint section, DIMCONSTRAINT's Radius default,
the small-button Dimensional ribbon grid and tooltip descriptions.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-22 13:09:47 +03:00
ramox81andClaude Fable 5.1 b435af64cd Dynamic angular constraint: screen-size extension lines, reference grips, Properties parity
Dynamic dimensions carry DIMEXO/DIMEXE/DIMASZ overrides in text-height
ratios, a two-line angular dimension draws extension lines only beyond
its sides, a selected dynamic angle shows triangle grips at the arc ends
with squares at the arc point and text, and the constraint dimension's
Properties follow the reference: kind titles, General before Constraint,
angular-precision Value and Measurement, drawn text position, reference
row order for Fit, Primary Units and Tolerances, and text/dimension line
alignment rows reading On as the aligned state.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-22 11:58:59 +03:00
ramox81andClaude Fable 5.1 160930b99a Angular dimension drawing: ray-based three-point frame, text beside the arc
Three-point angular dimensions take their sweep from the two rays and the
arc point (extension lines follow their own rays, straight and reflex
angles draw), dynamic angular dimensions store no text point so DIMTAD
places the text beside an unbroken arc, and dynamic dimensions carry a
DIMGAP override of a quarter text height.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-22 10:41:52 +03:00
ramox81andClaude Fable 5.1 4ad4041858 Angular dimensional constraint: reference flow, dynamic angular dimension, angN parameters
DCANGULAR picks two lines, an arc or three points, takes the dimension
line location to choose the sector and the value or name, and creates the
dynamic two-line or three-point angular dimension driven by an angN
parameter. Reference messages for invalid, repeated and parallel sides,
existing names and invalid names; angle values display within one turn at
the angular precision; the first side (or vertex and first point) stays
when the value changes; the ribbon Dimensional panel follows the reference
order.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-22 10:02:40 +03:00
Karim Jerbi 4432f633e7 perf(glyphs): memoize constraint-glyph placements behind constraints_epoch
Placements (entity lookups, intersections, String labels, projections)
recomputed per view() and per mouse-move hit-test, with overlay re-clones
and 2-3x offset recomputes. New constraints_epoch bumped on every set
mutation/visibility/undo/DWG-load (plus new set_constraint_enabled API);
single-slot Arc<[GlyphEntry]> memo on an 11-field key (hover/selection
excluded); overlay de-cloned/de-duped to the single geometry source;
hit paths reuse the cache.

Tests:
- cached_glyph_placements_hit_returns_same_arc: same-key Arc identity
- cached_glyph_placements_invalidated_by_metadata_edit: edit + selection change yield new Arc
- glyph_hit_test_entries_matches_precomputed_boxes: shared hit-test helper

Bench (cargo bench glyph, 60 constraints): 8.18us -> 0.05-0.15us (~55x).
A/B reference deleted.
2026-09-21 22:52:47 +01:00
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 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 <noreply@anthropic.com>
2026-09-21 22:21:19 +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 <noreply@anthropic.com>
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 <noreply@anthropic.com>
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 <noreply@anthropic.com>
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 <noreply@anthropic.com>
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 <noreply@anthropic.com>
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 <noreply@anthropic.com>
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 <noreply@anthropic.com>
2026-09-21 11:53:19 +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 <noreply@anthropic.com>
2026-09-21 09:18:40 +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 <noreply@anthropic.com>
2026-09-20 21:12:07 +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
ramox81andClaude Fable 5.1 b24d04d620 Hover an object-mode Horizontal/Vertical glyph without endpoint markers
The reference highlights only the object when its Horizontal/Vertical bar
is hovered; the extra cross markers at the line's ends were ours alone.
Point-mode (2Points) relations keep marking their two points.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-18 23:46:26 +03:00
ramox81andClaude Fable 5.1 3492ae32eb Show the Equal glyph on every object of the relation
The reference places an Equal bar on each object it joins; one glyph on
the first object only left the follower unmarked.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-18 23:32:42 +03:00
ramox81andClaude Fable 5.1 8520ee45e8 Bring the Equal constraint to reference parity
Equal was applied through a generic gather-then-apply flow and, with the
default size-retaining solve mode, never changed anything: the solver
held both sizes and the relation could not be met. Now:

- GCEQUAL joins ECONSTRAINT and GEOMCONSTRAINT Equal; both objects are
  picked inside the command (`Select first object or [Multiple]:`,
  `Select second object:`; Multiple gathers `Select objects to make equal
  to the first:`), a selection made beforehand is not used, a miss says
  `No object found.` and re-asks, an unsupported object or the same object
  twice is reported and re-asked, a repeat is refused.
- The follower is resized in place before the relation is added: a line or
  straight polyline segment keeps its start and direction and its end
  moves to the first object's length; a circle or arc keeps its center and
  takes the radius.
- During edits the side that is not being edited follows the same rule:
  its size is not retained, its start (or center) and other vertices are
  held and its direction kept, so only its length or radius changes; a
  chain of Equal relations follows along.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-18 22:56:31 +03:00
ramox81andClaude Fable 5.1 1f0b888833 Turn an object onto its Horizontal/Vertical axis before solving
The solver cannot start from an axis lying exactly across the datum: the
distance and direction equations are singular there, so a horizontal line,
a text at 0 degrees or an ellipse whose major axis is horizontal stayed
put when Vertical was applied. The command now turns the object about its
anchor (line start, picked segment's first vertex, text insertion point,
ellipse center) onto the axis first — a polyline moves only the segment's
end vertex — and lets the constraint hold what already fits. Two points on
one entity follow the same rule about the first point.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-18 22:40:39 +03:00
Hakan Seven 3ba7b38934 Merge pull request #1357 from ramox81/codex/vertical-constraint-parity
Match Vertical geometric constraint behavior

# Conflicts:
#	src/app/commands/draw.rs
#	src/scene/parametric_constraints.rs
#	src/ui/overlay.rs
2026-09-18 18:54:12 +03:00
Hakan Seven 7ef4e9f336 Merge pull request #1356 from ramox81/codex/fixed-constraint-parity
Match Fix geometric constraint behavior

# Conflicts:
#	src/scene/parametric_constraints.rs
#	src/scene/parametric_solve.rs
2026-09-18 18:53:18 +03:00
ramox81andClaude Fable 5.1 26e458d6f7 Match Vertical geometric constraint behavior
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 <noreply@anthropic.com>
2026-09-18 18:19:49 +03:00
ramox81andClaude Fable 5.1 45f3088a89 Draw the Fix constraint bar glyph as a padlock
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 <noreply@anthropic.com>
2026-09-18 16:55:11 +03:00
ramox81andClaude Fable 5.1 f998b59193 Match Fix geometric constraint behavior
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 <noreply@anthropic.com>
2026-09-18 15:38:33 +03:00
ramox81 9aadc97c11 feat: complete symmetric constraint behavior 2026-09-18 10:27:00 +03:00
Hakan Seven f0a3336302 fix: retain horizontal constraint axes 2026-09-17 17:55:56 +03:00
Hakan Seven f9c59503f0 Merge pull request #1334 from ramox81/codex/horizontal-constraint-parity 2026-09-17 17:39:44 +03:00
Hakan Seven 16c417f81d Merge pull request #1332 from ramox81/codex/concentric-constraint-parity
# Conflicts:
#	src/entities/arc.rs
#	src/entities/ellipse.rs
#	src/modules/parametric/mod.rs
#	src/scene/parametric_solve.rs
#	src/ui/overlay.rs
2026-09-17 17:24:14 +03:00
ramox81 059906f347 Fix horizontal geometric constraint behavior 2026-09-17 17:18:59 +03:00
ramox81 d9f3d71342 Fix Concentric build integration 2026-09-17 16:21:39 +03:00
ramox81 a6a70420c4 fix: align concentric constraint behavior 2026-09-17 15:31:26 +03:00
ramox81 6260723937 Revert "Match Smooth connected-endpoint workflow"
This reverts commit dfa75f45b5.
2026-09-17 13:50:15 +03:00
ramox81 dfa75f45b5 Match Smooth connected-endpoint workflow 2026-09-17 13:37:25 +03:00
ramox81 7c6665153c Complete Smooth G2 constraint workflow 2026-09-17 12:39:23 +03:00
ramox81 60bfc88b39 Fix ordered perpendicular constraint behavior 2026-09-16 18:21:16 +03:00