refactor(grip): square-only marker set + oriented stretch handles

Phase 1 of bringing the grip vocabulary in line with the standard
CAD convention: drop the per-position-type shape encoding (Diamond
for translate, Circle for parameter) and use a plain square for
every endpoint / vertex / centre grip. The behavioural midpoint vs
vertex distinction stays — it lives on `GripDef::is_midpoint` and
drives `Translate` vs `Absolute` in the grip-edit dispatcher — only
the marker shape collapses.

- `GripShape` keeps `Square`, `Rectangle`, `Triangle`. Diamond /
  Circle are gone.
- `GripDef` gains `dir: Option<[f32; 2]>` — a world-XY direction
  vector consumed by `Rectangle` to orient the box along its
  segment.
- `entities::common` exposes `square_grip`, `center_grip` (same
  square marker, flagged as translate), `rectangle_grip(id, world,
  dir)` for oriented mid-segment handles, and a kept-for-Phase-2
  `triangle_grip`.
- `overlay::GripMarker` / `grips_to_screen[_paper]` thread `dir`
  through to the canvas painter; the Rectangle path rotates the
  box around the grip centre using the world-XY direction (flipping
  the sin for screen-Y).

Every existing `diamond_grip(id, w)` call becomes `center_grip(id,
w)` — the visual change is square-replacing-diamond at line
midpoints / arc midpoints / circle centres / ellipse centres /
viewport / hatch loop centroids / dimension grips / image corners /
multileader / ray / underlay / ole2frame / solid3d.

`LwPolyline` grows a stretch handle on every segment (straight or
arc), drawn as the new oriented rectangle. The grip-edit path
translates both segment endpoints for straight segments and
adjusts the arc bulge from the new midpoint for arc segments.
This commit is contained in:
Hakan Seven 2026-05-29 02:07:34 +03:00
commit 5755c2e130
20 changed files with 184 additions and 133 deletions

View file

@ -7,7 +7,7 @@ use glam::Vec3;
use crate::command::EntityTransform;
use crate::entities::common::{
diamond_grip, edit_prop as edit, parse_f64, ro_prop as ro, square_grip,
center_grip, edit_prop as edit, parse_f64, ro_prop as ro, square_grip,
};
use crate::entities::traits::{Grippable, PropertyEditable, Transformable};
use crate::scene::object::{GripApply, GripDef, PropSection};
@ -594,45 +594,45 @@ impl Grippable for Dimension {
match self {
Dimension::Linear(d) => vec![
square_grip(0, v3(&d.first_point)),
diamond_grip(1, v3(&d.second_point)),
diamond_grip(2, v3(&d.definition_point)),
diamond_grip(3, text),
center_grip(1, v3(&d.second_point)),
center_grip(2, v3(&d.definition_point)),
center_grip(3, text),
],
Dimension::Aligned(d) => vec![
square_grip(0, v3(&d.first_point)),
diamond_grip(1, v3(&d.second_point)),
diamond_grip(2, v3(&d.definition_point)),
diamond_grip(3, text),
center_grip(1, v3(&d.second_point)),
center_grip(2, v3(&d.definition_point)),
center_grip(3, text),
],
Dimension::Radius(d) => vec![
square_grip(0, v3(&d.angle_vertex)),
diamond_grip(1, v3(&d.definition_point)),
diamond_grip(2, text),
center_grip(1, v3(&d.definition_point)),
center_grip(2, text),
],
Dimension::Diameter(d) => vec![
square_grip(0, v3(&d.angle_vertex)),
diamond_grip(1, v3(&d.definition_point)),
diamond_grip(2, text),
center_grip(1, v3(&d.definition_point)),
center_grip(2, text),
],
Dimension::Angular2Ln(d) => vec![
square_grip(0, v3(&d.angle_vertex)),
diamond_grip(1, v3(&d.first_point)),
diamond_grip(2, v3(&d.second_point)),
diamond_grip(3, v3(&d.definition_point)),
diamond_grip(4, text),
center_grip(1, v3(&d.first_point)),
center_grip(2, v3(&d.second_point)),
center_grip(3, v3(&d.definition_point)),
center_grip(4, text),
],
Dimension::Angular3Pt(d) => vec![
square_grip(0, v3(&d.angle_vertex)),
diamond_grip(1, v3(&d.first_point)),
diamond_grip(2, v3(&d.second_point)),
diamond_grip(3, v3(&d.definition_point)),
diamond_grip(4, text),
center_grip(1, v3(&d.first_point)),
center_grip(2, v3(&d.second_point)),
center_grip(3, v3(&d.definition_point)),
center_grip(4, text),
],
Dimension::Ordinate(d) => vec![
square_grip(0, v3(&d.definition_point)),
diamond_grip(1, v3(&d.feature_location)),
diamond_grip(2, v3(&d.leader_endpoint)),
diamond_grip(3, text),
center_grip(1, v3(&d.feature_location)),
center_grip(2, v3(&d.leader_endpoint)),
center_grip(3, text),
],
}
}