use fj_math::{Scalar, Vector};
use crate::{
geometry::GlobalPath,
objects::{Face, Sketch, Solid, Surface},
operations::{derive::DeriveFrom, insert::Insert, reverse::Reverse},
storage::Handle,
Core,
};
use super::{face::SweepFace, SweepCache};
pub trait SweepSketch {
fn sweep_sketch(
&self,
surface: Handle<Surface>,
path: impl Into<Vector<3>>,
core: &mut Core,
) -> Solid;
}
impl SweepSketch for Sketch {
fn sweep_sketch(
&self,
surface: Handle<Surface>,
path: impl Into<Vector<3>>,
core: &mut Core,
) -> Solid {
let path = path.into();
let mut cache = SweepCache::default();
let mut shells = Vec::new();
for region in self.regions() {
let region = {
assert!(region
.exterior()
.winding(&core.layers.geometry)
.is_ccw());
let is_negative_sweep = {
let u = match core.layers.geometry.of_surface(&surface).u {
GlobalPath::Circle(_) => todo!(
"Sweeping sketch from a rounded surfaces is not \
supported"
),
GlobalPath::Line(line) => line.direction(),
};
let v = core.layers.geometry.of_surface(&surface).v;
let normal = u.cross(&v);
normal.dot(&path) < Scalar::ZERO
};
if is_negative_sweep {
region.clone()
} else {
region.reverse(core).insert(core).derive_from(region, core)
}
};
let face = Face::new(surface.clone(), region.clone()).insert(core);
let shell = face.sweep_face(path, &mut cache, core).insert(core);
shells.push(shell);
}
Solid::new(shells)
}
}