forked from 1b-agent/opencadstudio-upstream
feat(properties): fill placeholder rows from acadrust fields + doc lookups
Bump acadrust to a46cb8b (spline knot parameterization + mtext line-space style now stored) and populate rows the builders left blank: Entity-local: spline Knot Parameterization + closed-spline Area (shoelace), mtext Line space style, hatch Spacing (pattern-line offset), leader Text offset (annotation offset), region Area + Perimeter (wire-loop approx). Doc-dependent (resolved in app/properties.rs where the document is reachable): insert Block Unit + Unit factor (block record units vs INSUNITS), underlay Name + Path (definition object), leader Text style / vertical placement / overall scale and tolerance Text style (dimension style), multileader Max points + segment angles (mleader style). Rows needing an annotation-scale / sheet-set subsystem or an internal PDF/DWF layer parser are intentionally left blank. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
0a9c27e39d
commit
f50ad0dde4
7 files changed
+258
-8
No files matched your search
@@ -150,7 +150,15 @@ fn properties(h: &Hatch) -> Vec<PropSection> {
|
||||
),
|
||||
ro("Layer override", "layer_override", String::new()),
|
||||
ro("Double", "double", if h.is_double { "Yes" } else { "No" }),
|
||||
ro("Spacing", "spacing", String::new()),
|
||||
ro(
|
||||
"Spacing",
|
||||
"spacing",
|
||||
h.pattern
|
||||
.lines
|
||||
.first()
|
||||
.map(|l| format!("{:.4}", l.offset.length()))
|
||||
.unwrap_or_default(),
|
||||
),
|
||||
ro("ISO pen width", "iso_pen_width", String::new()),
|
||||
ro("Gradient colors", "gradient_colors", g.colors.len().to_string()),
|
||||
ro("Gradient tint", "gradient_tint", format!("{:.4}", g.color_tint)),
|
||||
|
||||
@@ -231,7 +231,11 @@ fn properties(leader: &Leader) -> Vec<PropSection> {
|
||||
|
||||
let text = vec![
|
||||
edit("Text height", "text_height", leader.text_height),
|
||||
ro("Text offset", "text_offset", String::new()),
|
||||
ro(
|
||||
"Text offset",
|
||||
"text_offset",
|
||||
format!("{:.4}", leader.annotation_offset.length()),
|
||||
),
|
||||
ro("Text style", "text_style", String::new()),
|
||||
ro("Text color", "text_color", color_str(&leader.override_color)),
|
||||
ro("Text position vert", "text_pos_vert", String::new()),
|
||||
|
||||
@@ -272,7 +272,14 @@ fn properties(t: &MText, text_style_names: &[String]) -> Vec<PropSection> {
|
||||
"line_space_distance",
|
||||
format!("{line_space_distance:.4}"),
|
||||
),
|
||||
ro("Line space style", "line_space_style", String::new()),
|
||||
ro(
|
||||
"Line space style",
|
||||
"line_space_style",
|
||||
match t.line_spacing_style {
|
||||
acadrust::entities::LineSpacingStyle::Exactly => "Exactly",
|
||||
_ => "At least",
|
||||
},
|
||||
),
|
||||
ro(
|
||||
"Background mask",
|
||||
"background_mask",
|
||||
|
||||
+36
-2
@@ -52,6 +52,39 @@ fn translate_wires(wires: &mut Vec<acadrust::entities::Wire>, d: Vec3) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Approximate a region's enclosed area and boundary perimeter from its
|
||||
/// wireframe loops. Perimeter is the total edge length across every wire.
|
||||
/// Area accumulates the Newell area vector of each loop (opposite-wound
|
||||
/// holes subtract) and halves its magnitude — exact for a single planar
|
||||
/// loop, approximate for multi-loop or curved regions. Returns zeros when
|
||||
/// there is nothing to measure.
|
||||
fn region_area_perimeter(wires: &[acadrust::entities::Wire]) -> (f64, f64) {
|
||||
let mut perimeter = 0.0;
|
||||
let (mut nx, mut ny, mut nz) = (0.0, 0.0, 0.0);
|
||||
for wire in wires {
|
||||
let pts = &wire.points;
|
||||
if pts.len() < 2 {
|
||||
continue;
|
||||
}
|
||||
for seg in pts.windows(2) {
|
||||
let dx = seg[1].x - seg[0].x;
|
||||
let dy = seg[1].y - seg[0].y;
|
||||
let dz = seg[1].z - seg[0].z;
|
||||
perimeter += (dx * dx + dy * dy + dz * dz).sqrt();
|
||||
}
|
||||
let n = pts.len();
|
||||
for i in 0..n {
|
||||
let a = &pts[i];
|
||||
let b = &pts[(i + 1) % n];
|
||||
nx += (a.y - b.y) * (a.z + b.z);
|
||||
ny += (a.z - b.z) * (a.x + b.x);
|
||||
nz += (a.x - b.x) * (a.y + b.y);
|
||||
}
|
||||
}
|
||||
let area = 0.5 * (nx * nx + ny * ny + nz * nz).sqrt();
|
||||
(area, perimeter)
|
||||
}
|
||||
|
||||
// ── Solid3D ───────────────────────────────────────────────────────────────────
|
||||
|
||||
impl Grippable for Solid3D {
|
||||
@@ -132,11 +165,12 @@ impl Grippable for Region {
|
||||
|
||||
impl PropertyEditable for Region {
|
||||
fn geometry_properties(&self, _text_style_names: &[String]) -> Vec<PropSection> {
|
||||
let (area, perimeter) = region_area_perimeter(&self.wires);
|
||||
vec![PropSection {
|
||||
title: "Geometry".into(),
|
||||
props: vec![
|
||||
ro("Area", "rgn_area", String::new()),
|
||||
ro("Perimeter", "rgn_perimeter", String::new()),
|
||||
ro("Area", "rgn_area", format!("{area:.4}")),
|
||||
ro("Perimeter", "rgn_perimeter", format!("{perimeter:.4}")),
|
||||
],
|
||||
}]
|
||||
}
|
||||
|
||||
+26
-2
@@ -133,6 +133,30 @@ fn properties(spline: &Spline) -> Vec<PropSection> {
|
||||
let closed = spline.flags.closed || spline.flags.periodic;
|
||||
let yes_no = |b: bool| if b { "Yes" } else { "No" };
|
||||
|
||||
// Knot parameterization method (R2013+ DWG); older splines report 0.
|
||||
let knot_param = match spline.knot_parameterization {
|
||||
0 => "Chord",
|
||||
1 => "Square Root",
|
||||
2 => "Uniform",
|
||||
_ => "Custom",
|
||||
};
|
||||
|
||||
// Closed splines enclose an area; approximate it with the shoelace
|
||||
// formula over the defining points projected to the XY plane, matching
|
||||
// the polyline approximation already used for Length.
|
||||
let area = if closed && pts.len() >= 3 {
|
||||
let mut acc = 0.0;
|
||||
for w in pts.windows(2) {
|
||||
acc += w[0].x * w[1].y - w[1].x * w[0].y;
|
||||
}
|
||||
if let (Some(first), Some(last)) = (pts.first(), pts.last()) {
|
||||
acc += last.x * first.y - first.x * last.y;
|
||||
}
|
||||
format!("{:.4}", acc.abs() * 0.5)
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
|
||||
vec![
|
||||
PropSection {
|
||||
title: "Data Points".into(),
|
||||
@@ -161,7 +185,7 @@ fn properties(spline: &Spline) -> Vec<PropSection> {
|
||||
format!("{:.4}", cp0.map(|p| p.z).unwrap_or(0.0)),
|
||||
),
|
||||
ro("Weight", "weight", format!("{:.4}", w0.unwrap_or(1.0))),
|
||||
ro("Knot Parameterization", "knot_param", String::new()),
|
||||
ro("Knot Parameterization", "knot_param", knot_param),
|
||||
ro(
|
||||
"Fit Point Count",
|
||||
"fit_pt_count",
|
||||
@@ -198,7 +222,7 @@ fn properties(spline: &Spline) -> Vec<PropSection> {
|
||||
ro("Closed", "closed", yes_no(closed)),
|
||||
ro("Planar", "planar", yes_no(spline.flags.planar)),
|
||||
ro("Length", "length", format!("{length:.4}")),
|
||||
ro("Area", "area", String::new()),
|
||||
ro("Area", "area", area),
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
Reference in new issue
Block a user