diff --git a/crates/fj-kernel/src/algorithms/sweep/vertex.rs b/crates/fj-kernel/src/algorithms/sweep/vertex.rs index 558a93fdb..4bf5f662a 100644 --- a/crates/fj-kernel/src/algorithms/sweep/vertex.rs +++ b/crates/fj-kernel/src/algorithms/sweep/vertex.rs @@ -1,120 +1,14 @@ -use fj_math::{Point, Scalar, Vector}; +use fj_math::Vector; use crate::{ - geometry::path::SurfacePath, insert::Insert, - objects::{ - Curve, GlobalCurve, GlobalEdge, GlobalVertex, HalfEdge, Objects, - Surface, SurfaceVertex, - }, + objects::{GlobalCurve, GlobalEdge, GlobalVertex, Objects}, services::Service, storage::Handle, }; use super::{Sweep, SweepCache}; -impl Sweep for (Point<1>, Handle, Handle) { - type Swept = Handle; - - fn sweep_with_cache( - self, - path: impl Into>, - cache: &mut SweepCache, - objects: &mut Service, - ) -> Self::Swept { - let (point, surface_vertex, surface) = self; - let path = path.into(); - - // The result of sweeping a `Vertex` is an `Edge`. Seems - // straight-forward at first, but there are some subtleties we need to - // understand: - // - // 1. To create an `Edge`, we need the `Curve` that defines it. A - // `Curve` is defined in a `Surface`, and we're going to need that to - // create the `Curve`. Which is why this `Sweep` implementation is - // for `(Vertex, Surface)`, and not just for `Vertex`. - // 2. Please note that, while the output `Edge` has two vertices, our - // input `Vertex` is not one of them! It can't be, unless the `Curve` - // of the output `Edge` happens to be the same `Curve` that the input - // `Vertex` is defined on. That would be an edge case that probably - // can't result in anything valid, and we're going to ignore it for - // now. - // 3. This means, we have to compute everything that defines the - // output `Edge`: The `Curve`, the vertices, and the `GlobalCurve`. - // - // Before we get to that though, let's make sure that whoever called - // this didn't give us bad input. - - // So, we're supposed to create the `Edge` by sweeping a `Vertex` using - // `path`. Unless `path` is identical to the path that created the - // `Surface`, this doesn't make any sense. Let's make sure this - // requirement is met. - // - // Further, the `Curve` that was swept to create the `Surface` needs to - // be the same `Curve` that the input `Vertex` is defined on. If it's - // not, we have no way of knowing the surface coordinates of the input - // `Vertex` on the `Surface`, and we're going to need to do that further - // down. There's no way to check for that, unfortunately. - assert_eq!(path, surface.geometry().v); - - // With that out of the way, let's start by creating the `GlobalEdge`, - // as that is the most straight-forward part of this operations, and - // we're going to need it soon anyway. - let (edge_global, vertices_global) = surface_vertex - .global_form() - .clone() - .sweep_with_cache(path, cache, objects); - - // Next, let's compute the surface coordinates of the two vertices of - // the output `Edge`, as we're going to need these for the rest of this - // operation. - // - // They both share a u-coordinate, which is the t-coordinate of our - // input `Vertex`. Remember, we validated above, that the `Curve` of the - // `Surface` and the curve of the input `Vertex` are the same, so we can - // do that. - // - // Now remember what we also validated above: That `path`, which we're - // using to create the output `Edge`, also created the `Surface`, and - // thereby defined its coordinate system. That makes the v-coordinates - // straight-forward: The start of the edge is at zero, the end is at - // one. - let points_surface = [ - Point::from([point.t, Scalar::ZERO]), - Point::from([point.t, Scalar::ONE]), - ]; - - // Armed with those coordinates, creating the `Curve` of the output - // `Edge` is straight-forward. - let curve = { - let (path, _) = SurfacePath::line_from_points(points_surface); - - Curve::new(surface.clone(), path, edge_global.curve().clone()) - .insert(objects) - }; - - let vertices_surface = { - let [_, position] = points_surface; - let [_, global_form] = vertices_global; - - [ - surface_vertex, - SurfaceVertex::new(position, surface, global_form) - .insert(objects), - ] - }; - - // And now the vertices. Again, nothing wild here. - let boundary = vertices_surface.map(|surface_vertex| { - (Point::from([surface_vertex.position().v]), surface_vertex) - }); - - // And finally, creating the output `Edge` is just a matter of - // assembling the pieces we've already created. - HalfEdge::new(curve, boundary, edge_global).insert(objects) - } -} - impl Sweep for Handle { type Swept = (Handle, [Self; 2]); @@ -145,61 +39,3 @@ impl Sweep for Handle { (global_edge, vertices) } } - -#[cfg(test)] -mod tests { - use fj_math::Point; - use pretty_assertions::assert_eq; - - use crate::{ - algorithms::sweep::Sweep, - builder::{CurveBuilder, HalfEdgeBuilder}, - insert::Insert, - partial::{ - Partial, PartialCurve, PartialGlobalVertex, PartialHalfEdge, - PartialObject, PartialSurfaceVertex, - }, - services::Services, - }; - - #[test] - fn vertex_surface() { - let mut services = Services::new(); - - let surface = services.objects.surfaces.xz_plane(); - let (position, surface_vertex) = { - let mut curve = PartialCurve { - surface: Partial::from(surface.clone()), - ..Default::default() - }; - curve.update_as_u_axis(); - - let surface_form = Partial::from_partial(PartialSurfaceVertex { - position: Some(Point::from([0., 0.])), - surface: Partial::from(surface.clone()), - global_form: Partial::from_partial(PartialGlobalVertex { - position: Some(Point::from([0., 0., 0.])), - }), - }) - .build(&mut services.objects); - - (Point::from([0.]), surface_form) - }; - - let half_edge = (position, surface_vertex, surface.clone()) - .sweep([0., 0., 1.], &mut services.objects); - - let expected_half_edge = { - let mut half_edge = PartialHalfEdge::default(); - half_edge.update_as_line_segment_from_points( - surface, - [[0., 0.], [0., 1.]], - ); - - half_edge - .build(&mut services.objects) - .insert(&mut services.objects) - }; - assert_eq!(half_edge, expected_half_edge); - } -}