diff --git a/crates/fj-core/src/algorithms/mod.rs b/crates/fj-core/src/algorithms/mod.rs index 4c5f9ad38..6665e8ba5 100644 --- a/crates/fj-core/src/algorithms/mod.rs +++ b/crates/fj-core/src/algorithms/mod.rs @@ -13,6 +13,5 @@ pub mod approx; pub mod bounding_volume; pub mod intersect; -pub mod sweep; pub mod transform; pub mod triangulate; diff --git a/crates/fj-core/src/operations/mod.rs b/crates/fj-core/src/operations/mod.rs index ea218d6dd..405884c50 100644 --- a/crates/fj-core/src/operations/mod.rs +++ b/crates/fj-core/src/operations/mod.rs @@ -45,4 +45,5 @@ pub mod merge; pub mod replace; pub mod reverse; pub mod split; +pub mod sweep; pub mod update; diff --git a/crates/fj-core/src/algorithms/sweep/face.rs b/crates/fj-core/src/operations/sweep/face.rs similarity index 88% rename from crates/fj-core/src/algorithms/sweep/face.rs rename to crates/fj-core/src/operations/sweep/face.rs index a08a5cb2c..46ac6f3c3 100644 --- a/crates/fj-core/src/algorithms/sweep/face.rs +++ b/crates/fj-core/src/operations/sweep/face.rs @@ -10,13 +10,12 @@ use crate::{ build::BuildCycle, insert::Insert, join::JoinCycle, reverse::Reverse, }, services::Services, - storage::Handle, }; use super::{Sweep, SweepCache}; -impl Sweep for Handle { - type Swept = Handle; +impl Sweep for &Face { + type Swept = Shell; fn sweep_with_cache( self, @@ -41,7 +40,7 @@ impl Sweep for Handle { let mut faces = Vec::new(); - let bottom_face = bottom_face(self, path, services); + let bottom_face = bottom_face(self, path, services).insert(services); faces.push(bottom_face.clone()); let top_surface = @@ -65,12 +64,14 @@ impl Sweep for Handle { let (side_face, top_edge) = ( bottom_half_edge.deref(), - bottom_half_edge_next.start_vertex(), + bottom_half_edge_next.start_vertex().clone(), bottom_face.surface().deref(), bottom_face.region().color(), ) .sweep_with_cache(path, cache, services); + let side_face = side_face.insert(services); + faces.push(side_face); top_edges.push(( @@ -101,19 +102,15 @@ impl Sweep for Handle { let top_face = Face::new(top_surface, top_region).insert(services); faces.push(top_face); - Shell::new(faces).insert(services) + Shell::new(faces) } } -fn bottom_face( - face: Handle, - path: Vector<3>, - services: &mut Services, -) -> Handle { +fn bottom_face(face: &Face, path: Vector<3>, services: &mut Services) -> Face { let is_negative_sweep = { let u = match face.surface().geometry().u { GlobalPath::Circle(_) => todo!( - "Sweeping from faces defined in round surfaces is not \ + "Sweeping from faces defined in rounded surfaces is not \ supported" ), GlobalPath::Line(line) => line.direction(), @@ -126,8 +123,8 @@ fn bottom_face( }; if is_negative_sweep { - face + face.clone() } else { - face.reverse(services).insert(services) + face.reverse(services) } } diff --git a/crates/fj-core/src/algorithms/sweep/edge.rs b/crates/fj-core/src/operations/sweep/half_edge.rs similarity index 76% rename from crates/fj-core/src/algorithms/sweep/edge.rs rename to crates/fj-core/src/operations/sweep/half_edge.rs index fe227d26a..81c92b83d 100644 --- a/crates/fj-core/src/algorithms/sweep/edge.rs +++ b/crates/fj-core/src/operations/sweep/half_edge.rs @@ -4,7 +4,7 @@ use fj_math::{Point, Scalar, Vector}; use crate::{ objects::{Cycle, Face, HalfEdge, Region, Surface, Vertex}, operations::{ - build::BuildHalfEdge, + build::{BuildCycle, BuildHalfEdge}, insert::Insert, update::{UpdateCycle, UpdateHalfEdge}, }, @@ -14,8 +14,8 @@ use crate::{ use super::{Sweep, SweepCache}; -impl Sweep for (&HalfEdge, &Handle, &Surface, Option) { - type Swept = (Handle, Handle); +impl Sweep for (&HalfEdge, Handle, &Surface, Option) { + type Swept = (Face, Handle); fn sweep_with_cache( self, @@ -23,19 +23,20 @@ impl Sweep for (&HalfEdge, &Handle, &Surface, Option) { cache: &mut SweepCache, services: &mut Services, ) -> Self::Swept { - let (edge, next_vertex, surface, color) = self; + let (edge, end_vertex, surface, color) = self; let path = path.into(); - let surface = - (edge.path(), surface).sweep_with_cache(path, cache, services); + let surface = (edge.path(), surface) + .sweep_with_cache(path, cache, services) + .insert(services); // Next, we need to define the boundaries of the face. Let's start with // the global vertices and edges. let (vertices, curves) = { - let [a, b] = [edge.start_vertex(), next_vertex].map(Clone::clone); - let (curve_up, [_, c]) = + let [a, b] = [edge.start_vertex().clone(), end_vertex]; + let (curve_up, c) = b.clone().sweep_with_cache(path, cache, services); - let (curve_down, [_, d]) = + let (curve_down, d) = a.clone().sweep_with_cache(path, cache, services); ( @@ -75,7 +76,7 @@ impl Sweep for (&HalfEdge, &Handle, &Surface, Option) { [[a, b], [c, d], [b, a], [d, c]] }; - let mut exterior = Some(Cycle::new([])); + let mut exterior = Cycle::empty(); // Armed with all of that, we're ready to create the edges. let [_edge_bottom, _edge_up, edge_top, _edge_down] = boundaries @@ -101,21 +102,15 @@ impl Sweep for (&HalfEdge, &Handle, &Surface, Option) { edge.insert(services) }; - exterior = Some( - exterior.take().unwrap().add_half_edges([edge.clone()]), - ); + exterior = exterior.add_half_edges([edge.clone()]); edge }); - let region = Region::new(exterior.unwrap().insert(services), [], color) - .insert(services); - + let exterior = exterior.insert(services); + let region = Region::new(exterior, [], color).insert(services); let face = Face::new(surface, region); - // And we're done creating the face! All that's left to do is build our - // return values. - let face = face.insert(services); (face, edge_top) } } diff --git a/crates/fj-core/src/algorithms/sweep/mod.rs b/crates/fj-core/src/operations/sweep/mod.rs similarity index 98% rename from crates/fj-core/src/algorithms/sweep/mod.rs rename to crates/fj-core/src/operations/sweep/mod.rs index 04d808895..434379648 100644 --- a/crates/fj-core/src/algorithms/sweep/mod.rs +++ b/crates/fj-core/src/operations/sweep/mod.rs @@ -1,7 +1,7 @@ //! Sweeping objects along a path to create new objects -mod edge; mod face; +mod half_edge; mod path; mod sketch; mod vertex; diff --git a/crates/fj-core/src/algorithms/sweep/path.rs b/crates/fj-core/src/operations/sweep/path.rs similarity index 92% rename from crates/fj-core/src/algorithms/sweep/path.rs rename to crates/fj-core/src/operations/sweep/path.rs index 2e1fc85e3..cb5caab04 100644 --- a/crates/fj-core/src/algorithms/sweep/path.rs +++ b/crates/fj-core/src/operations/sweep/path.rs @@ -3,21 +3,19 @@ use fj_math::{Circle, Line, Vector}; use crate::{ geometry::{GlobalPath, SurfaceGeometry, SurfacePath}, objects::Surface, - operations::insert::Insert, services::Services, - storage::Handle, }; use super::{Sweep, SweepCache}; impl Sweep for (SurfacePath, &Surface) { - type Swept = Handle; + type Swept = Surface; fn sweep_with_cache( self, path: impl Into>, _: &mut SweepCache, - services: &mut Services, + _: &mut Services, ) -> Self::Swept { let (curve, surface) = self; @@ -72,6 +70,6 @@ impl Sweep for (SurfacePath, &Surface) { } }; - Surface::new(SurfaceGeometry { u, v: path.into() }).insert(services) + Surface::new(SurfaceGeometry { u, v: path.into() }) } } diff --git a/crates/fj-core/src/algorithms/sweep/sketch.rs b/crates/fj-core/src/operations/sweep/sketch.rs similarity index 75% rename from crates/fj-core/src/algorithms/sweep/sketch.rs rename to crates/fj-core/src/operations/sweep/sketch.rs index bf0e555b3..f5cde015d 100644 --- a/crates/fj-core/src/algorithms/sweep/sketch.rs +++ b/crates/fj-core/src/operations/sweep/sketch.rs @@ -9,8 +9,8 @@ use crate::{ use super::{Sweep, SweepCache}; -impl Sweep for (Handle, Handle) { - type Swept = Handle; +impl Sweep for (&Sketch, Handle) { + type Swept = Solid; fn sweep_with_cache( self, @@ -25,10 +25,12 @@ impl Sweep for (Handle, Handle) { for region in sketch.regions() { let face = Face::new(surface.clone(), region.clone()).insert(services); - let shell = face.sweep_with_cache(path, cache, services); + let shell = face + .sweep_with_cache(path, cache, services) + .insert(services); shells.push(shell); } - Solid::new(shells).insert(services) + Solid::new(shells) } } diff --git a/crates/fj-core/src/algorithms/sweep/vertex.rs b/crates/fj-core/src/operations/sweep/vertex.rs similarity index 81% rename from crates/fj-core/src/algorithms/sweep/vertex.rs rename to crates/fj-core/src/operations/sweep/vertex.rs index 603583ffe..f998d5907 100644 --- a/crates/fj-core/src/algorithms/sweep/vertex.rs +++ b/crates/fj-core/src/operations/sweep/vertex.rs @@ -10,7 +10,7 @@ use crate::{ use super::{Sweep, SweepCache}; impl Sweep for Handle { - type Swept = (Handle, [Self; 2]); + type Swept = (Handle, Self); fn sweep_with_cache( self, @@ -24,14 +24,12 @@ impl Sweep for Handle { .or_insert_with(|| Curve::new().insert(services)) .clone(); - let a = self.clone(); - let b = cache + let vertex = cache .vertices .entry(self.id()) .or_insert_with(|| Vertex::new().insert(services)) .clone(); - let vertices = [a, b]; - (curve, vertices) + (curve, vertex) } } diff --git a/models/cuboid/src/lib.rs b/models/cuboid/src/lib.rs index 8588c2b22..2f6dcf305 100644 --- a/models/cuboid/src/lib.rs +++ b/models/cuboid/src/lib.rs @@ -1,10 +1,10 @@ use fj::{ core::{ - algorithms::sweep::Sweep, objects::{Region, Sketch, Solid}, operations::{ build::{BuildRegion, BuildSketch}, insert::Insert, + sweep::Sweep, update::UpdateSketch, }, services::Services, @@ -14,22 +14,20 @@ use fj::{ }; pub fn model(x: f64, y: f64, z: f64, services: &mut Services) -> Handle { - let sketch = Sketch::empty() - .add_region( - Region::polygon( - [ - [-x / 2., -y / 2.], - [x / 2., -y / 2.], - [x / 2., y / 2.], - [-x / 2., y / 2.], - ], - services, - ) - .insert(services), + let sketch = Sketch::empty().add_region( + Region::polygon( + [ + [-x / 2., -y / 2.], + [x / 2., -y / 2.], + [x / 2., y / 2.], + [-x / 2., y / 2.], + ], + services, ) - .insert(services); + .insert(services), + ); let surface = services.objects.surfaces.xy_plane(); let path = Vector::from([0., 0., z]); - (sketch, surface).sweep(path, services) + (&sketch, surface).sweep(path, services).insert(services) } diff --git a/models/spacer/src/lib.rs b/models/spacer/src/lib.rs index 253a2fc64..586bf0c4b 100644 --- a/models/spacer/src/lib.rs +++ b/models/spacer/src/lib.rs @@ -1,11 +1,11 @@ use fj::{ core::{ - algorithms::sweep::Sweep, objects::{Cycle, Region, Sketch, Solid}, operations::{ build::{BuildCycle, BuildRegion, BuildSketch}, insert::Insert, reverse::Reverse, + sweep::Sweep, update::{UpdateRegion, UpdateSketch}, }, services::Services, @@ -20,21 +20,15 @@ pub fn model( height: f64, services: &mut Services, ) -> Handle { - let sketch = Sketch::empty() - .add_region( - Region::circle(Point::origin(), outer, services) - .add_interiors([Cycle::circle( - Point::origin(), - inner, - services, - ) + let sketch = Sketch::empty().add_region( + Region::circle(Point::origin(), outer, services) + .add_interiors([Cycle::circle(Point::origin(), inner, services) .reverse(services) .insert(services)]) - .insert(services), - ) - .insert(services); + .insert(services), + ); let surface = services.objects.surfaces.xy_plane(); let path = Vector::from([0., 0., height]); - (sketch, surface).sweep(path, services) + (&sketch, surface).sweep(path, services).insert(services) } diff --git a/models/split/src/lib.rs b/models/split/src/lib.rs index f3d7c19ad..3cbdaec53 100644 --- a/models/split/src/lib.rs +++ b/models/split/src/lib.rs @@ -1,11 +1,11 @@ use fj::{ core::{ - algorithms::sweep::Sweep, objects::{Region, Sketch, Solid}, operations::{ build::{BuildRegion, BuildSketch}, insert::Insert, split::SplitFace, + sweep::Sweep, update::{UpdateSketch, UpdateSolid}, }, services::Services, @@ -19,24 +19,22 @@ pub fn model( split_pos: f64, services: &mut Services, ) -> Handle { - let sketch = Sketch::empty() - .add_region( - Region::polygon( - [ - [-size / 2., -size / 2.], - [size / 2., -size / 2.], - [size / 2., size / 2.], - [-size / 2., size / 2.], - ], - services, - ) - .insert(services), + let sketch = Sketch::empty().add_region( + Region::polygon( + [ + [-size / 2., -size / 2.], + [size / 2., -size / 2.], + [size / 2., size / 2.], + [-size / 2., size / 2.], + ], + services, ) - .insert(services); + .insert(services), + ); let surface = services.objects.surfaces.xy_plane(); let path = Vector::from([0., 0., size]); - let solid = (sketch, surface).sweep(path, services); + let solid = (&sketch, surface).sweep(path, services); solid .update_shell(solid.shells().only(), |shell| { diff --git a/models/star/src/lib.rs b/models/star/src/lib.rs index c6ce938c0..b46e7b862 100644 --- a/models/star/src/lib.rs +++ b/models/star/src/lib.rs @@ -2,12 +2,12 @@ use std::f64::consts::PI; use fj::{ core::{ - algorithms::sweep::Sweep, objects::{Cycle, Region, Sketch, Solid}, operations::{ build::{BuildCycle, BuildRegion, BuildSketch}, insert::Insert, reverse::Reverse, + sweep::Sweep, update::{UpdateRegion, UpdateSketch}, }, services::Services, @@ -43,17 +43,15 @@ pub fn model( inner_points.push([x / 2., y / 2.]); } - let sketch = Sketch::empty() - .add_region( - Region::polygon(outer_points, services) - .add_interiors([Cycle::polygon(inner_points, services) - .reverse(services) - .insert(services)]) - .insert(services), - ) - .insert(services); + let sketch = Sketch::empty().add_region( + Region::polygon(outer_points, services) + .add_interiors([Cycle::polygon(inner_points, services) + .reverse(services) + .insert(services)]) + .insert(services), + ); let surface = services.objects.surfaces.xy_plane(); let path = Vector::from([0., 0., h]); - (sketch, surface).sweep(path, services) + (&sketch, surface).sweep(path, services).insert(services) }