Skip to main content

geop_lib_sweep/
common.rs

1//! [`Profile`], the named curve chain extrude and revolve sweep, and the
2//! simplest profiles: polygons, polylines and circles. The curves are the
3//! kernel's own (see `geop_core_geometry::nurb_curve`). The topology itself
4//! is described whole and built in one go, see [`crate::sweep`].
5
6use geop_core_geometry::nurb_curve::{NurbCurve2D, sqrt2_over_2};
7use geop_core_math::{geop_error::GeopResult, scalars::Scalar, vector::Vector2};
8
9// ── Profile shapes ───────────────────────────────────────────────────────────
10
11/// The closed polygon through `points` (and back to the first), one line
12/// per side — the simplest profile loop for [`crate::extrude::extrude`].
13pub fn polygon(points: &[Vector2]) -> GeopResult<Vec<NurbCurve2D>> {
14    (0..points.len())
15        .map(|i| NurbCurve2D::line(points[i], points[(i + 1) % points.len()]))
16        .collect()
17}
18
19/// The open chain of lines through `points` — the simplest profile for
20/// [`crate::revolve::revolve_at_oriented`].
21pub fn polyline(points: &[Vector2]) -> GeopResult<Vec<NurbCurve2D>> {
22    points
23        .windows(2)
24        .map(|w| NurbCurve2D::line(w[0], w[1]))
25        .collect()
26}
27
28/// A circle of radius `r` around `(cx, cy)` as four quarter arcs,
29/// counter-clockwise.
30pub fn circle_at(cx: f64, cy: f64, r: f64) -> GeopResult<Vec<NurbCurve2D>> {
31    let at = |x: f64, y: f64| Vector2::from_array([Scalar::from_f64(x), Scalar::from_f64(y)]);
32    let q = [(r, 0.0), (0.0, r), (-r, 0.0), (0.0, -r)];
33    (0..4)
34        .map(|i| {
35            let (a, b) = (q[i], q[(i + 1) % 4]);
36            NurbCurve2D::arc(
37                at(cx + a.0, cy + a.1),
38                at(cx + a.0 + b.0, cy + a.1 + b.1),
39                at(cx + b.0, cy + b.1),
40                sqrt2_over_2(),
41            )
42        })
43        .collect()
44}
45
46/// What the tests of this crate share besides [`crate::shapes`].
47#[cfg(test)]
48pub(crate) mod testing {
49    use geop_core_topology::Model;
50
51    /// Draws `model`'s topology, `resolution` samples per curve, into
52    /// `outputs/{file}`, checking it draws points, lines, faces and labels.
53    pub fn render(model: &Model, resolution: usize, file: &str) {
54        let scene = geop_core_rasterize::debug::rasterize_topology(model, resolution).unwrap();
55        assert!(!scene.points.is_empty());
56        assert!(!scene.lines.is_empty());
57        assert!(!scene.triangles_transparent.is_empty());
58        assert!(!scene.labels.is_empty());
59        std::fs::create_dir_all("outputs").unwrap();
60        scene.save_to_file(&format!("outputs/{file}")).unwrap();
61    }
62}