forked from 1b-agent/opencadstudio-upstream
refactor(modify): take plane geometry from cadkernel
TRIM, FILLET and EXPLODE each carried their own copy of the same plane maths. The copies had already drifted apart: `ll` differed only in parameter names between trim.rs and fillet.rs, `arc_pts` only in which angle helper it called, and `norm` meant angle normalisation in trim.rs and explode.rs while meaning vector normalisation in two other files. The implementations now live in cadkernel's geom2d. A new local `geom` module adapts the call shapes — the kernel takes `[f64; 2]` points and returns `[f64; 3]`, while these commands pass loose scalars and feed `WireModel::points`, which is `[f32; 3]`. Narrowing stays on this side because only the caller knows whether it is a preview wire, which leaves `points_low` empty and accepts the loss, or resident geometry, which splits the f64 into a high/low pair instead. Call sites are untouched: the kernel functions are imported under the old local names, so the signatures they were written against still hold. This also fixes ELLIPSE trim and extend previews. `ellipse_pts` wrote its components as [x, z, y] while `arc_pts` — reached from the same match in `entity_pts`, feeding the same `[f32; 3]` — wrote [x, y, z], and `WireModel::points` is documented as world-space positions. Ellipse previews were collapsing onto y = 0 and displacing along Z. The kernel's `ellipse_arc` orders them correctly, so delegating corrects it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
051272ad71
commit
d0cc3284d2
6 files changed
+152
-272
No files matched your search
@@ -0,0 +1,128 @@
|
||||
//! Adapters between the editing commands and `cadkernel`'s plane geometry.
|
||||
//!
|
||||
//! The kernel takes points as `[f64; 2]` and hands tessellation back as
|
||||
//! `[f64; 3]`. The commands here grew up passing loose `x, y` scalars and
|
||||
//! feeding [`WireModel::points`](crate::scene::model::wire_model::WireModel),
|
||||
//! which is `[f32; 3]`. These wrappers absorb that difference in one place so
|
||||
//! the maths itself lives once, in the kernel.
|
||||
//!
|
||||
//! Narrowing to `f32` happens here rather than in the kernel deliberately:
|
||||
//! preview wires leave `points_low` empty, so they accept the loss, while the
|
||||
//! resident render path splits the `f64` into a high/low pair instead. Only a
|
||||
//! caller knows which of the two it is.
|
||||
|
||||
use acadrust::kernel::geom2d::{self, Ellipse};
|
||||
|
||||
/// Re-exported unchanged: these already speak in plain `f64`, so there is no
|
||||
/// call-shape difference for this module to absorb.
|
||||
pub use acadrust::kernel::geom2d::{angle_within_arc, arc_parameter, lerp, normalize_angle};
|
||||
|
||||
/// Preview geometry keeps the density the commands have always used.
|
||||
const SEGMENTS_PER_RADIAN: f64 = geom2d::DEFAULT_SEGMENTS_PER_RADIAN;
|
||||
|
||||
fn narrow(points: Vec<[f64; 3]>) -> Vec<[f32; 3]> {
|
||||
points
|
||||
.into_iter()
|
||||
.map(|p| [p[0] as f32, p[1] as f32, p[2] as f32])
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Where two infinite lines cross, as `(t, u)`; `None` when parallel.
|
||||
///
|
||||
/// Both parameters are unbounded, so EXTEND can use a crossing that lies past
|
||||
/// the end of either line.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn line_line(
|
||||
px: f64,
|
||||
py: f64,
|
||||
dx: f64,
|
||||
dy: f64,
|
||||
qx: f64,
|
||||
qy: f64,
|
||||
ex: f64,
|
||||
ey: f64,
|
||||
) -> Option<(f64, f64)> {
|
||||
geom2d::line_line([px, py], [dx, dy], [qx, qy], [ex, ey])
|
||||
}
|
||||
|
||||
/// Line parameters where `p + t·d` meets a circle: none, one when tangent, or
|
||||
/// two ordered by increasing `t`.
|
||||
pub fn line_circle(px: f64, py: f64, dx: f64, dy: f64, cx: f64, cy: f64, r: f64) -> Vec<f64> {
|
||||
geom2d::line_circle([px, py], [dx, dy], [cx, cy], r)
|
||||
}
|
||||
|
||||
/// Angles **on the first circle** where two circles meet.
|
||||
pub fn circle_circle_angles(cx1: f64, cy1: f64, r1: f64, cx2: f64, cy2: f64, r2: f64) -> Vec<f64> {
|
||||
geom2d::circle_circle_angles([cx1, cy1], r1, [cx2, cy2], r2)
|
||||
}
|
||||
|
||||
/// `(s_on_line, t_on_ellipse)` pairs where a line meets an ellipse.
|
||||
///
|
||||
/// `nx, ny` is the unit major axis.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn line_ellipse(
|
||||
px: f64,
|
||||
py: f64,
|
||||
dx: f64,
|
||||
dy: f64,
|
||||
cx: f64,
|
||||
cy: f64,
|
||||
a: f64,
|
||||
b: f64,
|
||||
nx: f64,
|
||||
ny: f64,
|
||||
) -> Vec<(f64, f64)> {
|
||||
geom2d::line_ellipse(
|
||||
[px, py],
|
||||
[dx, dy],
|
||||
&Ellipse {
|
||||
centre: [cx, cy],
|
||||
major_radius: a,
|
||||
minor_radius: b,
|
||||
major_axis: [nx, ny],
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/// The two endpoints of a straight segment, as render vertices.
|
||||
pub fn line_points(start: [f64; 3], end: [f64; 3]) -> Vec<[f32; 3]> {
|
||||
narrow(vec![start, end])
|
||||
}
|
||||
|
||||
/// A circular arc sampled counter-clockwise, as render vertices.
|
||||
pub fn arc_points(cx: f64, cy: f64, r: f64, a0: f64, a1: f64, z: f64) -> Vec<[f32; 3]> {
|
||||
narrow(geom2d::arc([cx, cy], r, a0, a1, z, SEGMENTS_PER_RADIAN))
|
||||
}
|
||||
|
||||
/// An elliptical arc sampled between two of the ellipse's own parameters, as
|
||||
/// render vertices.
|
||||
///
|
||||
/// Components come back as `[x, y, z]`. The hand-rolled version this replaces
|
||||
/// wrote them as `[x, z, y]`, which flattened ELLIPSE trim previews onto
|
||||
/// `y = 0` and displaced them along Z.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn ellipse_points(
|
||||
cx: f64,
|
||||
cy: f64,
|
||||
a: f64,
|
||||
b: f64,
|
||||
nx: f64,
|
||||
ny: f64,
|
||||
t0: f64,
|
||||
t1: f64,
|
||||
z: f64,
|
||||
) -> Vec<[f32; 3]> {
|
||||
let ellipse = Ellipse {
|
||||
centre: [cx, cy],
|
||||
major_radius: a,
|
||||
minor_radius: b,
|
||||
major_axis: [nx, ny],
|
||||
};
|
||||
narrow(geom2d::ellipse_arc(
|
||||
&ellipse,
|
||||
t0,
|
||||
t1,
|
||||
z,
|
||||
SEGMENTS_PER_RADIAN,
|
||||
))
|
||||
}
|
||||
Reference in new issue
Block a user