refactor(scene/mod.rs): pull entity-specific helpers into entities/
Five chunks moved out of the 5965-line scene/mod.rs to live with the entities they belong to: - wide_lwpolyline_fills → entities/lwpolyline.rs::wide_fills - wide_polyline2d_fills → entities/polyline.rs::wide_fills - polyline_segment_fill → entities/common.rs (shared by both above) - text_obb_corners_native + text_baseline_points + text_greek_obb_tris → entities/text_support.rs (handles Text/MText/Attribute alike) - append_insert_attribute_wires → entities/insert.rs Net: scene/mod.rs 5965 → 5404 lines (~560 lines extracted). Three helpers in scene/render.rs / scene/block_cache.rs widened from pub(super) to pub(crate) so the relocated functions can still reach them. scene::entity_aabb also widened for the same reason. scene::tessellate_entity_dim_text stays put — it's a thin wrapper around the private tessellate_entity dispatcher and moving it would require exposing tessellate_entity's full signature across the crate. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
64d8b2117d
commit
40180e9089
8 changed files with 566 additions and 573 deletions
|
|
@ -167,3 +167,84 @@ pub fn ro_prop(label: &'static str, field: &'static str, value: impl Into<String
|
|||
pub fn parse_f64(value: &str) -> Option<f64> {
|
||||
value.trim().parse::<f64>().ok()
|
||||
}
|
||||
/// Compute the filled boundary polygon for one polyline segment.
|
||||
/// For straight segments: a rectangle/trapezoid.
|
||||
/// For arc segments: an arc band (outer arc + reversed inner arc).
|
||||
/// Returns `None` if the segment is degenerate.
|
||||
pub(crate) fn polyline_segment_fill(
|
||||
p0: [f32; 2],
|
||||
p1: [f32; 2],
|
||||
hw0: f32,
|
||||
hw1: f32,
|
||||
bulge: f32,
|
||||
) -> Option<Vec<[f32; 2]>> {
|
||||
if bulge.abs() < 1e-9 {
|
||||
// Straight segment — rectangle or trapezoid
|
||||
let dx = p1[0] - p0[0];
|
||||
let dy = p1[1] - p0[1];
|
||||
let len = (dx * dx + dy * dy).sqrt();
|
||||
if len < 1e-9 {
|
||||
return None;
|
||||
}
|
||||
let nx = -dy / len;
|
||||
let ny = dx / len;
|
||||
Some(vec![
|
||||
[p0[0] + hw0 * nx, p0[1] + hw0 * ny],
|
||||
[p1[0] + hw1 * nx, p1[1] + hw1 * ny],
|
||||
[p1[0] - hw1 * nx, p1[1] - hw1 * ny],
|
||||
[p0[0] - hw0 * nx, p0[1] - hw0 * ny],
|
||||
])
|
||||
} else {
|
||||
// Arc segment — arc band polygon.
|
||||
// Center math matches `bulge_to_arc` in modules/home/modify/explode.rs:
|
||||
// r = chord * (1 + b²) / (4·|b|)
|
||||
// d = r * (1 - b²) / (1 + b²) (signed: negative ⇒ major arc, center
|
||||
// flips to the opposite side of chord)
|
||||
// center = midpoint + sign(b) · d · left_perp(chord)
|
||||
let b = bulge as f64;
|
||||
let b2 = b * b;
|
||||
let dx = (p1[0] - p0[0]) as f64;
|
||||
let dy = (p1[1] - p0[1]) as f64;
|
||||
let chord_len = (dx * dx + dy * dy).sqrt();
|
||||
if chord_len < 1e-9 || b.abs() < 1e-12 {
|
||||
return None;
|
||||
}
|
||||
let r = chord_len * (1.0 + b2) / (4.0 * b.abs());
|
||||
let d_perp = r * (1.0 - b2) / (1.0 + b2);
|
||||
let mx = ((p0[0] + p1[0]) * 0.5) as f64;
|
||||
let my = ((p0[1] + p1[1]) * 0.5) as f64;
|
||||
let perp_x = -dy / chord_len;
|
||||
let perp_y = dx / chord_len;
|
||||
let sign = b.signum();
|
||||
let cx = (mx + sign * d_perp * perp_x) as f32;
|
||||
let cy = (my + sign * d_perp * perp_y) as f32;
|
||||
let a0 = ((p0[1] - cy) as f32).atan2((p0[0] - cx) as f32);
|
||||
let a1 = ((p1[1] - cy) as f32).atan2((p1[0] - cx) as f32);
|
||||
let (sa, mut ea) = if bulge > 0.0 { (a0, a1) } else { (a1, a0) };
|
||||
if ea < sa {
|
||||
ea += std::f32::consts::TAU;
|
||||
}
|
||||
let span = ea - sa;
|
||||
let segs = ((span.abs() / std::f32::consts::TAU) * 24.0)
|
||||
.ceil()
|
||||
.max(4.0) as u32;
|
||||
let r = r as f32;
|
||||
let r_outer = |t: f32| r + (hw0 + (hw1 - hw0) * t);
|
||||
let r_inner = |t: f32| (r - (hw0 + (hw1 - hw0) * t)).max(0.0);
|
||||
let mut boundary = Vec::with_capacity((segs as usize + 1) * 2);
|
||||
let inv = 1.0 / segs as f32;
|
||||
for j in 0..=segs {
|
||||
let t = j as f32 * inv;
|
||||
let ang = sa + span * t;
|
||||
let ro = r_outer(t);
|
||||
boundary.push([cx + ro * ang.cos(), cy + ro * ang.sin()]);
|
||||
}
|
||||
for j in (0..=segs).rev() {
|
||||
let t = j as f32 * inv;
|
||||
let ang = sa + span * t;
|
||||
let ri = r_inner(t);
|
||||
boundary.push([cx + ri * ang.cos(), cy + ri * ang.sin()]);
|
||||
}
|
||||
Some(boundary)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue