fj_core/operations/sweep/
sketch.rs1use fj_math::{Scalar, Vector};
2
3use crate::{
4 geometry::GlobalPath,
5 objects::{Face, Sketch, Solid, Surface},
6 operations::{derive::DeriveFrom, insert::Insert, reverse::Reverse},
7 storage::Handle,
8 Core,
9};
10
11use super::{face::SweepFace, SweepCache};
12
13pub trait SweepSketch {
19 fn sweep_sketch(
21 &self,
22 surface: Handle<Surface>,
23 path: impl Into<Vector<3>>,
24 core: &mut Core,
25 ) -> Solid;
26}
27
28impl SweepSketch for Sketch {
29 fn sweep_sketch(
30 &self,
31 surface: Handle<Surface>,
32 path: impl Into<Vector<3>>,
33 core: &mut Core,
34 ) -> Solid {
35 let path = path.into();
36 let mut cache = SweepCache::default();
37
38 let mut shells = Vec::new();
39 for region in self.regions() {
40 let region = {
41 assert!(region
44 .exterior()
45 .winding(&core.layers.geometry)
46 .is_ccw());
47
48 let is_negative_sweep = {
49 let u = match core.layers.geometry.of_surface(&surface).u {
50 GlobalPath::Circle(_) => todo!(
51 "Sweeping sketch from a rounded surfaces is not \
52 supported"
53 ),
54 GlobalPath::Line(line) => line.direction(),
55 };
56 let v = core.layers.geometry.of_surface(&surface).v;
57
58 let normal = u.cross(&v);
59
60 normal.dot(&path) < Scalar::ZERO
61 };
62
63 if is_negative_sweep {
64 region.clone()
65 } else {
66 region.reverse(core).insert(core).derive_from(region, core)
67 }
68 };
69
70 let face = Face::new(surface.clone(), region.clone()).insert(core);
71 let shell = face.sweep_face(path, &mut cache, core).insert(core);
72 shells.push(shell);
73 }
74
75 Solid::new(shells)
76 }
77}