2026-03-22 14:56:27 +03:00
|
|
|
|
use acadrust::entities::{HooklineDirection, Leader, LeaderCreationType, LeaderPathType};
|
|
|
|
|
|
use acadrust::Entity;
|
|
|
|
|
|
use glam::Vec3;
|
|
|
|
|
|
|
|
|
|
|
|
use crate::command::EntityTransform;
|
feat(properties): rework Text/MText/MLeader/Leader panels to standard layout
Match the entity Properties panels to the standard CAD layout and
web-verified behaviour:
- Text: combined Justify (horizontal x vertical) dropdown; Position and
Text-alignment rows become editable/grayed by justification; drop the
Annotative-scale row.
- MText: combined Justify; editable Direction, Line space distance
(back-solves the factor) and Line space style; Defined width/height
gated on column mode.
- MLeader: regrouped to match the palette - drop the Leader Structure
group (fold landing rows into Leaders), gate Text vs Block on content
type, full 9-value attachment label set, resolve handle-backed rows
(style, text style, arrowhead, linetype) to names.
- Leader: Lines & Arrows / Text / Fit are resolved from the dimension
style (arrowhead, arrow size, dim-line lineweight/colour, text gap,
vertical text pos, overall scale); Current Vertex navigator; combined
Type; Geometry group after General; no 3D-Visualisation group.
- General: rename "LT Scale" to "Linetype scale"; show ByLayer
transparency by name. Add shared num_prop helper for conditionally
editable numeric rows.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 18:01:44 +03:00
|
|
|
|
use crate::entities::common::{
|
|
|
|
|
|
center_grip, edit_prop as edit, ro_prop as ro, square_grip, stepper_prop as stepper,
|
|
|
|
|
|
};
|
2026-06-11 00:04:37 +03:00
|
|
|
|
use crate::entities::traits::TruckConvertible;
|
2026-06-16 11:33:46 +03:00
|
|
|
|
use crate::scene::convert::acad_to_truck::{TruckEntity, TruckObject};
|
|
|
|
|
|
use crate::scene::model::object::{GripApply, GripDef, PropSection, PropValue, Property};
|
|
|
|
|
|
use crate::scene::model::wire_model::TangentGeom;
|
2026-03-22 14:56:27 +03:00
|
|
|
|
|
|
|
|
|
|
// ── TruckConvertible (used for snap/grip key-vertices) ─────────────────────
|
|
|
|
|
|
|
|
|
|
|
|
fn to_truck(leader: &Leader) -> TruckEntity {
|
|
|
|
|
|
let verts = &leader.vertices;
|
2026-05-12 23:47:40 +03:00
|
|
|
|
let nan = [f64::NAN; 3];
|
|
|
|
|
|
let p3 = |v: &acadrust::types::Vector3| -> [f64; 3] { [v.x, v.y, v.z] };
|
2026-06-11 00:04:37 +03:00
|
|
|
|
let p3f = |v: &acadrust::types::Vector3| -> [f32; 3] { [v.x as f32, v.y as f32, v.z as f32] };
|
2026-03-22 14:56:27 +03:00
|
|
|
|
|
2026-05-12 23:47:40 +03:00
|
|
|
|
let mut points: Vec<[f64; 3]> = Vec::new();
|
2026-03-22 14:56:27 +03:00
|
|
|
|
let mut tangents: Vec<TangentGeom> = Vec::new();
|
2026-05-12 23:47:40 +03:00
|
|
|
|
let mut key_verts: Vec<[f64; 3]> = Vec::new();
|
2026-03-22 14:56:27 +03:00
|
|
|
|
|
|
|
|
|
|
// Main leader path
|
|
|
|
|
|
for v in verts {
|
|
|
|
|
|
points.push(p3(v));
|
|
|
|
|
|
key_verts.push(p3(v));
|
|
|
|
|
|
}
|
|
|
|
|
|
for i in 0..verts.len().saturating_sub(1) {
|
2026-05-12 23:47:40 +03:00
|
|
|
|
// TangentGeom uses f32 (UI-only); cast at construction.
|
2026-05-12 10:36:15 +03:00
|
|
|
|
tangents.push(TangentGeom::Line {
|
2026-05-12 23:47:40 +03:00
|
|
|
|
p1: p3f(&verts[i]),
|
|
|
|
|
|
p2: p3f(&verts[i + 1]),
|
2026-05-12 10:36:15 +03:00
|
|
|
|
});
|
2026-03-22 14:56:27 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Arrowhead at vertex[0]
|
|
|
|
|
|
if leader.arrow_enabled && verts.len() >= 2 {
|
|
|
|
|
|
let tip = &verts[0];
|
|
|
|
|
|
let next = &verts[1];
|
2026-05-12 23:47:40 +03:00
|
|
|
|
let dx = next.x - tip.x;
|
|
|
|
|
|
let dy = next.y - tip.y;
|
2026-03-22 14:56:27 +03:00
|
|
|
|
let len = (dx * dx + dy * dy).sqrt().max(1e-9);
|
|
|
|
|
|
let (dx, dy) = (dx / len, dy / len);
|
2026-06-03 16:17:29 +03:00
|
|
|
|
// Arrowhead sized to the text height, matching the MLEADER arrowhead.
|
|
|
|
|
|
let sz = (leader.text_height).max(1.0);
|
2026-05-12 23:47:40 +03:00
|
|
|
|
let a = std::f64::consts::PI / 6.0;
|
2026-03-22 14:56:27 +03:00
|
|
|
|
let (s, c) = a.sin_cos();
|
|
|
|
|
|
let tip_f = p3(tip);
|
|
|
|
|
|
points.push(nan);
|
2026-05-12 10:36:15 +03:00
|
|
|
|
points.push([
|
|
|
|
|
|
tip_f[0] + (dx * c - dy * s) * sz,
|
|
|
|
|
|
tip_f[1] + (dx * s + dy * c) * sz,
|
|
|
|
|
|
tip_f[2],
|
|
|
|
|
|
]);
|
2026-03-22 14:56:27 +03:00
|
|
|
|
points.push(tip_f);
|
2026-05-12 10:36:15 +03:00
|
|
|
|
points.push([
|
|
|
|
|
|
tip_f[0] + (dx * c + dy * s) * sz,
|
|
|
|
|
|
tip_f[1] + (-dx * s + dy * c) * sz,
|
|
|
|
|
|
tip_f[2],
|
|
|
|
|
|
]);
|
2026-03-22 14:56:27 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Landing line at last vertex
|
|
|
|
|
|
if leader.hookline_enabled && verts.len() >= 2 {
|
|
|
|
|
|
let last = verts.last().unwrap();
|
|
|
|
|
|
let prev = &verts[verts.len() - 2];
|
2026-06-22 18:18:35 +03:00
|
|
|
|
// Landing runs along the leader's horizontal direction (UCS X for
|
|
|
|
|
|
// UCS-placed leaders, world X otherwise), on the side the leader
|
|
|
|
|
|
// approaches from.
|
|
|
|
|
|
let (hx, hy) = {
|
|
|
|
|
|
let h = leader.horizontal_direction;
|
|
|
|
|
|
let l = (h.x * h.x + h.y * h.y).sqrt();
|
|
|
|
|
|
if l > 1e-9 {
|
|
|
|
|
|
(h.x / l, h.y / l)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
(1.0, 0.0)
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
let sign = if (last.x - prev.x) * hx + (last.y - prev.y) * hy >= 0.0 {
|
2026-06-11 00:04:37 +03:00
|
|
|
|
1.0_f64
|
|
|
|
|
|
} else {
|
|
|
|
|
|
-1.0_f64
|
|
|
|
|
|
};
|
2026-05-12 23:47:40 +03:00
|
|
|
|
let len = leader.text_height * 1.5;
|
2026-03-22 14:56:27 +03:00
|
|
|
|
let last_f = p3(last);
|
|
|
|
|
|
points.push(nan);
|
|
|
|
|
|
points.push(last_f);
|
2026-06-22 18:18:35 +03:00
|
|
|
|
points.push([
|
|
|
|
|
|
last_f[0] + sign * len * hx,
|
|
|
|
|
|
last_f[1] + sign * len * hy,
|
|
|
|
|
|
last_f[2],
|
|
|
|
|
|
]);
|
2026-03-22 14:56:27 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TruckEntity {
|
|
|
|
|
|
object: TruckObject::Lines(points),
|
|
|
|
|
|
snap_pts: vec![],
|
|
|
|
|
|
tangent_geoms: tangents,
|
|
|
|
|
|
key_vertices: key_verts,
|
2026-05-06 23:24:26 +03:00
|
|
|
|
fill_tris: vec![],
|
2026-03-22 14:56:27 +03:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ── Grips ──────────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
|
|
fn grips(leader: &Leader) -> Vec<GripDef> {
|
|
|
|
|
|
let n = leader.vertices.len();
|
|
|
|
|
|
let mut grips: Vec<GripDef> = leader
|
|
|
|
|
|
.vertices
|
|
|
|
|
|
.iter()
|
|
|
|
|
|
.enumerate()
|
2026-06-11 00:04:37 +03:00
|
|
|
|
.map(|(i, v)| square_grip(i, glam::DVec3::new(v.x, v.y, v.z)))
|
2026-03-22 14:56:27 +03:00
|
|
|
|
.collect();
|
|
|
|
|
|
|
|
|
|
|
|
if n >= 2 {
|
2026-06-11 00:04:37 +03:00
|
|
|
|
let sum = leader.vertices.iter().fold(glam::DVec3::ZERO, |acc, v| {
|
|
|
|
|
|
acc + glam::DVec3::new(v.x, v.y, v.z)
|
2026-03-22 14:56:27 +03:00
|
|
|
|
});
|
2026-06-11 00:04:37 +03:00
|
|
|
|
grips.push(center_grip(n, sum / n as f64));
|
2026-03-22 14:56:27 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
grips
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn apply_grip(leader: &mut Leader, grip_id: usize, apply: GripApply) {
|
|
|
|
|
|
let n = leader.vertices.len();
|
|
|
|
|
|
if grip_id < n {
|
|
|
|
|
|
if let Some(v) = leader.vertices.get_mut(grip_id) {
|
|
|
|
|
|
match apply {
|
|
|
|
|
|
GripApply::Absolute(p) => {
|
|
|
|
|
|
v.x = p.x as f64;
|
|
|
|
|
|
v.y = p.y as f64;
|
|
|
|
|
|
v.z = p.z as f64;
|
|
|
|
|
|
}
|
|
|
|
|
|
GripApply::Translate(d) => {
|
|
|
|
|
|
v.x += d.x as f64;
|
|
|
|
|
|
v.y += d.y as f64;
|
|
|
|
|
|
v.z += d.z as f64;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
} else if let GripApply::Translate(d) = apply {
|
|
|
|
|
|
leader.translate(acadrust::types::Vector3::new(
|
2026-05-12 10:36:15 +03:00
|
|
|
|
d.x as f64, d.y as f64, d.z as f64,
|
2026-03-22 14:56:27 +03:00
|
|
|
|
));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ── Properties ─────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
|
|
fn choice_prop(label: &str, field: &'static str, selected: &str, options: &[&str]) -> Property {
|
|
|
|
|
|
Property {
|
|
|
|
|
|
label: label.into(),
|
|
|
|
|
|
field,
|
|
|
|
|
|
value: PropValue::Choice {
|
|
|
|
|
|
selected: selected.to_string(),
|
|
|
|
|
|
options: options.iter().map(|s| s.to_string()).collect(),
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
feat(properties): rework Text/MText/MLeader/Leader panels to standard layout
Match the entity Properties panels to the standard CAD layout and
web-verified behaviour:
- Text: combined Justify (horizontal x vertical) dropdown; Position and
Text-alignment rows become editable/grayed by justification; drop the
Annotative-scale row.
- MText: combined Justify; editable Direction, Line space distance
(back-solves the factor) and Line space style; Defined width/height
gated on column mode.
- MLeader: regrouped to match the palette - drop the Leader Structure
group (fold landing rows into Leaders), gate Text vs Block on content
type, full 9-value attachment label set, resolve handle-backed rows
(style, text style, arrowhead, linetype) to names.
- Leader: Lines & Arrows / Text / Fit are resolved from the dimension
style (arrowhead, arrow size, dim-line lineweight/colour, text gap,
vertical text pos, overall scale); Current Vertex navigator; combined
Type; Geometry group after General; no 3D-Visualisation group.
- General: rename "LT Scale" to "Linetype scale"; show ByLayer
transparency by name. Add shared num_prop helper for conditionally
editable numeric rows.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 18:01:44 +03:00
|
|
|
|
/// Combined path/arrow "Type" value (path shape × arrowhead flag).
|
|
|
|
|
|
fn leader_type_str(path: &LeaderPathType, arrow: bool) -> &'static str {
|
|
|
|
|
|
match (path, arrow) {
|
|
|
|
|
|
(LeaderPathType::StraightLine, true) => "Line with arrow",
|
|
|
|
|
|
(LeaderPathType::StraightLine, false) => "Line without arrow",
|
|
|
|
|
|
(LeaderPathType::Spline, true) => "Spline with arrow",
|
|
|
|
|
|
(LeaderPathType::Spline, false) => "Spline without arrow",
|
feat(properties): conform entity property groups to PROPERTIES.md
Rewrite each entity's property builder to the per-entity group/row spec:
the correct sections (Geometry, Misc, Text, Pattern, Lines & Arrows, Leaders,
Block, …) with the spec's rows and real computed values — Diameter,
Circumference, Area, Delta X/Y/Z, Angle, Total angle, Arc length, Radius ratio,
etc. — plus apply routing for the editable rows.
Covers ~26 entities (Line, Circle, Arc, Point, Ellipse, Spline, polylines,
Ray/XLine, Insert, Text, MText, Hatch, Leader, MultiLeader, Tolerance, Solid,
Solid3D/Region/Body, meshes, MLine, Raster/Wipeout, Underlay, Table, Viewport,
Attribute, OLE). The 3D Visualization/Material group and the full Dimension
spec are deferred (they need document access for material/dimstyle name
resolution). Rows whose data is not in the pinned acadrust revision are shown
as empty placeholders, to be filled when the dependency is bumped.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 23:03:18 +03:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-02 22:46:19 +03:00
|
|
|
|
fn properties(leader: &Leader) -> Vec<PropSection> {
|
2026-03-22 14:56:27 +03:00
|
|
|
|
let n = leader.vertices.len();
|
feat(properties): rework Text/MText/MLeader/Leader panels to standard layout
Match the entity Properties panels to the standard CAD layout and
web-verified behaviour:
- Text: combined Justify (horizontal x vertical) dropdown; Position and
Text-alignment rows become editable/grayed by justification; drop the
Annotative-scale row.
- MText: combined Justify; editable Direction, Line space distance
(back-solves the factor) and Line space style; Defined width/height
gated on column mode.
- MLeader: regrouped to match the palette - drop the Leader Structure
group (fold landing rows into Leaders), gate Text vs Block on content
type, full 9-value attachment label set, resolve handle-backed rows
(style, text style, arrowhead, linetype) to names.
- Leader: Lines & Arrows / Text / Fit are resolved from the dimension
style (arrowhead, arrow size, dim-line lineweight/colour, text gap,
vertical text pos, overall scale); Current Vertex navigator; combined
Type; Geometry group after General; no 3D-Visualisation group.
- General: rename "LT Scale" to "Linetype scale"; show ByLayer
transparency by name. Add shared num_prop helper for conditionally
editable numeric rows.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 18:01:44 +03:00
|
|
|
|
// The panel's Current Vertex focus, clamped to this leader's range.
|
|
|
|
|
|
let vi = if n == 0 {
|
|
|
|
|
|
0
|
|
|
|
|
|
} else {
|
|
|
|
|
|
crate::scene::view::dispatch::prop_current_vertex().min(n - 1)
|
|
|
|
|
|
};
|
|
|
|
|
|
let vertex_label = if n == 0 {
|
|
|
|
|
|
"—".to_string()
|
|
|
|
|
|
} else {
|
|
|
|
|
|
format!("{} / {}", vi + 1, n)
|
|
|
|
|
|
};
|
feat(properties): conform entity property groups to PROPERTIES.md
Rewrite each entity's property builder to the per-entity group/row spec:
the correct sections (Geometry, Misc, Text, Pattern, Lines & Arrows, Leaders,
Block, …) with the spec's rows and real computed values — Diameter,
Circumference, Area, Delta X/Y/Z, Angle, Total angle, Arc length, Radius ratio,
etc. — plus apply routing for the editable rows.
Covers ~26 entities (Line, Circle, Arc, Point, Ellipse, Spline, polylines,
Ray/XLine, Insert, Text, MText, Hatch, Leader, MultiLeader, Tolerance, Solid,
Solid3D/Region/Body, meshes, MLine, Raster/Wipeout, Underlay, Table, Viewport,
Attribute, OLE). The 3D Visualization/Material group and the full Dimension
spec are deferred (they need document access for material/dimstyle name
resolution). Rows whose data is not in the pinned acadrust revision are shown
as empty placeholders, to be filled when the dependency is bumped.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 23:03:18 +03:00
|
|
|
|
|
feat(properties): rework Text/MText/MLeader/Leader panels to standard layout
Match the entity Properties panels to the standard CAD layout and
web-verified behaviour:
- Text: combined Justify (horizontal x vertical) dropdown; Position and
Text-alignment rows become editable/grayed by justification; drop the
Annotative-scale row.
- MText: combined Justify; editable Direction, Line space distance
(back-solves the factor) and Line space style; Defined width/height
gated on column mode.
- MLeader: regrouped to match the palette - drop the Leader Structure
group (fold landing rows into Leaders), gate Text vs Block on content
type, full 9-value attachment label set, resolve handle-backed rows
(style, text style, arrowhead, linetype) to names.
- Leader: Lines & Arrows / Text / Fit are resolved from the dimension
style (arrowhead, arrow size, dim-line lineweight/colour, text gap,
vertical text pos, overall scale); Current Vertex navigator; combined
Type; Geometry group after General; no 3D-Visualisation group.
- General: rename "LT Scale" to "Linetype scale"; show ByLayer
transparency by name. Add shared num_prop helper for conditionally
editable numeric rows.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 18:01:44 +03:00
|
|
|
|
// Geometry sits right after General — a leader owns editable path vertices,
|
|
|
|
|
|
// navigated one at a time by the Current Vertex spinner.
|
|
|
|
|
|
let mut geometry = vec![stepper("Current Vertex", "current_vertex", vertex_label)];
|
|
|
|
|
|
if let Some(v) = leader.vertices.get(vi) {
|
|
|
|
|
|
geometry.push(edit("Vertex X", "vertex_x", v.x));
|
|
|
|
|
|
geometry.push(edit("Vertex Y", "vertex_y", v.y));
|
|
|
|
|
|
geometry.push(edit("Vertex Z", "vertex_z", v.z));
|
|
|
|
|
|
} else {
|
|
|
|
|
|
geometry.push(ro("Vertex X", "vertex_x", String::new()));
|
|
|
|
|
|
geometry.push(ro("Vertex Y", "vertex_y", String::new()));
|
|
|
|
|
|
geometry.push(ro("Vertex Z", "vertex_z", String::new()));
|
|
|
|
|
|
}
|
feat(properties): conform entity property groups to PROPERTIES.md
Rewrite each entity's property builder to the per-entity group/row spec:
the correct sections (Geometry, Misc, Text, Pattern, Lines & Arrows, Leaders,
Block, …) with the spec's rows and real computed values — Diameter,
Circumference, Area, Delta X/Y/Z, Angle, Total angle, Arc length, Radius ratio,
etc. — plus apply routing for the editable rows.
Covers ~26 entities (Line, Circle, Arc, Point, Ellipse, Spline, polylines,
Ray/XLine, Insert, Text, MText, Hatch, Leader, MultiLeader, Tolerance, Solid,
Solid3D/Region/Body, meshes, MLine, Raster/Wipeout, Underlay, Table, Viewport,
Attribute, OLE). The 3D Visualization/Material group and the full Dimension
spec are deferred (they need document access for material/dimstyle name
resolution). Rows whose data is not in the pinned acadrust revision are shown
as empty placeholders, to be filled when the dependency is bumped.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 23:03:18 +03:00
|
|
|
|
|
feat(properties): rework Text/MText/MLeader/Leader panels to standard layout
Match the entity Properties panels to the standard CAD layout and
web-verified behaviour:
- Text: combined Justify (horizontal x vertical) dropdown; Position and
Text-alignment rows become editable/grayed by justification; drop the
Annotative-scale row.
- MText: combined Justify; editable Direction, Line space distance
(back-solves the factor) and Line space style; Defined width/height
gated on column mode.
- MLeader: regrouped to match the palette - drop the Leader Structure
group (fold landing rows into Leaders), gate Text vs Block on content
type, full 9-value attachment label set, resolve handle-backed rows
(style, text style, arrowhead, linetype) to names.
- Leader: Lines & Arrows / Text / Fit are resolved from the dimension
style (arrowhead, arrow size, dim-line lineweight/colour, text gap,
vertical text pos, overall scale); Current Vertex navigator; combined
Type; Geometry group after General; no 3D-Visualisation group.
- General: rename "LT Scale" to "Linetype scale"; show ByLayer
transparency by name. Add shared num_prop helper for conditionally
editable numeric rows.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 18:01:44 +03:00
|
|
|
|
// Misc: Dim style (upgraded to a dropdown by the panel builder), the
|
|
|
|
|
|
// combined path/arrow Type, and annotative state (from the dim style).
|
feat(properties): conform entity property groups to PROPERTIES.md
Rewrite each entity's property builder to the per-entity group/row spec:
the correct sections (Geometry, Misc, Text, Pattern, Lines & Arrows, Leaders,
Block, …) with the spec's rows and real computed values — Diameter,
Circumference, Area, Delta X/Y/Z, Angle, Total angle, Arc length, Radius ratio,
etc. — plus apply routing for the editable rows.
Covers ~26 entities (Line, Circle, Arc, Point, Ellipse, Spline, polylines,
Ray/XLine, Insert, Text, MText, Hatch, Leader, MultiLeader, Tolerance, Solid,
Solid3D/Region/Body, meshes, MLine, Raster/Wipeout, Underlay, Table, Viewport,
Attribute, OLE). The 3D Visualization/Material group and the full Dimension
spec are deferred (they need document access for material/dimstyle name
resolution). Rows whose data is not in the pinned acadrust revision are shown
as empty placeholders, to be filled when the dependency is bumped.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 23:03:18 +03:00
|
|
|
|
let misc = vec![
|
|
|
|
|
|
Property {
|
|
|
|
|
|
label: "Dim style".into(),
|
|
|
|
|
|
field: "dimension_style",
|
|
|
|
|
|
value: PropValue::EditText(leader.dimension_style.clone()),
|
|
|
|
|
|
},
|
feat(properties): rework Text/MText/MLeader/Leader panels to standard layout
Match the entity Properties panels to the standard CAD layout and
web-verified behaviour:
- Text: combined Justify (horizontal x vertical) dropdown; Position and
Text-alignment rows become editable/grayed by justification; drop the
Annotative-scale row.
- MText: combined Justify; editable Direction, Line space distance
(back-solves the factor) and Line space style; Defined width/height
gated on column mode.
- MLeader: regrouped to match the palette - drop the Leader Structure
group (fold landing rows into Leaders), gate Text vs Block on content
type, full 9-value attachment label set, resolve handle-backed rows
(style, text style, arrowhead, linetype) to names.
- Leader: Lines & Arrows / Text / Fit are resolved from the dimension
style (arrowhead, arrow size, dim-line lineweight/colour, text gap,
vertical text pos, overall scale); Current Vertex navigator; combined
Type; Geometry group after General; no 3D-Visualisation group.
- General: rename "LT Scale" to "Linetype scale"; show ByLayer
transparency by name. Add shared num_prop helper for conditionally
editable numeric rows.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 18:01:44 +03:00
|
|
|
|
choice_prop(
|
|
|
|
|
|
"Type",
|
|
|
|
|
|
"leader_type",
|
|
|
|
|
|
leader_type_str(&leader.path_type, leader.arrow_enabled),
|
|
|
|
|
|
&[
|
|
|
|
|
|
"Line with arrow",
|
|
|
|
|
|
"Line without arrow",
|
|
|
|
|
|
"Spline with arrow",
|
|
|
|
|
|
"Spline without arrow",
|
|
|
|
|
|
],
|
|
|
|
|
|
),
|
|
|
|
|
|
ro("Annotative", "annotative", "No"),
|
feat(properties): conform entity property groups to PROPERTIES.md
Rewrite each entity's property builder to the per-entity group/row spec:
the correct sections (Geometry, Misc, Text, Pattern, Lines & Arrows, Leaders,
Block, …) with the spec's rows and real computed values — Diameter,
Circumference, Area, Delta X/Y/Z, Angle, Total angle, Arc length, Radius ratio,
etc. — plus apply routing for the editable rows.
Covers ~26 entities (Line, Circle, Arc, Point, Ellipse, Spline, polylines,
Ray/XLine, Insert, Text, MText, Hatch, Leader, MultiLeader, Tolerance, Solid,
Solid3D/Region/Body, meshes, MLine, Raster/Wipeout, Underlay, Table, Viewport,
Attribute, OLE). The 3D Visualization/Material group and the full Dimension
spec are deferred (they need document access for material/dimstyle name
resolution). Rows whose data is not in the pinned acadrust revision are shown
as empty placeholders, to be filled when the dependency is bumped.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 23:03:18 +03:00
|
|
|
|
];
|
|
|
|
|
|
|
feat(properties): rework Text/MText/MLeader/Leader panels to standard layout
Match the entity Properties panels to the standard CAD layout and
web-verified behaviour:
- Text: combined Justify (horizontal x vertical) dropdown; Position and
Text-alignment rows become editable/grayed by justification; drop the
Annotative-scale row.
- MText: combined Justify; editable Direction, Line space distance
(back-solves the factor) and Line space style; Defined width/height
gated on column mode.
- MLeader: regrouped to match the palette - drop the Leader Structure
group (fold landing rows into Leaders), gate Text vs Block on content
type, full 9-value attachment label set, resolve handle-backed rows
(style, text style, arrowhead, linetype) to names.
- Leader: Lines & Arrows / Text / Fit are resolved from the dimension
style (arrowhead, arrow size, dim-line lineweight/colour, text gap,
vertical text pos, overall scale); Current Vertex navigator; combined
Type; Geometry group after General; no 3D-Visualisation group.
- General: rename "LT Scale" to "Linetype scale"; show ByLayer
transparency by name. Add shared num_prop helper for conditionally
editable numeric rows.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 18:01:44 +03:00
|
|
|
|
// Lines & Arrows / Text / Fit are dimension-style-derived; the panel builder
|
|
|
|
|
|
// resolves leader.dimension_style and fills these values from the DimStyle.
|
feat(properties): conform entity property groups to PROPERTIES.md
Rewrite each entity's property builder to the per-entity group/row spec:
the correct sections (Geometry, Misc, Text, Pattern, Lines & Arrows, Leaders,
Block, …) with the spec's rows and real computed values — Diameter,
Circumference, Area, Delta X/Y/Z, Angle, Total angle, Arc length, Radius ratio,
etc. — plus apply routing for the editable rows.
Covers ~26 entities (Line, Circle, Arc, Point, Ellipse, Spline, polylines,
Ray/XLine, Insert, Text, MText, Hatch, Leader, MultiLeader, Tolerance, Solid,
Solid3D/Region/Body, meshes, MLine, Raster/Wipeout, Underlay, Table, Viewport,
Attribute, OLE). The 3D Visualization/Material group and the full Dimension
spec are deferred (they need document access for material/dimstyle name
resolution). Rows whose data is not in the pinned acadrust revision are shown
as empty placeholders, to be filled when the dependency is bumped.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 23:03:18 +03:00
|
|
|
|
let lines_arrows = vec![
|
feat(properties): rework Text/MText/MLeader/Leader panels to standard layout
Match the entity Properties panels to the standard CAD layout and
web-verified behaviour:
- Text: combined Justify (horizontal x vertical) dropdown; Position and
Text-alignment rows become editable/grayed by justification; drop the
Annotative-scale row.
- MText: combined Justify; editable Direction, Line space distance
(back-solves the factor) and Line space style; Defined width/height
gated on column mode.
- MLeader: regrouped to match the palette - drop the Leader Structure
group (fold landing rows into Leaders), gate Text vs Block on content
type, full 9-value attachment label set, resolve handle-backed rows
(style, text style, arrowhead, linetype) to names.
- Leader: Lines & Arrows / Text / Fit are resolved from the dimension
style (arrowhead, arrow size, dim-line lineweight/colour, text gap,
vertical text pos, overall scale); Current Vertex navigator; combined
Type; Geometry group after General; no 3D-Visualisation group.
- General: rename "LT Scale" to "Linetype scale"; show ByLayer
transparency by name. Add shared num_prop helper for conditionally
editable numeric rows.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 18:01:44 +03:00
|
|
|
|
ro("Arrow", "arrow_block", "Closed filled"),
|
|
|
|
|
|
ro("Arrow size", "arrow_size", String::new()),
|
|
|
|
|
|
ro("Dim line lineweight", "dim_line_lw", "ByLayer"),
|
|
|
|
|
|
ro("Dim line color", "dim_line_color", "ByLayer"),
|
2026-03-22 14:56:27 +03:00
|
|
|
|
];
|
feat(properties): conform entity property groups to PROPERTIES.md
Rewrite each entity's property builder to the per-entity group/row spec:
the correct sections (Geometry, Misc, Text, Pattern, Lines & Arrows, Leaders,
Block, …) with the spec's rows and real computed values — Diameter,
Circumference, Area, Delta X/Y/Z, Angle, Total angle, Arc length, Radius ratio,
etc. — plus apply routing for the editable rows.
Covers ~26 entities (Line, Circle, Arc, Point, Ellipse, Spline, polylines,
Ray/XLine, Insert, Text, MText, Hatch, Leader, MultiLeader, Tolerance, Solid,
Solid3D/Region/Body, meshes, MLine, Raster/Wipeout, Underlay, Table, Viewport,
Attribute, OLE). The 3D Visualization/Material group and the full Dimension
spec are deferred (they need document access for material/dimstyle name
resolution). Rows whose data is not in the pinned acadrust revision are shown
as empty placeholders, to be filled when the dependency is bumped.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 23:03:18 +03:00
|
|
|
|
let text = vec![
|
feat(properties): rework Text/MText/MLeader/Leader panels to standard layout
Match the entity Properties panels to the standard CAD layout and
web-verified behaviour:
- Text: combined Justify (horizontal x vertical) dropdown; Position and
Text-alignment rows become editable/grayed by justification; drop the
Annotative-scale row.
- MText: combined Justify; editable Direction, Line space distance
(back-solves the factor) and Line space style; Defined width/height
gated on column mode.
- MLeader: regrouped to match the palette - drop the Leader Structure
group (fold landing rows into Leaders), gate Text vs Block on content
type, full 9-value attachment label set, resolve handle-backed rows
(style, text style, arrowhead, linetype) to names.
- Leader: Lines & Arrows / Text / Fit are resolved from the dimension
style (arrowhead, arrow size, dim-line lineweight/colour, text gap,
vertical text pos, overall scale); Current Vertex navigator; combined
Type; Geometry group after General; no 3D-Visualisation group.
- General: rename "LT Scale" to "Linetype scale"; show ByLayer
transparency by name. Add shared num_prop helper for conditionally
editable numeric rows.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 18:01:44 +03:00
|
|
|
|
ro("Text offset", "text_offset", String::new()),
|
|
|
|
|
|
ro("Text pos vert", "text_pos_vert", String::new()),
|
feat(properties): conform entity property groups to PROPERTIES.md
Rewrite each entity's property builder to the per-entity group/row spec:
the correct sections (Geometry, Misc, Text, Pattern, Lines & Arrows, Leaders,
Block, …) with the spec's rows and real computed values — Diameter,
Circumference, Area, Delta X/Y/Z, Angle, Total angle, Arc length, Radius ratio,
etc. — plus apply routing for the editable rows.
Covers ~26 entities (Line, Circle, Arc, Point, Ellipse, Spline, polylines,
Ray/XLine, Insert, Text, MText, Hatch, Leader, MultiLeader, Tolerance, Solid,
Solid3D/Region/Body, meshes, MLine, Raster/Wipeout, Underlay, Table, Viewport,
Attribute, OLE). The 3D Visualization/Material group and the full Dimension
spec are deferred (they need document access for material/dimstyle name
resolution). Rows whose data is not in the pinned acadrust revision are shown
as empty placeholders, to be filled when the dependency is bumped.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 23:03:18 +03:00
|
|
|
|
];
|
|
|
|
|
|
let fit = vec![ro("Dim scale overall", "dim_scale_overall", String::new())];
|
|
|
|
|
|
|
|
|
|
|
|
vec![
|
feat(properties): rework Text/MText/MLeader/Leader panels to standard layout
Match the entity Properties panels to the standard CAD layout and
web-verified behaviour:
- Text: combined Justify (horizontal x vertical) dropdown; Position and
Text-alignment rows become editable/grayed by justification; drop the
Annotative-scale row.
- MText: combined Justify; editable Direction, Line space distance
(back-solves the factor) and Line space style; Defined width/height
gated on column mode.
- MLeader: regrouped to match the palette - drop the Leader Structure
group (fold landing rows into Leaders), gate Text vs Block on content
type, full 9-value attachment label set, resolve handle-backed rows
(style, text style, arrowhead, linetype) to names.
- Leader: Lines & Arrows / Text / Fit are resolved from the dimension
style (arrowhead, arrow size, dim-line lineweight/colour, text gap,
vertical text pos, overall scale); Current Vertex navigator; combined
Type; Geometry group after General; no 3D-Visualisation group.
- General: rename "LT Scale" to "Linetype scale"; show ByLayer
transparency by name. Add shared num_prop helper for conditionally
editable numeric rows.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 18:01:44 +03:00
|
|
|
|
PropSection {
|
|
|
|
|
|
title: "Geometry".into(),
|
|
|
|
|
|
props: geometry,
|
|
|
|
|
|
},
|
feat(properties): conform entity property groups to PROPERTIES.md
Rewrite each entity's property builder to the per-entity group/row spec:
the correct sections (Geometry, Misc, Text, Pattern, Lines & Arrows, Leaders,
Block, …) with the spec's rows and real computed values — Diameter,
Circumference, Area, Delta X/Y/Z, Angle, Total angle, Arc length, Radius ratio,
etc. — plus apply routing for the editable rows.
Covers ~26 entities (Line, Circle, Arc, Point, Ellipse, Spline, polylines,
Ray/XLine, Insert, Text, MText, Hatch, Leader, MultiLeader, Tolerance, Solid,
Solid3D/Region/Body, meshes, MLine, Raster/Wipeout, Underlay, Table, Viewport,
Attribute, OLE). The 3D Visualization/Material group and the full Dimension
spec are deferred (they need document access for material/dimstyle name
resolution). Rows whose data is not in the pinned acadrust revision are shown
as empty placeholders, to be filled when the dependency is bumped.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 23:03:18 +03:00
|
|
|
|
PropSection {
|
|
|
|
|
|
title: "Misc".into(),
|
|
|
|
|
|
props: misc,
|
|
|
|
|
|
},
|
|
|
|
|
|
PropSection {
|
|
|
|
|
|
title: "Lines & Arrows".into(),
|
|
|
|
|
|
props: lines_arrows,
|
|
|
|
|
|
},
|
|
|
|
|
|
PropSection {
|
|
|
|
|
|
title: "Text".into(),
|
|
|
|
|
|
props: text,
|
|
|
|
|
|
},
|
|
|
|
|
|
PropSection {
|
|
|
|
|
|
title: "Fit".into(),
|
|
|
|
|
|
props: fit,
|
|
|
|
|
|
},
|
|
|
|
|
|
]
|
2026-03-22 14:56:27 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn apply_geom_prop(leader: &mut Leader, field: &str, value: &str) {
|
|
|
|
|
|
let f64 = |s: &str| -> Option<f64> { s.trim().parse().ok() };
|
feat(properties): rework Text/MText/MLeader/Leader panels to standard layout
Match the entity Properties panels to the standard CAD layout and
web-verified behaviour:
- Text: combined Justify (horizontal x vertical) dropdown; Position and
Text-alignment rows become editable/grayed by justification; drop the
Annotative-scale row.
- MText: combined Justify; editable Direction, Line space distance
(back-solves the factor) and Line space style; Defined width/height
gated on column mode.
- MLeader: regrouped to match the palette - drop the Leader Structure
group (fold landing rows into Leaders), gate Text vs Block on content
type, full 9-value attachment label set, resolve handle-backed rows
(style, text style, arrowhead, linetype) to names.
- Leader: Lines & Arrows / Text / Fit are resolved from the dimension
style (arrowhead, arrow size, dim-line lineweight/colour, text gap,
vertical text pos, overall scale); Current Vertex navigator; combined
Type; Geometry group after General; no 3D-Visualisation group.
- General: rename "LT Scale" to "Linetype scale"; show ByLayer
transparency by name. Add shared num_prop helper for conditionally
editable numeric rows.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 18:01:44 +03:00
|
|
|
|
// Vertex X/Y/Z edit whichever vertex the Current Vertex navigator focuses.
|
|
|
|
|
|
let vi = if leader.vertices.is_empty() {
|
|
|
|
|
|
0
|
|
|
|
|
|
} else {
|
|
|
|
|
|
crate::scene::view::dispatch::prop_current_vertex().min(leader.vertices.len() - 1)
|
|
|
|
|
|
};
|
2026-03-22 14:56:27 +03:00
|
|
|
|
|
|
|
|
|
|
match field {
|
|
|
|
|
|
"dimension_style" => leader.dimension_style = value.to_string(),
|
feat(properties): rework Text/MText/MLeader/Leader panels to standard layout
Match the entity Properties panels to the standard CAD layout and
web-verified behaviour:
- Text: combined Justify (horizontal x vertical) dropdown; Position and
Text-alignment rows become editable/grayed by justification; drop the
Annotative-scale row.
- MText: combined Justify; editable Direction, Line space distance
(back-solves the factor) and Line space style; Defined width/height
gated on column mode.
- MLeader: regrouped to match the palette - drop the Leader Structure
group (fold landing rows into Leaders), gate Text vs Block on content
type, full 9-value attachment label set, resolve handle-backed rows
(style, text style, arrowhead, linetype) to names.
- Leader: Lines & Arrows / Text / Fit are resolved from the dimension
style (arrowhead, arrow size, dim-line lineweight/colour, text gap,
vertical text pos, overall scale); Current Vertex navigator; combined
Type; Geometry group after General; no 3D-Visualisation group.
- General: rename "LT Scale" to "Linetype scale"; show ByLayer
transparency by name. Add shared num_prop helper for conditionally
editable numeric rows.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 18:01:44 +03:00
|
|
|
|
"leader_type" => {
|
|
|
|
|
|
let (p, a) = match value {
|
|
|
|
|
|
"Line without arrow" => (LeaderPathType::StraightLine, false),
|
|
|
|
|
|
"Spline with arrow" => (LeaderPathType::Spline, true),
|
|
|
|
|
|
"Spline without arrow" => (LeaderPathType::Spline, false),
|
|
|
|
|
|
_ => (LeaderPathType::StraightLine, true),
|
|
|
|
|
|
};
|
|
|
|
|
|
leader.path_type = p;
|
|
|
|
|
|
leader.arrow_enabled = a;
|
|
|
|
|
|
}
|
2026-03-22 14:56:27 +03:00
|
|
|
|
"path_type" => {
|
|
|
|
|
|
leader.path_type = match value {
|
|
|
|
|
|
"Spline" => LeaderPathType::Spline,
|
|
|
|
|
|
_ => LeaderPathType::StraightLine,
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
"creation_type" => {
|
|
|
|
|
|
leader.creation_type = match value {
|
|
|
|
|
|
"With Tolerance" => LeaderCreationType::WithTolerance,
|
|
|
|
|
|
"With Block" => LeaderCreationType::WithBlock,
|
|
|
|
|
|
"No Annotation" => LeaderCreationType::NoAnnotation,
|
|
|
|
|
|
_ => LeaderCreationType::WithText,
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
2026-05-12 10:36:15 +03:00
|
|
|
|
"arrow_enabled" => {
|
|
|
|
|
|
leader.arrow_enabled = if value == "toggle" {
|
|
|
|
|
|
!leader.arrow_enabled
|
|
|
|
|
|
} else {
|
|
|
|
|
|
value == "true"
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
"hookline_enabled" => {
|
|
|
|
|
|
leader.hookline_enabled = if value == "toggle" {
|
|
|
|
|
|
!leader.hookline_enabled
|
|
|
|
|
|
} else {
|
|
|
|
|
|
value == "true"
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-03-22 14:56:27 +03:00
|
|
|
|
"hookline_direction" => {
|
|
|
|
|
|
leader.hookline_direction = match value {
|
|
|
|
|
|
"Same" => HooklineDirection::Same,
|
|
|
|
|
|
_ => HooklineDirection::Opposite,
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
"text_height" => {
|
|
|
|
|
|
if let Some(v) = f64(value) {
|
|
|
|
|
|
leader.text_height = v;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
"text_width" => {
|
|
|
|
|
|
if let Some(v) = f64(value) {
|
|
|
|
|
|
leader.text_width = v;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
"normal_x" => {
|
|
|
|
|
|
if let Some(v) = f64(value) {
|
|
|
|
|
|
leader.normal.x = v;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
"normal_y" => {
|
|
|
|
|
|
if let Some(v) = f64(value) {
|
|
|
|
|
|
leader.normal.y = v;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
"normal_z" => {
|
|
|
|
|
|
if let Some(v) = f64(value) {
|
|
|
|
|
|
leader.normal.z = v;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
"h_dir_x" => {
|
|
|
|
|
|
if let Some(v) = f64(value) {
|
|
|
|
|
|
leader.horizontal_direction.x = v;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
"h_dir_y" => {
|
|
|
|
|
|
if let Some(v) = f64(value) {
|
|
|
|
|
|
leader.horizontal_direction.y = v;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
"h_dir_z" => {
|
|
|
|
|
|
if let Some(v) = f64(value) {
|
|
|
|
|
|
leader.horizontal_direction.z = v;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
"block_offset_x" => {
|
|
|
|
|
|
if let Some(v) = f64(value) {
|
|
|
|
|
|
leader.block_offset.x = v;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
"block_offset_y" => {
|
|
|
|
|
|
if let Some(v) = f64(value) {
|
|
|
|
|
|
leader.block_offset.y = v;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
"block_offset_z" => {
|
|
|
|
|
|
if let Some(v) = f64(value) {
|
|
|
|
|
|
leader.block_offset.z = v;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
"ann_offset_x" => {
|
|
|
|
|
|
if let Some(v) = f64(value) {
|
|
|
|
|
|
leader.annotation_offset.x = v;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
"ann_offset_y" => {
|
|
|
|
|
|
if let Some(v) = f64(value) {
|
|
|
|
|
|
leader.annotation_offset.y = v;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
"ann_offset_z" => {
|
|
|
|
|
|
if let Some(v) = f64(value) {
|
|
|
|
|
|
leader.annotation_offset.z = v;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
feat(properties): conform entity property groups to PROPERTIES.md
Rewrite each entity's property builder to the per-entity group/row spec:
the correct sections (Geometry, Misc, Text, Pattern, Lines & Arrows, Leaders,
Block, …) with the spec's rows and real computed values — Diameter,
Circumference, Area, Delta X/Y/Z, Angle, Total angle, Arc length, Radius ratio,
etc. — plus apply routing for the editable rows.
Covers ~26 entities (Line, Circle, Arc, Point, Ellipse, Spline, polylines,
Ray/XLine, Insert, Text, MText, Hatch, Leader, MultiLeader, Tolerance, Solid,
Solid3D/Region/Body, meshes, MLine, Raster/Wipeout, Underlay, Table, Viewport,
Attribute, OLE). The 3D Visualization/Material group and the full Dimension
spec are deferred (they need document access for material/dimstyle name
resolution). Rows whose data is not in the pinned acadrust revision are shown
as empty placeholders, to be filled when the dependency is bumped.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 23:03:18 +03:00
|
|
|
|
"vertex_x" => {
|
feat(properties): rework Text/MText/MLeader/Leader panels to standard layout
Match the entity Properties panels to the standard CAD layout and
web-verified behaviour:
- Text: combined Justify (horizontal x vertical) dropdown; Position and
Text-alignment rows become editable/grayed by justification; drop the
Annotative-scale row.
- MText: combined Justify; editable Direction, Line space distance
(back-solves the factor) and Line space style; Defined width/height
gated on column mode.
- MLeader: regrouped to match the palette - drop the Leader Structure
group (fold landing rows into Leaders), gate Text vs Block on content
type, full 9-value attachment label set, resolve handle-backed rows
(style, text style, arrowhead, linetype) to names.
- Leader: Lines & Arrows / Text / Fit are resolved from the dimension
style (arrowhead, arrow size, dim-line lineweight/colour, text gap,
vertical text pos, overall scale); Current Vertex navigator; combined
Type; Geometry group after General; no 3D-Visualisation group.
- General: rename "LT Scale" to "Linetype scale"; show ByLayer
transparency by name. Add shared num_prop helper for conditionally
editable numeric rows.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 18:01:44 +03:00
|
|
|
|
if let (Some(v), Some(vert)) = (f64(value), leader.vertices.get_mut(vi)) {
|
2026-03-22 14:56:27 +03:00
|
|
|
|
vert.x = v;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
feat(properties): conform entity property groups to PROPERTIES.md
Rewrite each entity's property builder to the per-entity group/row spec:
the correct sections (Geometry, Misc, Text, Pattern, Lines & Arrows, Leaders,
Block, …) with the spec's rows and real computed values — Diameter,
Circumference, Area, Delta X/Y/Z, Angle, Total angle, Arc length, Radius ratio,
etc. — plus apply routing for the editable rows.
Covers ~26 entities (Line, Circle, Arc, Point, Ellipse, Spline, polylines,
Ray/XLine, Insert, Text, MText, Hatch, Leader, MultiLeader, Tolerance, Solid,
Solid3D/Region/Body, meshes, MLine, Raster/Wipeout, Underlay, Table, Viewport,
Attribute, OLE). The 3D Visualization/Material group and the full Dimension
spec are deferred (they need document access for material/dimstyle name
resolution). Rows whose data is not in the pinned acadrust revision are shown
as empty placeholders, to be filled when the dependency is bumped.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 23:03:18 +03:00
|
|
|
|
"vertex_y" => {
|
feat(properties): rework Text/MText/MLeader/Leader panels to standard layout
Match the entity Properties panels to the standard CAD layout and
web-verified behaviour:
- Text: combined Justify (horizontal x vertical) dropdown; Position and
Text-alignment rows become editable/grayed by justification; drop the
Annotative-scale row.
- MText: combined Justify; editable Direction, Line space distance
(back-solves the factor) and Line space style; Defined width/height
gated on column mode.
- MLeader: regrouped to match the palette - drop the Leader Structure
group (fold landing rows into Leaders), gate Text vs Block on content
type, full 9-value attachment label set, resolve handle-backed rows
(style, text style, arrowhead, linetype) to names.
- Leader: Lines & Arrows / Text / Fit are resolved from the dimension
style (arrowhead, arrow size, dim-line lineweight/colour, text gap,
vertical text pos, overall scale); Current Vertex navigator; combined
Type; Geometry group after General; no 3D-Visualisation group.
- General: rename "LT Scale" to "Linetype scale"; show ByLayer
transparency by name. Add shared num_prop helper for conditionally
editable numeric rows.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 18:01:44 +03:00
|
|
|
|
if let (Some(v), Some(vert)) = (f64(value), leader.vertices.get_mut(vi)) {
|
2026-03-22 14:56:27 +03:00
|
|
|
|
vert.y = v;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
feat(properties): conform entity property groups to PROPERTIES.md
Rewrite each entity's property builder to the per-entity group/row spec:
the correct sections (Geometry, Misc, Text, Pattern, Lines & Arrows, Leaders,
Block, …) with the spec's rows and real computed values — Diameter,
Circumference, Area, Delta X/Y/Z, Angle, Total angle, Arc length, Radius ratio,
etc. — plus apply routing for the editable rows.
Covers ~26 entities (Line, Circle, Arc, Point, Ellipse, Spline, polylines,
Ray/XLine, Insert, Text, MText, Hatch, Leader, MultiLeader, Tolerance, Solid,
Solid3D/Region/Body, meshes, MLine, Raster/Wipeout, Underlay, Table, Viewport,
Attribute, OLE). The 3D Visualization/Material group and the full Dimension
spec are deferred (they need document access for material/dimstyle name
resolution). Rows whose data is not in the pinned acadrust revision are shown
as empty placeholders, to be filled when the dependency is bumped.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 23:03:18 +03:00
|
|
|
|
"vertex_z" => {
|
feat(properties): rework Text/MText/MLeader/Leader panels to standard layout
Match the entity Properties panels to the standard CAD layout and
web-verified behaviour:
- Text: combined Justify (horizontal x vertical) dropdown; Position and
Text-alignment rows become editable/grayed by justification; drop the
Annotative-scale row.
- MText: combined Justify; editable Direction, Line space distance
(back-solves the factor) and Line space style; Defined width/height
gated on column mode.
- MLeader: regrouped to match the palette - drop the Leader Structure
group (fold landing rows into Leaders), gate Text vs Block on content
type, full 9-value attachment label set, resolve handle-backed rows
(style, text style, arrowhead, linetype) to names.
- Leader: Lines & Arrows / Text / Fit are resolved from the dimension
style (arrowhead, arrow size, dim-line lineweight/colour, text gap,
vertical text pos, overall scale); Current Vertex navigator; combined
Type; Geometry group after General; no 3D-Visualisation group.
- General: rename "LT Scale" to "Linetype scale"; show ByLayer
transparency by name. Add shared num_prop helper for conditionally
editable numeric rows.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 18:01:44 +03:00
|
|
|
|
if let (Some(v), Some(vert)) = (f64(value), leader.vertices.get_mut(vi)) {
|
2026-03-22 14:56:27 +03:00
|
|
|
|
vert.z = v;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
_ => {}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ── Transform ──────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
|
|
fn apply_transform(leader: &mut Leader, t: &EntityTransform) {
|
2026-06-16 11:33:46 +03:00
|
|
|
|
crate::scene::view::transform::apply_standard_entity_transform(leader, t, |entity, p1, p2| {
|
2026-03-22 14:56:27 +03:00
|
|
|
|
for v in &mut entity.vertices {
|
2026-06-16 11:33:46 +03:00
|
|
|
|
crate::scene::view::transform::reflect_xy_point(&mut v.x, &mut v.y, p1, p2);
|
2026-03-22 14:56:27 +03:00
|
|
|
|
}
|
2026-06-16 11:33:46 +03:00
|
|
|
|
crate::scene::view::transform::reflect_xy_point(
|
2026-03-22 14:56:27 +03:00
|
|
|
|
&mut entity.block_offset.x,
|
|
|
|
|
|
&mut entity.block_offset.y,
|
|
|
|
|
|
p1,
|
|
|
|
|
|
p2,
|
|
|
|
|
|
);
|
2026-06-16 11:33:46 +03:00
|
|
|
|
crate::scene::view::transform::reflect_xy_point(
|
2026-03-22 14:56:27 +03:00
|
|
|
|
&mut entity.annotation_offset.x,
|
|
|
|
|
|
&mut entity.annotation_offset.y,
|
|
|
|
|
|
p1,
|
|
|
|
|
|
p2,
|
|
|
|
|
|
);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ── Trait impls ────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
|
|
impl TruckConvertible for Leader {
|
|
|
|
|
|
fn to_truck(&self, _document: &acadrust::CadDocument) -> Option<TruckEntity> {
|
2026-05-12 10:36:15 +03:00
|
|
|
|
if self.vertices.is_empty() {
|
|
|
|
|
|
return None;
|
|
|
|
|
|
}
|
2026-03-22 14:56:27 +03:00
|
|
|
|
Some(to_truck(self))
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
feat(grip): popup menus for polylines, spline, mline, hatch, leaders, text
Vocabulary added: AddFitPoint, RemoveFitPoint, Refit, RefineVertices,
TangentDirection, MoveWithText, StackText, UnstackText.
Polyline/Polyline2D/Polyline3D: vertex Add/Remove. MLine: same.
Spline: CV Add/Remove plus Refine Vertices (chord-midpoint insertion,
weights kept in sync, knots cleared so to_truck rebuilds uniform vec).
Hatch: centroid Origin/Angle/Scale (Angle and Scale prompt for value).
Leader: vertex Add/Remove (arrow + centroid stay Stretch-only).
MultiLeader: vertex Add/Remove Leader; MText location Move-with-Leader /
Move-Independent (menu live, structural edits stubbed). Text/MText:
Rotate prompts for degrees and sets rotation.
Spline, Leader, MultiLeader switched from impl_entity_basics! to manual
trait impls so grip_menu can be overridden.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 15:14:43 +03:00
|
|
|
|
impl crate::entities::traits::Grippable for Leader {
|
|
|
|
|
|
fn grips(&self) -> Vec<GripDef> {
|
|
|
|
|
|
grips(self)
|
|
|
|
|
|
}
|
|
|
|
|
|
fn apply_grip(&mut self, grip_id: usize, apply: GripApply) {
|
|
|
|
|
|
apply_grip(self, grip_id, apply);
|
|
|
|
|
|
}
|
2026-06-16 11:33:46 +03:00
|
|
|
|
fn grip_menu(&self, grip_id: usize) -> Vec<crate::scene::model::object::GripMenuItem> {
|
|
|
|
|
|
use crate::scene::model::object::{GripMenuAction, GripMenuItem};
|
feat(grip): popup menus for polylines, spline, mline, hatch, leaders, text
Vocabulary added: AddFitPoint, RemoveFitPoint, Refit, RefineVertices,
TangentDirection, MoveWithText, StackText, UnstackText.
Polyline/Polyline2D/Polyline3D: vertex Add/Remove. MLine: same.
Spline: CV Add/Remove plus Refine Vertices (chord-midpoint insertion,
weights kept in sync, knots cleared so to_truck rebuilds uniform vec).
Hatch: centroid Origin/Angle/Scale (Angle and Scale prompt for value).
Leader: vertex Add/Remove (arrow + centroid stay Stretch-only).
MultiLeader: vertex Add/Remove Leader; MText location Move-with-Leader /
Move-Independent (menu live, structural edits stubbed). Text/MText:
Rotate prompts for degrees and sets rotation.
Spline, Leader, MultiLeader switched from impl_entity_basics! to manual
trait impls so grip_menu can be overridden.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 15:14:43 +03:00
|
|
|
|
let n = self.vertices.len();
|
|
|
|
|
|
if grip_id == 0 {
|
|
|
|
|
|
// Arrow head — stretch only.
|
2026-06-11 00:04:37 +03:00
|
|
|
|
vec![GripMenuItem {
|
|
|
|
|
|
label: "Stretch",
|
|
|
|
|
|
action: GripMenuAction::Stretch,
|
|
|
|
|
|
}]
|
feat(grip): popup menus for polylines, spline, mline, hatch, leaders, text
Vocabulary added: AddFitPoint, RemoveFitPoint, Refit, RefineVertices,
TangentDirection, MoveWithText, StackText, UnstackText.
Polyline/Polyline2D/Polyline3D: vertex Add/Remove. MLine: same.
Spline: CV Add/Remove plus Refine Vertices (chord-midpoint insertion,
weights kept in sync, knots cleared so to_truck rebuilds uniform vec).
Hatch: centroid Origin/Angle/Scale (Angle and Scale prompt for value).
Leader: vertex Add/Remove (arrow + centroid stay Stretch-only).
MultiLeader: vertex Add/Remove Leader; MText location Move-with-Leader /
Move-Independent (menu live, structural edits stubbed). Text/MText:
Rotate prompts for degrees and sets rotation.
Spline, Leader, MultiLeader switched from impl_entity_basics! to manual
trait impls so grip_menu can be overridden.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 15:14:43 +03:00
|
|
|
|
} else if grip_id < n {
|
|
|
|
|
|
vec![
|
2026-06-11 00:04:37 +03:00
|
|
|
|
GripMenuItem {
|
|
|
|
|
|
label: "Stretch",
|
|
|
|
|
|
action: GripMenuAction::Stretch,
|
|
|
|
|
|
},
|
|
|
|
|
|
GripMenuItem {
|
|
|
|
|
|
label: "Add Vertex",
|
|
|
|
|
|
action: GripMenuAction::AddVertex,
|
|
|
|
|
|
},
|
|
|
|
|
|
GripMenuItem {
|
|
|
|
|
|
label: "Remove Vertex",
|
|
|
|
|
|
action: GripMenuAction::RemoveVertex,
|
|
|
|
|
|
},
|
feat(grip): popup menus for polylines, spline, mline, hatch, leaders, text
Vocabulary added: AddFitPoint, RemoveFitPoint, Refit, RefineVertices,
TangentDirection, MoveWithText, StackText, UnstackText.
Polyline/Polyline2D/Polyline3D: vertex Add/Remove. MLine: same.
Spline: CV Add/Remove plus Refine Vertices (chord-midpoint insertion,
weights kept in sync, knots cleared so to_truck rebuilds uniform vec).
Hatch: centroid Origin/Angle/Scale (Angle and Scale prompt for value).
Leader: vertex Add/Remove (arrow + centroid stay Stretch-only).
MultiLeader: vertex Add/Remove Leader; MText location Move-with-Leader /
Move-Independent (menu live, structural edits stubbed). Text/MText:
Rotate prompts for degrees and sets rotation.
Spline, Leader, MultiLeader switched from impl_entity_basics! to manual
trait impls so grip_menu can be overridden.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 15:14:43 +03:00
|
|
|
|
]
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// Centroid grip — move whole leader.
|
2026-06-11 00:04:37 +03:00
|
|
|
|
vec![GripMenuItem {
|
|
|
|
|
|
label: "Stretch",
|
|
|
|
|
|
action: GripMenuAction::Stretch,
|
|
|
|
|
|
}]
|
feat(grip): popup menus for polylines, spline, mline, hatch, leaders, text
Vocabulary added: AddFitPoint, RemoveFitPoint, Refit, RefineVertices,
TangentDirection, MoveWithText, StackText, UnstackText.
Polyline/Polyline2D/Polyline3D: vertex Add/Remove. MLine: same.
Spline: CV Add/Remove plus Refine Vertices (chord-midpoint insertion,
weights kept in sync, knots cleared so to_truck rebuilds uniform vec).
Hatch: centroid Origin/Angle/Scale (Angle and Scale prompt for value).
Leader: vertex Add/Remove (arrow + centroid stay Stretch-only).
MultiLeader: vertex Add/Remove Leader; MText location Move-with-Leader /
Move-Independent (menu live, structural edits stubbed). Text/MText:
Rotate prompts for degrees and sets rotation.
Spline, Leader, MultiLeader switched from impl_entity_basics! to manual
trait impls so grip_menu can be overridden.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 15:14:43 +03:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-06-16 11:33:46 +03:00
|
|
|
|
fn apply_grip_menu(&mut self, grip_id: usize, action: crate::scene::model::object::GripMenuAction) {
|
|
|
|
|
|
use crate::scene::model::object::GripMenuAction as A;
|
feat(grip): popup menus for polylines, spline, mline, hatch, leaders, text
Vocabulary added: AddFitPoint, RemoveFitPoint, Refit, RefineVertices,
TangentDirection, MoveWithText, StackText, UnstackText.
Polyline/Polyline2D/Polyline3D: vertex Add/Remove. MLine: same.
Spline: CV Add/Remove plus Refine Vertices (chord-midpoint insertion,
weights kept in sync, knots cleared so to_truck rebuilds uniform vec).
Hatch: centroid Origin/Angle/Scale (Angle and Scale prompt for value).
Leader: vertex Add/Remove (arrow + centroid stay Stretch-only).
MultiLeader: vertex Add/Remove Leader; MText location Move-with-Leader /
Move-Independent (menu live, structural edits stubbed). Text/MText:
Rotate prompts for degrees and sets rotation.
Spline, Leader, MultiLeader switched from impl_entity_basics! to manual
trait impls so grip_menu can be overridden.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 15:14:43 +03:00
|
|
|
|
let n = self.vertices.len();
|
|
|
|
|
|
match action {
|
|
|
|
|
|
A::AddVertex if grip_id < n => {
|
|
|
|
|
|
let i1 = (grip_id + 1).min(n - 1);
|
|
|
|
|
|
if i1 == grip_id {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
let v0 = &self.vertices[grip_id];
|
|
|
|
|
|
let v1 = &self.vertices[i1];
|
|
|
|
|
|
let mid = acadrust::types::Vector3::new(
|
|
|
|
|
|
(v0.x + v1.x) * 0.5,
|
|
|
|
|
|
(v0.y + v1.y) * 0.5,
|
|
|
|
|
|
(v0.z + v1.z) * 0.5,
|
|
|
|
|
|
);
|
|
|
|
|
|
self.vertices.insert(i1, mid);
|
|
|
|
|
|
}
|
|
|
|
|
|
A::RemoveVertex if grip_id < n && n > 2 => {
|
|
|
|
|
|
self.vertices.remove(grip_id);
|
|
|
|
|
|
}
|
|
|
|
|
|
_ => {}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl crate::entities::traits::PropertyEditable for Leader {
|
2026-07-02 22:46:19 +03:00
|
|
|
|
fn geometry_properties(&self, _text_style_names: &[String]) -> Vec<PropSection> {
|
feat(grip): popup menus for polylines, spline, mline, hatch, leaders, text
Vocabulary added: AddFitPoint, RemoveFitPoint, Refit, RefineVertices,
TangentDirection, MoveWithText, StackText, UnstackText.
Polyline/Polyline2D/Polyline3D: vertex Add/Remove. MLine: same.
Spline: CV Add/Remove plus Refine Vertices (chord-midpoint insertion,
weights kept in sync, knots cleared so to_truck rebuilds uniform vec).
Hatch: centroid Origin/Angle/Scale (Angle and Scale prompt for value).
Leader: vertex Add/Remove (arrow + centroid stay Stretch-only).
MultiLeader: vertex Add/Remove Leader; MText location Move-with-Leader /
Move-Independent (menu live, structural edits stubbed). Text/MText:
Rotate prompts for degrees and sets rotation.
Spline, Leader, MultiLeader switched from impl_entity_basics! to manual
trait impls so grip_menu can be overridden.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 15:14:43 +03:00
|
|
|
|
properties(self)
|
|
|
|
|
|
}
|
|
|
|
|
|
fn apply_geom_prop(&mut self, field: &str, value: &str) {
|
|
|
|
|
|
apply_geom_prop(self, field, value);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl crate::entities::traits::Transformable for Leader {
|
|
|
|
|
|
fn apply_transform(&mut self, t: &EntityTransform) {
|
|
|
|
|
|
apply_transform(self, t);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
refactor(tess): move per-entity tessellation into entities/
Each entity's tessellation now lives alongside its definition in
entities/*.rs, attached to the entity type via a local trait:
LegacyTess — Viewport / Insert / Hatch / Ole2Frame
(fallback path for entities not on the truck pipeline)
LeaderTess — Leader
MultiLeaderTess — MultiLeader
DimensionTess — Dimension (carries its dim-only helpers too:
~1700 lines of dim_geometry, dim_text_*, format_*,
tolerance, suppression, etc.)
scene/tessellate.rs keeps only the cross-entity dispatcher plus the
shared dim machinery reused by leader/multileader/dimension
(ArrowKind, DimGeom, append_arrow, arrow_from_block, add_segment,
add_polyline, normalized_or, push_tri, color_or_inherit, entity_z,
offset_snap_pts). Cross-entity arc helpers + aci_to_rgba moved to
scene/tess_util.rs.
scene/tessellate.rs shrinks from ~3300 to 809 lines. Compile clean,
all 9 tests pass.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 23:12:27 +03:00
|
|
|
|
|
|
|
|
|
|
/// Per-entity tessellation entry for `Leader`. Lives here so all leader
|
|
|
|
|
|
/// tess code stays alongside the entity definition. Cross-entity dim
|
2026-06-16 11:33:46 +03:00
|
|
|
|
/// machinery (arrow shapes, `DimGeom`) lives in `scene::convert::tessellate` and
|
refactor(tess): move per-entity tessellation into entities/
Each entity's tessellation now lives alongside its definition in
entities/*.rs, attached to the entity type via a local trait:
LegacyTess — Viewport / Insert / Hatch / Ole2Frame
(fallback path for entities not on the truck pipeline)
LeaderTess — Leader
MultiLeaderTess — MultiLeader
DimensionTess — Dimension (carries its dim-only helpers too:
~1700 lines of dim_geometry, dim_text_*, format_*,
tolerance, suppression, etc.)
scene/tessellate.rs keeps only the cross-entity dispatcher plus the
shared dim machinery reused by leader/multileader/dimension
(ArrowKind, DimGeom, append_arrow, arrow_from_block, add_segment,
add_polyline, normalized_or, push_tri, color_or_inherit, entity_z,
offset_snap_pts). Cross-entity arc helpers + aci_to_rgba moved to
scene/tess_util.rs.
scene/tessellate.rs shrinks from ~3300 to 809 lines. Compile clean,
all 9 tests pass.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 23:12:27 +03:00
|
|
|
|
/// is reused via the dim arrow emitter so the leader matches the active
|
|
|
|
|
|
/// DIMSTYLE.
|
|
|
|
|
|
pub trait LeaderTess {
|
|
|
|
|
|
fn tessellate(
|
|
|
|
|
|
&self,
|
|
|
|
|
|
document: &acadrust::CadDocument,
|
|
|
|
|
|
handle: acadrust::Handle,
|
|
|
|
|
|
selected: bool,
|
|
|
|
|
|
entity_color: [f32; 4],
|
|
|
|
|
|
line_weight_px: f32,
|
|
|
|
|
|
anno_scale: f32,
|
2026-06-16 11:33:46 +03:00
|
|
|
|
) -> crate::scene::model::wire_model::WireModel;
|
refactor(tess): move per-entity tessellation into entities/
Each entity's tessellation now lives alongside its definition in
entities/*.rs, attached to the entity type via a local trait:
LegacyTess — Viewport / Insert / Hatch / Ole2Frame
(fallback path for entities not on the truck pipeline)
LeaderTess — Leader
MultiLeaderTess — MultiLeader
DimensionTess — Dimension (carries its dim-only helpers too:
~1700 lines of dim_geometry, dim_text_*, format_*,
tolerance, suppression, etc.)
scene/tessellate.rs keeps only the cross-entity dispatcher plus the
shared dim machinery reused by leader/multileader/dimension
(ArrowKind, DimGeom, append_arrow, arrow_from_block, add_segment,
add_polyline, normalized_or, push_tri, color_or_inherit, entity_z,
offset_snap_pts). Cross-entity arc helpers + aci_to_rgba moved to
scene/tess_util.rs.
scene/tessellate.rs shrinks from ~3300 to 809 lines. Compile clean,
all 9 tests pass.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 23:12:27 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl LeaderTess for Leader {
|
|
|
|
|
|
fn tessellate(
|
|
|
|
|
|
&self,
|
|
|
|
|
|
document: &acadrust::CadDocument,
|
|
|
|
|
|
handle: acadrust::Handle,
|
|
|
|
|
|
selected: bool,
|
|
|
|
|
|
entity_color: [f32; 4],
|
|
|
|
|
|
line_weight_px: f32,
|
|
|
|
|
|
anno_scale: f32,
|
2026-06-16 11:33:46 +03:00
|
|
|
|
) -> crate::scene::model::wire_model::WireModel {
|
|
|
|
|
|
use crate::scene::convert::tessellate::{append_arrow, arrow_from_block, ArrowKind, DimGeom};
|
feat(properties): editable per-object leader dimension overrides
A legacy leader's Lines & Arrows / Text / Fit rows are now editable
per-object overrides of its dimension style, stored in the standard
ACAD_DSTYLE XDATA record (new src/entities/dim_override.rs codec). Arrow
block, arrow size, dim-line lineweight, text offset, vertical text
position and overall scale each prefer an override over the style; the
renderer honours arrow size / block / overall scale and the dim-line
lineweight, so an edited leader redraws at its new arrow and weight.
XDATA edits go through a new dispatch::set_entity_xdata, which registers
the application in the APPID table (the DWG writer drops records for an
unregistered app) and drops that app's stale verbatim EED block (which
otherwise wins over the structured record on a DWG save), so edits and
clears round-trip. The hyperlink editor moves onto this path too.
Dim-line colour stays read-only: it would live in the leader's
override_color, which the file layer doesn't serialise, so making it
editable would silently lose the pick on save. Picking "Closed filled"
writes an explicit null-handle arrow override rather than clearing, so
it sticks even when the style's arrow differs; an unparseable numeric
entry is ignored instead of wiping the stored override.
Note: the DXF entity writer only emits XDATA for hatches, so these
overrides (and hyperlinks) currently persist on DWG save but not DXF —
an acadrust-side gap to close separately.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 00:28:42 +03:00
|
|
|
|
use crate::entities::dim_override as dov;
|
2026-06-16 11:33:46 +03:00
|
|
|
|
use crate::scene::model::wire_model::WireModel;
|
feat(properties): editable per-object leader dimension overrides
A legacy leader's Lines & Arrows / Text / Fit rows are now editable
per-object overrides of its dimension style, stored in the standard
ACAD_DSTYLE XDATA record (new src/entities/dim_override.rs codec). Arrow
block, arrow size, dim-line lineweight, text offset, vertical text
position and overall scale each prefer an override over the style; the
renderer honours arrow size / block / overall scale and the dim-line
lineweight, so an edited leader redraws at its new arrow and weight.
XDATA edits go through a new dispatch::set_entity_xdata, which registers
the application in the APPID table (the DWG writer drops records for an
unregistered app) and drops that app's stale verbatim EED block (which
otherwise wins over the structured record on a DWG save), so edits and
clears round-trip. The hyperlink editor moves onto this path too.
Dim-line colour stays read-only: it would live in the leader's
override_color, which the file layer doesn't serialise, so making it
editable would silently lose the pick on save. Picking "Closed filled"
writes an explicit null-handle arrow override rather than clearing, so
it sticks even when the style's arrow differs; an unparseable numeric
entry is ignored instead of wiping the stored override.
Note: the DXF entity writer only emits XDATA for hatches, so these
overrides (and hyperlinks) currently persist on DWG save but not DXF —
an acadrust-side gap to close separately.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 00:28:42 +03:00
|
|
|
|
let xd = &self.common.extended_data;
|
2026-07-13 17:31:09 +03:00
|
|
|
|
// Dim-line colour: a per-object ACAD_DSTYLE override (code 176, an ACI
|
|
|
|
|
|
// index) wins over the assigned dim style's DIMCLRD; ByLayer / ByBlock
|
|
|
|
|
|
// (0 / 256) and no setting fall through to the entity colour.
|
refactor(tess): move per-entity tessellation into entities/
Each entity's tessellation now lives alongside its definition in
entities/*.rs, attached to the entity type via a local trait:
LegacyTess — Viewport / Insert / Hatch / Ole2Frame
(fallback path for entities not on the truck pipeline)
LeaderTess — Leader
MultiLeaderTess — MultiLeader
DimensionTess — Dimension (carries its dim-only helpers too:
~1700 lines of dim_geometry, dim_text_*, format_*,
tolerance, suppression, etc.)
scene/tessellate.rs keeps only the cross-entity dispatcher plus the
shared dim machinery reused by leader/multileader/dimension
(ArrowKind, DimGeom, append_arrow, arrow_from_block, add_segment,
add_polyline, normalized_or, push_tri, color_or_inherit, entity_z,
offset_snap_pts). Cross-entity arc helpers + aci_to_rgba moved to
scene/tess_util.rs.
scene/tessellate.rs shrinks from ~3300 to 809 lines. Compile clean,
all 9 tests pass.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 23:12:27 +03:00
|
|
|
|
let color = if selected {
|
|
|
|
|
|
WireModel::SELECTED
|
|
|
|
|
|
} else {
|
2026-07-13 17:31:09 +03:00
|
|
|
|
let dim_clr = dov::int(xd, dov::DIMCLRD).or_else(|| {
|
|
|
|
|
|
document
|
|
|
|
|
|
.dim_styles
|
|
|
|
|
|
.iter()
|
|
|
|
|
|
.find(|s| {
|
|
|
|
|
|
s.name.eq_ignore_ascii_case(&self.dimension_style)
|
|
|
|
|
|
|| (self.dimension_style.trim().is_empty()
|
|
|
|
|
|
&& s.name.eq_ignore_ascii_case("Standard"))
|
|
|
|
|
|
})
|
|
|
|
|
|
.map(|s| s.dimclrd)
|
|
|
|
|
|
});
|
|
|
|
|
|
match dim_clr {
|
|
|
|
|
|
Some(idx) if idx != 0 && idx != 256 => crate::scene::convert::tess_util::aci_to_rgba(
|
|
|
|
|
|
&acadrust::types::Color::from_index(idx),
|
|
|
|
|
|
),
|
|
|
|
|
|
_ => entity_color,
|
|
|
|
|
|
}
|
refactor(tess): move per-entity tessellation into entities/
Each entity's tessellation now lives alongside its definition in
entities/*.rs, attached to the entity type via a local trait:
LegacyTess — Viewport / Insert / Hatch / Ole2Frame
(fallback path for entities not on the truck pipeline)
LeaderTess — Leader
MultiLeaderTess — MultiLeader
DimensionTess — Dimension (carries its dim-only helpers too:
~1700 lines of dim_geometry, dim_text_*, format_*,
tolerance, suppression, etc.)
scene/tessellate.rs keeps only the cross-entity dispatcher plus the
shared dim machinery reused by leader/multileader/dimension
(ArrowKind, DimGeom, append_arrow, arrow_from_block, add_segment,
add_polyline, normalized_or, push_tri, color_or_inherit, entity_z,
offset_snap_pts). Cross-entity arc helpers + aci_to_rgba moved to
scene/tess_util.rs.
scene/tessellate.rs shrinks from ~3300 to 809 lines. Compile clean,
all 9 tests pass.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 23:12:27 +03:00
|
|
|
|
};
|
feat(properties): editable per-object leader dimension overrides
A legacy leader's Lines & Arrows / Text / Fit rows are now editable
per-object overrides of its dimension style, stored in the standard
ACAD_DSTYLE XDATA record (new src/entities/dim_override.rs codec). Arrow
block, arrow size, dim-line lineweight, text offset, vertical text
position and overall scale each prefer an override over the style; the
renderer honours arrow size / block / overall scale and the dim-line
lineweight, so an edited leader redraws at its new arrow and weight.
XDATA edits go through a new dispatch::set_entity_xdata, which registers
the application in the APPID table (the DWG writer drops records for an
unregistered app) and drops that app's stale verbatim EED block (which
otherwise wins over the structured record on a DWG save), so edits and
clears round-trip. The hyperlink editor moves onto this path too.
Dim-line colour stays read-only: it would live in the leader's
override_color, which the file layer doesn't serialise, so making it
editable would silently lose the pick on save. Picking "Closed filled"
writes an explicit null-handle arrow override rather than clearing, so
it sticks even when the style's arrow differs; an unparseable numeric
entry is ignored instead of wiping the stored override.
Note: the DXF entity writer only emits XDATA for hatches, so these
overrides (and hyperlinks) currently persist on DWG save but not DXF —
an acadrust-side gap to close separately.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 00:28:42 +03:00
|
|
|
|
// A concrete DIMLWD override sets the leader line's weight; ByLayer /
|
|
|
|
|
|
// ByBlock / Default and no override keep the resolved weight passed in.
|
|
|
|
|
|
let line_weight_px = match dov::int(xd, dov::DIMLWD) {
|
|
|
|
|
|
Some(lwd) if lwd >= 0 => crate::scene::view::render::lineweight_to_px(
|
|
|
|
|
|
&acadrust::types::LineWeight::from_value(lwd),
|
|
|
|
|
|
),
|
|
|
|
|
|
_ => line_weight_px,
|
|
|
|
|
|
};
|
refactor(tess): move per-entity tessellation into entities/
Each entity's tessellation now lives alongside its definition in
entities/*.rs, attached to the entity type via a local trait:
LegacyTess — Viewport / Insert / Hatch / Ole2Frame
(fallback path for entities not on the truck pipeline)
LeaderTess — Leader
MultiLeaderTess — MultiLeader
DimensionTess — Dimension (carries its dim-only helpers too:
~1700 lines of dim_geometry, dim_text_*, format_*,
tolerance, suppression, etc.)
scene/tessellate.rs keeps only the cross-entity dispatcher plus the
shared dim machinery reused by leader/multileader/dimension
(ArrowKind, DimGeom, append_arrow, arrow_from_block, add_segment,
add_polyline, normalized_or, push_tri, color_or_inherit, entity_z,
offset_snap_pts). Cross-entity arc helpers + aci_to_rgba moved to
scene/tess_util.rs.
scene/tessellate.rs shrinks from ~3300 to 809 lines. Compile clean,
all 9 tests pass.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 23:12:27 +03:00
|
|
|
|
let name = handle.value().to_string();
|
|
|
|
|
|
let p3 = |v: &acadrust::types::Vector3| -> [f32; 3] {
|
2026-06-24 18:38:23 +03:00
|
|
|
|
[(v.x) as f32, (v.y) as f32, (v.z) as f32]
|
refactor(tess): move per-entity tessellation into entities/
Each entity's tessellation now lives alongside its definition in
entities/*.rs, attached to the entity type via a local trait:
LegacyTess — Viewport / Insert / Hatch / Ole2Frame
(fallback path for entities not on the truck pipeline)
LeaderTess — Leader
MultiLeaderTess — MultiLeader
DimensionTess — Dimension (carries its dim-only helpers too:
~1700 lines of dim_geometry, dim_text_*, format_*,
tolerance, suppression, etc.)
scene/tessellate.rs keeps only the cross-entity dispatcher plus the
shared dim machinery reused by leader/multileader/dimension
(ArrowKind, DimGeom, append_arrow, arrow_from_block, add_segment,
add_polyline, normalized_or, push_tri, color_or_inherit, entity_z,
offset_snap_pts). Cross-entity arc helpers + aci_to_rgba moved to
scene/tess_util.rs.
scene/tessellate.rs shrinks from ~3300 to 809 lines. Compile clean,
all 9 tests pass.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 23:12:27 +03:00
|
|
|
|
};
|
|
|
|
|
|
let nan = [f32::NAN; 3];
|
|
|
|
|
|
|
|
|
|
|
|
let verts = &self.vertices;
|
|
|
|
|
|
|
|
|
|
|
|
if verts.len() < 2 {
|
|
|
|
|
|
return WireModel {
|
refactor(text): per-entity SDF text — all text kinds, selection/hover highlight
Rearchitect SDF text from a document-wide collector to per-entity
production during tessellation, so each entity owns its glyph quads and
composite/nested text is covered for free (no re-explosion, no per-frame
document walk).
- WireModel gains `text_verts`: glyph quads ride on the wire, so they are
cached by the tess memo, cloned on hit, and transformed by the block
expand loop exactly like `points`.
- Text arm (tessellate.rs) builds the quads when SDF is on and suppresses
the strokes; render gathers text_verts from the viewport wire set
(`gather_text_verts`, cached on wire content id) — the old collector is
removed. Covers model, dimension, table, block-internal and paper-sheet
text uniformly.
- MLEADER text (lays out via layout_mtext, not the Text arm) gets its own
SDF branch driven by the per-run GlyphRun.
- Pick box comes from the rendered glyph quads (true text extent), not
entity_aabb which mis-places the box for MTEXT; composite paths no longer
clobber the empty text wire's tight AABB (dim pick box hugs the text).
- Selection / hover highlight via a text-highlight overlay (upload_text_
highlight, keyed on selection_generation) mirroring the selected-wire
xray overlay; base glyphs stay neutral so a deselect leaves no stale tint.
- Debug: env OCS_TEXT_BOX draws each run's glyph-bounds rectangle.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 17:01:36 +03:00
|
|
|
|
text_verts: Vec::new(),
|
refactor(tess): move per-entity tessellation into entities/
Each entity's tessellation now lives alongside its definition in
entities/*.rs, attached to the entity type via a local trait:
LegacyTess — Viewport / Insert / Hatch / Ole2Frame
(fallback path for entities not on the truck pipeline)
LeaderTess — Leader
MultiLeaderTess — MultiLeader
DimensionTess — Dimension (carries its dim-only helpers too:
~1700 lines of dim_geometry, dim_text_*, format_*,
tolerance, suppression, etc.)
scene/tessellate.rs keeps only the cross-entity dispatcher plus the
shared dim machinery reused by leader/multileader/dimension
(ArrowKind, DimGeom, append_arrow, arrow_from_block, add_segment,
add_polyline, normalized_or, push_tri, color_or_inherit, entity_z,
offset_snap_pts). Cross-entity arc helpers + aci_to_rgba moved to
scene/tess_util.rs.
scene/tessellate.rs shrinks from ~3300 to 809 lines. Compile clean,
all 9 tests pass.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 23:12:27 +03:00
|
|
|
|
name,
|
|
|
|
|
|
points: vec![],
|
2026-06-23 17:08:54 +03:00
|
|
|
|
points_low: Vec::new(),
|
refactor(tess): move per-entity tessellation into entities/
Each entity's tessellation now lives alongside its definition in
entities/*.rs, attached to the entity type via a local trait:
LegacyTess — Viewport / Insert / Hatch / Ole2Frame
(fallback path for entities not on the truck pipeline)
LeaderTess — Leader
MultiLeaderTess — MultiLeader
DimensionTess — Dimension (carries its dim-only helpers too:
~1700 lines of dim_geometry, dim_text_*, format_*,
tolerance, suppression, etc.)
scene/tessellate.rs keeps only the cross-entity dispatcher plus the
shared dim machinery reused by leader/multileader/dimension
(ArrowKind, DimGeom, append_arrow, arrow_from_block, add_segment,
add_polyline, normalized_or, push_tri, color_or_inherit, entity_z,
offset_snap_pts). Cross-entity arc helpers + aci_to_rgba moved to
scene/tess_util.rs.
scene/tessellate.rs shrinks from ~3300 to 809 lines. Compile clean,
all 9 tests pass.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 23:12:27 +03:00
|
|
|
|
color,
|
|
|
|
|
|
selected,
|
|
|
|
|
|
aci: 0,
|
|
|
|
|
|
pattern_length: 0.0,
|
|
|
|
|
|
pattern: [0.0; 8],
|
|
|
|
|
|
line_weight_px,
|
|
|
|
|
|
snap_pts: vec![],
|
|
|
|
|
|
tangent_geoms: vec![],
|
|
|
|
|
|
key_vertices: vec![],
|
|
|
|
|
|
aabb: WireModel::UNBOUNDED_AABB,
|
|
|
|
|
|
plinegen: true,
|
|
|
|
|
|
vp_scissor: None,
|
|
|
|
|
|
fill_tris: vec![],
|
2026-06-23 18:03:40 +03:00
|
|
|
|
fill_tris_low: Vec::new(),
|
refactor(tess): move per-entity tessellation into entities/
Each entity's tessellation now lives alongside its definition in
entities/*.rs, attached to the entity type via a local trait:
LegacyTess — Viewport / Insert / Hatch / Ole2Frame
(fallback path for entities not on the truck pipeline)
LeaderTess — Leader
MultiLeaderTess — MultiLeader
DimensionTess — Dimension (carries its dim-only helpers too:
~1700 lines of dim_geometry, dim_text_*, format_*,
tolerance, suppression, etc.)
scene/tessellate.rs keeps only the cross-entity dispatcher plus the
shared dim machinery reused by leader/multileader/dimension
(ArrowKind, DimGeom, append_arrow, arrow_from_block, add_segment,
add_polyline, normalized_or, push_tri, color_or_inherit, entity_z,
offset_snap_pts). Cross-entity arc helpers + aci_to_rgba moved to
scene/tess_util.rs.
scene/tessellate.rs shrinks from ~3300 to 809 lines. Compile clean,
all 9 tests pass.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 23:12:27 +03:00
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let mut points: Vec<[f32; 3]> = verts.iter().map(|v| p3(v)).collect();
|
|
|
|
|
|
let mut tangents: Vec<TangentGeom> = Vec::new();
|
2026-06-23 22:23:56 +03:00
|
|
|
|
let key_vertices: Vec<[f64; 3]> = verts.iter().map(|v| [v.x, v.y, v.z]).collect();
|
refactor(tess): move per-entity tessellation into entities/
Each entity's tessellation now lives alongside its definition in
entities/*.rs, attached to the entity type via a local trait:
LegacyTess — Viewport / Insert / Hatch / Ole2Frame
(fallback path for entities not on the truck pipeline)
LeaderTess — Leader
MultiLeaderTess — MultiLeader
DimensionTess — Dimension (carries its dim-only helpers too:
~1700 lines of dim_geometry, dim_text_*, format_*,
tolerance, suppression, etc.)
scene/tessellate.rs keeps only the cross-entity dispatcher plus the
shared dim machinery reused by leader/multileader/dimension
(ArrowKind, DimGeom, append_arrow, arrow_from_block, add_segment,
add_polyline, normalized_or, push_tri, color_or_inherit, entity_z,
offset_snap_pts). Cross-entity arc helpers + aci_to_rgba moved to
scene/tess_util.rs.
scene/tessellate.rs shrinks from ~3300 to 809 lines. Compile clean,
all 9 tests pass.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 23:12:27 +03:00
|
|
|
|
let mut fill_tris: Vec<[f32; 3]> = Vec::new();
|
|
|
|
|
|
|
|
|
|
|
|
for i in 0..verts.len().saturating_sub(1) {
|
|
|
|
|
|
tangents.push(TangentGeom::Line {
|
|
|
|
|
|
p1: p3(&verts[i]),
|
|
|
|
|
|
p2: p3(&verts[i + 1]),
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if self.arrow_enabled {
|
|
|
|
|
|
// Resolve the active dim style → DIMLDRBLK to pick the arrow shape.
|
|
|
|
|
|
// DIMASZ × DIMSCALE drives the size when available; otherwise fall
|
|
|
|
|
|
// back to the legacy text-height heuristic.
|
|
|
|
|
|
let style = document.dim_styles.iter().find(|s| {
|
|
|
|
|
|
s.name.eq_ignore_ascii_case(&self.dimension_style)
|
|
|
|
|
|
|| (self.dimension_style.trim().is_empty()
|
|
|
|
|
|
&& s.name.eq_ignore_ascii_case("Standard"))
|
|
|
|
|
|
});
|
feat(properties): editable per-object leader dimension overrides
A legacy leader's Lines & Arrows / Text / Fit rows are now editable
per-object overrides of its dimension style, stored in the standard
ACAD_DSTYLE XDATA record (new src/entities/dim_override.rs codec). Arrow
block, arrow size, dim-line lineweight, text offset, vertical text
position and overall scale each prefer an override over the style; the
renderer honours arrow size / block / overall scale and the dim-line
lineweight, so an edited leader redraws at its new arrow and weight.
XDATA edits go through a new dispatch::set_entity_xdata, which registers
the application in the APPID table (the DWG writer drops records for an
unregistered app) and drops that app's stale verbatim EED block (which
otherwise wins over the structured record on a DWG save), so edits and
clears round-trip. The hyperlink editor moves onto this path too.
Dim-line colour stays read-only: it would live in the leader's
override_color, which the file layer doesn't serialise, so making it
editable would silently lose the pick on save. Picking "Closed filled"
writes an explicit null-handle arrow override rather than clearing, so
it sticks even when the style's arrow differs; an unparseable numeric
entry is ignored instead of wiping the stored override.
Note: the DXF entity writer only emits XDATA for hatches, so these
overrides (and hyperlinks) currently persist on DWG save but not DXF —
an acadrust-side gap to close separately.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 00:28:42 +03:00
|
|
|
|
// Each of DIMSCALE / DIMASZ / DIMLDRBLK prefers a per-object override
|
|
|
|
|
|
// over the style, so an edited leader arrow renders at its new size,
|
|
|
|
|
|
// scale and shape.
|
|
|
|
|
|
let dim_scale = dov::real(xd, dov::DIMSCALE)
|
|
|
|
|
|
.filter(|v| *v > 1e-6)
|
|
|
|
|
|
.or_else(|| style.map(|s| s.dimscale).filter(|v| *v > 1e-6))
|
refactor(tess): move per-entity tessellation into entities/
Each entity's tessellation now lives alongside its definition in
entities/*.rs, attached to the entity type via a local trait:
LegacyTess — Viewport / Insert / Hatch / Ole2Frame
(fallback path for entities not on the truck pipeline)
LeaderTess — Leader
MultiLeaderTess — MultiLeader
DimensionTess — Dimension (carries its dim-only helpers too:
~1700 lines of dim_geometry, dim_text_*, format_*,
tolerance, suppression, etc.)
scene/tessellate.rs keeps only the cross-entity dispatcher plus the
shared dim machinery reused by leader/multileader/dimension
(ArrowKind, DimGeom, append_arrow, arrow_from_block, add_segment,
add_polyline, normalized_or, push_tri, color_or_inherit, entity_z,
offset_snap_pts). Cross-entity arc helpers + aci_to_rgba moved to
scene/tess_util.rs.
scene/tessellate.rs shrinks from ~3300 to 809 lines. Compile clean,
all 9 tests pass.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 23:12:27 +03:00
|
|
|
|
.unwrap_or(anno_scale as f64);
|
feat(properties): editable per-object leader dimension overrides
A legacy leader's Lines & Arrows / Text / Fit rows are now editable
per-object overrides of its dimension style, stored in the standard
ACAD_DSTYLE XDATA record (new src/entities/dim_override.rs codec). Arrow
block, arrow size, dim-line lineweight, text offset, vertical text
position and overall scale each prefer an override over the style; the
renderer honours arrow size / block / overall scale and the dim-line
lineweight, so an edited leader redraws at its new arrow and weight.
XDATA edits go through a new dispatch::set_entity_xdata, which registers
the application in the APPID table (the DWG writer drops records for an
unregistered app) and drops that app's stale verbatim EED block (which
otherwise wins over the structured record on a DWG save), so edits and
clears round-trip. The hyperlink editor moves onto this path too.
Dim-line colour stays read-only: it would live in the leader's
override_color, which the file layer doesn't serialise, so making it
editable would silently lose the pick on save. Picking "Closed filled"
writes an explicit null-handle arrow override rather than clearing, so
it sticks even when the style's arrow differs; an unparseable numeric
entry is ignored instead of wiping the stored override.
Note: the DXF entity writer only emits XDATA for hatches, so these
overrides (and hyperlinks) currently persist on DWG save but not DXF —
an acadrust-side gap to close separately.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 00:28:42 +03:00
|
|
|
|
let ovr_asz = dov::real(xd, dov::DIMASZ);
|
|
|
|
|
|
let arrow_size = match (ovr_asz, style) {
|
|
|
|
|
|
(Some(a), _) => (a * dim_scale) as f32,
|
|
|
|
|
|
(None, Some(s)) => (s.dimasz * dim_scale) as f32,
|
|
|
|
|
|
(None, None) => (self.text_height as f32).max(1.0) * anno_scale,
|
refactor(tess): move per-entity tessellation into entities/
Each entity's tessellation now lives alongside its definition in
entities/*.rs, attached to the entity type via a local trait:
LegacyTess — Viewport / Insert / Hatch / Ole2Frame
(fallback path for entities not on the truck pipeline)
LeaderTess — Leader
MultiLeaderTess — MultiLeader
DimensionTess — Dimension (carries its dim-only helpers too:
~1700 lines of dim_geometry, dim_text_*, format_*,
tolerance, suppression, etc.)
scene/tessellate.rs keeps only the cross-entity dispatcher plus the
shared dim machinery reused by leader/multileader/dimension
(ArrowKind, DimGeom, append_arrow, arrow_from_block, add_segment,
add_polyline, normalized_or, push_tri, color_or_inherit, entity_z,
offset_snap_pts). Cross-entity arc helpers + aci_to_rgba moved to
scene/tess_util.rs.
scene/tessellate.rs shrinks from ~3300 to 809 lines. Compile clean,
all 9 tests pass.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 23:12:27 +03:00
|
|
|
|
};
|
feat(properties): editable per-object leader dimension overrides
A legacy leader's Lines & Arrows / Text / Fit rows are now editable
per-object overrides of its dimension style, stored in the standard
ACAD_DSTYLE XDATA record (new src/entities/dim_override.rs codec). Arrow
block, arrow size, dim-line lineweight, text offset, vertical text
position and overall scale each prefer an override over the style; the
renderer honours arrow size / block / overall scale and the dim-line
lineweight, so an edited leader redraws at its new arrow and weight.
XDATA edits go through a new dispatch::set_entity_xdata, which registers
the application in the APPID table (the DWG writer drops records for an
unregistered app) and drops that app's stale verbatim EED block (which
otherwise wins over the structured record on a DWG save), so edits and
clears round-trip. The hyperlink editor moves onto this path too.
Dim-line colour stays read-only: it would live in the leader's
override_color, which the file layer doesn't serialise, so making it
editable would silently lose the pick on save. Picking "Closed filled"
writes an explicit null-handle arrow override rather than clearing, so
it sticks even when the style's arrow differs; an unparseable numeric
entry is ignored instead of wiping the stored override.
Note: the DXF entity writer only emits XDATA for hatches, so these
overrides (and hyperlinks) currently persist on DWG save but not DXF —
an acadrust-side gap to close separately.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 00:28:42 +03:00
|
|
|
|
let arrow_blk = dov::handle(xd, dov::DIMLDRBLK).or_else(|| style.map(|s| s.dimldrblk));
|
|
|
|
|
|
let arrow = match arrow_blk {
|
|
|
|
|
|
Some(h) => arrow_from_block(document, h, arrow_size.max(0.001)),
|
refactor(tess): move per-entity tessellation into entities/
Each entity's tessellation now lives alongside its definition in
entities/*.rs, attached to the entity type via a local trait:
LegacyTess — Viewport / Insert / Hatch / Ole2Frame
(fallback path for entities not on the truck pipeline)
LeaderTess — Leader
MultiLeaderTess — MultiLeader
DimensionTess — Dimension (carries its dim-only helpers too:
~1700 lines of dim_geometry, dim_text_*, format_*,
tolerance, suppression, etc.)
scene/tessellate.rs keeps only the cross-entity dispatcher plus the
shared dim machinery reused by leader/multileader/dimension
(ArrowKind, DimGeom, append_arrow, arrow_from_block, add_segment,
add_polyline, normalized_or, push_tri, color_or_inherit, entity_z,
offset_snap_pts). Cross-entity arc helpers + aci_to_rgba moved to
scene/tess_util.rs.
scene/tessellate.rs shrinks from ~3300 to 809 lines. Compile clean,
all 9 tests pass.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 23:12:27 +03:00
|
|
|
|
None => ArrowKind::Triangle {
|
|
|
|
|
|
size: arrow_size.max(0.001),
|
|
|
|
|
|
filled: true,
|
|
|
|
|
|
size_mul: 1.0,
|
|
|
|
|
|
},
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
let tip = &verts[0];
|
|
|
|
|
|
let next = &verts[1];
|
|
|
|
|
|
let dx = (next.x - tip.x) as f32;
|
|
|
|
|
|
let dy = (next.y - tip.y) as f32;
|
|
|
|
|
|
let len = (dx * dx + dy * dy).sqrt().max(1e-9);
|
|
|
|
|
|
let dir = Vec3::new(dx / len, dy / len, 0.0);
|
|
|
|
|
|
let tip_f = p3(tip);
|
|
|
|
|
|
let tip_v = Vec3::new(tip_f[0], tip_f[1], tip_f[2]);
|
|
|
|
|
|
// Reuse the dim arrow emitter so the leader shape matches the
|
|
|
|
|
|
// DIMSTYLE in use (Closed Filled by default, Dot, Tick, …).
|
|
|
|
|
|
let mut arrow_pts: Vec<[f32; 3]> = Vec::new();
|
|
|
|
|
|
let mut arrow_geom = DimGeom::new();
|
|
|
|
|
|
append_arrow(&mut arrow_geom, tip_v, dir, &arrow);
|
|
|
|
|
|
if !arrow_geom.dim_lines.is_empty() {
|
|
|
|
|
|
arrow_pts.push(nan);
|
|
|
|
|
|
arrow_pts.extend(arrow_geom.dim_lines);
|
|
|
|
|
|
}
|
|
|
|
|
|
points.extend(arrow_pts);
|
|
|
|
|
|
fill_tris.extend(arrow_geom.arrow_fill);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if self.hookline_enabled {
|
|
|
|
|
|
let last = verts.last().unwrap();
|
|
|
|
|
|
let prev = &verts[verts.len() - 2];
|
|
|
|
|
|
let sign = if (last.x - prev.x) >= 0.0 {
|
|
|
|
|
|
1.0_f32
|
|
|
|
|
|
} else {
|
|
|
|
|
|
-1.0_f32
|
|
|
|
|
|
};
|
|
|
|
|
|
let land_len = self.text_height as f32 * 1.5 * anno_scale;
|
|
|
|
|
|
let last_f = p3(last);
|
|
|
|
|
|
points.push(nan);
|
|
|
|
|
|
points.push(last_f);
|
|
|
|
|
|
points.push([last_f[0] + sign * land_len, last_f[1], last_f[2]]);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
WireModel {
|
refactor(text): per-entity SDF text — all text kinds, selection/hover highlight
Rearchitect SDF text from a document-wide collector to per-entity
production during tessellation, so each entity owns its glyph quads and
composite/nested text is covered for free (no re-explosion, no per-frame
document walk).
- WireModel gains `text_verts`: glyph quads ride on the wire, so they are
cached by the tess memo, cloned on hit, and transformed by the block
expand loop exactly like `points`.
- Text arm (tessellate.rs) builds the quads when SDF is on and suppresses
the strokes; render gathers text_verts from the viewport wire set
(`gather_text_verts`, cached on wire content id) — the old collector is
removed. Covers model, dimension, table, block-internal and paper-sheet
text uniformly.
- MLEADER text (lays out via layout_mtext, not the Text arm) gets its own
SDF branch driven by the per-run GlyphRun.
- Pick box comes from the rendered glyph quads (true text extent), not
entity_aabb which mis-places the box for MTEXT; composite paths no longer
clobber the empty text wire's tight AABB (dim pick box hugs the text).
- Selection / hover highlight via a text-highlight overlay (upload_text_
highlight, keyed on selection_generation) mirroring the selected-wire
xray overlay; base glyphs stay neutral so a deselect leaves no stale tint.
- Debug: env OCS_TEXT_BOX draws each run's glyph-bounds rectangle.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 17:01:36 +03:00
|
|
|
|
text_verts: Vec::new(),
|
refactor(tess): move per-entity tessellation into entities/
Each entity's tessellation now lives alongside its definition in
entities/*.rs, attached to the entity type via a local trait:
LegacyTess — Viewport / Insert / Hatch / Ole2Frame
(fallback path for entities not on the truck pipeline)
LeaderTess — Leader
MultiLeaderTess — MultiLeader
DimensionTess — Dimension (carries its dim-only helpers too:
~1700 lines of dim_geometry, dim_text_*, format_*,
tolerance, suppression, etc.)
scene/tessellate.rs keeps only the cross-entity dispatcher plus the
shared dim machinery reused by leader/multileader/dimension
(ArrowKind, DimGeom, append_arrow, arrow_from_block, add_segment,
add_polyline, normalized_or, push_tri, color_or_inherit, entity_z,
offset_snap_pts). Cross-entity arc helpers + aci_to_rgba moved to
scene/tess_util.rs.
scene/tessellate.rs shrinks from ~3300 to 809 lines. Compile clean,
all 9 tests pass.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 23:12:27 +03:00
|
|
|
|
name,
|
|
|
|
|
|
points,
|
2026-06-23 17:08:54 +03:00
|
|
|
|
points_low: Vec::new(),
|
refactor(tess): move per-entity tessellation into entities/
Each entity's tessellation now lives alongside its definition in
entities/*.rs, attached to the entity type via a local trait:
LegacyTess — Viewport / Insert / Hatch / Ole2Frame
(fallback path for entities not on the truck pipeline)
LeaderTess — Leader
MultiLeaderTess — MultiLeader
DimensionTess — Dimension (carries its dim-only helpers too:
~1700 lines of dim_geometry, dim_text_*, format_*,
tolerance, suppression, etc.)
scene/tessellate.rs keeps only the cross-entity dispatcher plus the
shared dim machinery reused by leader/multileader/dimension
(ArrowKind, DimGeom, append_arrow, arrow_from_block, add_segment,
add_polyline, normalized_or, push_tri, color_or_inherit, entity_z,
offset_snap_pts). Cross-entity arc helpers + aci_to_rgba moved to
scene/tess_util.rs.
scene/tessellate.rs shrinks from ~3300 to 809 lines. Compile clean,
all 9 tests pass.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 23:12:27 +03:00
|
|
|
|
color,
|
|
|
|
|
|
selected,
|
|
|
|
|
|
aci: 0,
|
|
|
|
|
|
pattern_length: 0.0,
|
|
|
|
|
|
pattern: [0.0; 8],
|
|
|
|
|
|
line_weight_px,
|
|
|
|
|
|
snap_pts: vec![],
|
|
|
|
|
|
tangent_geoms: tangents,
|
|
|
|
|
|
key_vertices,
|
|
|
|
|
|
aabb: WireModel::UNBOUNDED_AABB,
|
|
|
|
|
|
plinegen: true,
|
|
|
|
|
|
vp_scissor: None,
|
|
|
|
|
|
fill_tris,
|
2026-06-23 18:03:40 +03:00
|
|
|
|
fill_tris_low: Vec::new(),
|
refactor(tess): move per-entity tessellation into entities/
Each entity's tessellation now lives alongside its definition in
entities/*.rs, attached to the entity type via a local trait:
LegacyTess — Viewport / Insert / Hatch / Ole2Frame
(fallback path for entities not on the truck pipeline)
LeaderTess — Leader
MultiLeaderTess — MultiLeader
DimensionTess — Dimension (carries its dim-only helpers too:
~1700 lines of dim_geometry, dim_text_*, format_*,
tolerance, suppression, etc.)
scene/tessellate.rs keeps only the cross-entity dispatcher plus the
shared dim machinery reused by leader/multileader/dimension
(ArrowKind, DimGeom, append_arrow, arrow_from_block, add_segment,
add_polyline, normalized_or, push_tri, color_or_inherit, entity_z,
offset_snap_pts). Cross-entity arc helpers + aci_to_rgba moved to
scene/tess_util.rs.
scene/tessellate.rs shrinks from ~3300 to 809 lines. Compile clean,
all 9 tests pass.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 23:12:27 +03:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|