fj_core/operations/sweep/
shell_face.rs

1use fj_math::Vector;
2
3use crate::{
4    objects::{Face, Region, Shell},
5    operations::{
6        derive::DeriveFrom,
7        insert::Insert,
8        presentation::GetColor,
9        reverse::Reverse,
10        sweep::{SweepCache, SweepRegion},
11        update::UpdateShell,
12    },
13    storage::Handle,
14    Core,
15};
16
17/// # Sweep a [`Face`] that is part of a [`Shell`]
18///
19/// See [module documentation] for more information.
20///
21/// [module documentation]: super
22pub trait SweepFaceOfShell {
23    /// # Sweep the [`Face`] of the [`Shell`]
24    ///
25    /// Extends the shell, adding the new faces to it.
26    ///
27    /// # Limitation
28    ///
29    ///  When generating new faces, these must NOT coincide with any existing faces in the shell.
30    ///
31    /// # Panics
32    ///
33    /// Panics, if the face has interior cycles. This is not a fundamental
34    /// limitation, but none the less not yet supported.
35    fn sweep_face_of_shell(
36        &self,
37        face: Handle<Face>,
38        path: impl Into<Vector<3>>,
39        core: &mut Core,
40    ) -> ShellExtendedBySweep;
41}
42
43impl SweepFaceOfShell for Shell {
44    fn sweep_face_of_shell(
45        &self,
46        face: Handle<Face>,
47        path: impl Into<Vector<3>>,
48        core: &mut Core,
49    ) -> ShellExtendedBySweep {
50        let path = path.into();
51
52        if !face.region().interiors().is_empty() {
53            todo!(
54                "Sweeping shell faces with interior cycles is not yet \
55                supported."
56            )
57        }
58
59        let mut cache = SweepCache::default();
60
61        let exterior = face
62            .region()
63            .exterior()
64            .reverse(core)
65            .insert(core)
66            .derive_from(face.region().exterior(), core);
67        let region = Region::new(exterior, []);
68        let swept_region = region.sweep_region(
69            face.surface(),
70            face.region().get_color(core),
71            path,
72            &mut cache,
73            core,
74        );
75
76        let shell = self
77            .remove_face(&face)
78            .add_faces(swept_region.clone().all_faces(), core);
79
80        ShellExtendedBySweep {
81            shell,
82            side_faces: swept_region.side_faces,
83            top_face: swept_region.top_face,
84        }
85    }
86}
87
88/// The result of sweeping a [`Face`] of a [`Shell`]
89///
90/// See [`SweepFaceOfShell`].
91pub struct ShellExtendedBySweep {
92    /// The resulting shell after the sweep
93    pub shell: Shell,
94
95    /// The side faces created by the sweep
96    pub side_faces: Vec<Face>,
97
98    /// The top face created by the sweep
99    pub top_face: Face,
100}