From a8a4a7e404e8b4846be9c616159dcc20c0f38da8 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 28 Nov 2023 17:44:56 +0100 Subject: [PATCH 1/3] Add `SweepFaceOfShell` --- crates/fj-core/src/operations/sweep/mod.rs | 2 + .../src/operations/sweep/shell_face.rs | 65 +++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 crates/fj-core/src/operations/sweep/shell_face.rs diff --git a/crates/fj-core/src/operations/sweep/mod.rs b/crates/fj-core/src/operations/sweep/mod.rs index 17d80e13b..729307455 100644 --- a/crates/fj-core/src/operations/sweep/mod.rs +++ b/crates/fj-core/src/operations/sweep/mod.rs @@ -8,6 +8,7 @@ mod face; mod half_edge; mod path; mod region; +mod shell_face; mod sketch; mod vertex; @@ -17,6 +18,7 @@ pub use self::{ half_edge::SweepHalfEdge, path::SweepSurfacePath, region::SweepRegion, + shell_face::SweepFaceOfShell, sketch::SweepSketch, vertex::SweepVertex, }; diff --git a/crates/fj-core/src/operations/sweep/shell_face.rs b/crates/fj-core/src/operations/sweep/shell_face.rs new file mode 100644 index 000000000..5632c295e --- /dev/null +++ b/crates/fj-core/src/operations/sweep/shell_face.rs @@ -0,0 +1,65 @@ +use fj_math::Vector; + +use crate::{ + objects::{Face, Region, Shell}, + operations::{ + insert::Insert, + reverse::Reverse, + sweep::{SweepCache, SweepRegion}, + update::UpdateShell, + }, + services::Services, + storage::Handle, +}; + +/// # Sweep a [`Face`] that is part of a [`Shell`] +/// +/// See [module documentation] for more information. +/// +/// [module documentation]: super +pub trait SweepFaceOfShell { + /// # Sweep the [`Face`] of the [`Shell`] + /// + /// Extends the shell, adding the new faces to it. + /// + /// # Panics + /// + /// Panics, if the face has interior cycles. This is not a fundamental + /// limitation, but none the less not yet supported. + fn sweep_face_of_shell( + &self, + face: Handle, + path: impl Into>, + services: &mut Services, + ) -> Self; +} + +impl SweepFaceOfShell for Shell { + fn sweep_face_of_shell( + &self, + face: Handle, + path: impl Into>, + services: &mut Services, + ) -> Self { + let path = path.into(); + + if !face.region().interiors().is_empty() { + todo!( + "Sweeping shell faces with interior cycles is not yet \ + supported." + ) + } + + let mut cache = SweepCache::default(); + + let exterior = + face.region().exterior().reverse(services).insert(services); + let region = Region::new(exterior, [], face.region().color()); + let faces = region + .sweep_region(face.surface(), path, &mut cache, services) + .into_iter() + .map(|face| face.insert(services)); + + self.remove_face(&face).add_faces(faces) + } +} From 69caaf94e8ed30c0427dd1aad117af4b18d6eaf6 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 28 Nov 2023 17:52:12 +0100 Subject: [PATCH 2/3] Refactor to prepare for follow-on change --- models/split/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/models/split/src/lib.rs b/models/split/src/lib.rs index 96a8f2e15..c576b72fc 100644 --- a/models/split/src/lib.rs +++ b/models/split/src/lib.rs @@ -46,7 +46,8 @@ pub fn model( (cycle.half_edges().nth(2).unwrap(), [split_pos]), ]; - shell.split_face(face, line, services).0.insert(services) + let (shell, _) = shell.split_face(face, line, services); + shell.insert(services) }) .insert(services) } From ad0e25b439c912d125aedc0c84003c2a1c6bdb6c Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 28 Nov 2023 17:55:15 +0100 Subject: [PATCH 3/3] Sweep half of split face in `split` model --- models/split/src/lib.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/models/split/src/lib.rs b/models/split/src/lib.rs index c576b72fc..d58003683 100644 --- a/models/split/src/lib.rs +++ b/models/split/src/lib.rs @@ -5,7 +5,7 @@ use fj::{ build::{BuildRegion, BuildSketch}, insert::Insert, split::SplitFace, - sweep::SweepSketch, + sweep::{SweepFaceOfShell, SweepSketch}, update::{UpdateSketch, UpdateSolid}, }, services::Services, @@ -46,8 +46,11 @@ pub fn model( (cycle.half_edges().nth(2).unwrap(), [split_pos]), ]; - let (shell, _) = shell.split_face(face, line, services); - shell.insert(services) + let (shell, [face, _]) = shell.split_face(face, line, services); + + shell + .sweep_face_of_shell(face, [0., 0., -size / 2.], services) + .insert(services) }) .insert(services) }