fj_core/operations/sweep/
path.rs

1use fj_math::{Circle, Line, Vector};
2
3use crate::{
4    geometry::{GlobalPath, SurfaceGeometry, SurfacePath},
5    objects::Surface,
6    operations::build::BuildSurface,
7    storage::Handle,
8    Core,
9};
10
11/// # Sweep a [`SurfacePath`]
12///
13/// See [module documentation] for more information.
14///
15/// [module documentation]: super
16pub trait SweepSurfacePath {
17    /// # Sweep the surface path
18    ///
19    /// Requires a reference to the surface that the path is defined on.
20    ///
21    ///
22    /// ## Implementation Note
23    ///
24    /// Sweeping a `SurfacePath` that is defined on a curved surface is
25    /// currently not supported:
26    /// <https://github.com/hannobraun/fornjot/issues/1112>
27    fn sweep_surface_path(
28        &self,
29        surface: &SurfaceGeometry,
30        path: impl Into<Vector<3>>,
31        core: &mut Core,
32    ) -> Handle<Surface>;
33}
34
35impl SweepSurfacePath for SurfacePath {
36    fn sweep_surface_path(
37        &self,
38        surface: &SurfaceGeometry,
39        path: impl Into<Vector<3>>,
40        core: &mut Core,
41    ) -> Handle<Surface> {
42        match surface.u {
43            GlobalPath::Circle(_) => {
44                // Sweeping a `Curve` creates a `Surface`. The u-axis of that
45                // `Surface` is a `GlobalPath`, which we are computing below.
46                // That computation might or might not work with an arbitrary
47                // surface. Probably not, but I'm not sure.
48                //
49                // What definitely won't work, is computing the bottom edge of
50                // the sweep. The edge sweeping code currently assumes that the
51                // bottom edge is a line (which is true when sweeping from a
52                // flat surface). But is the surface we're sweeping from is
53                // curved, there's simply no way to represent the curve of the
54                // resulting bottom edge.
55                todo!(
56                    "Sweeping a curve that is defined on a curved surface is \
57                    not supported yet."
58                )
59            }
60            GlobalPath::Line(_) => {
61                // We're sweeping from a curve on a flat surface, which is
62                // supported. Carry on.
63            }
64        }
65
66        let u = match self {
67            SurfacePath::Circle(circle) => {
68                let center = surface.point_from_surface_coords(circle.center());
69                let a = surface.vector_from_surface_coords(circle.a());
70                let b = surface.vector_from_surface_coords(circle.b());
71
72                let circle = Circle::new(center, a, b);
73
74                GlobalPath::Circle(circle)
75            }
76            SurfacePath::Line(line) => {
77                let origin = surface.point_from_surface_coords(line.origin());
78                let direction =
79                    surface.vector_from_surface_coords(line.direction());
80
81                let line = Line::from_origin_and_direction(origin, direction);
82
83                GlobalPath::Line(line)
84            }
85        };
86
87        Surface::surface_from_uv(u, path, core)
88    }
89}