use fj_interop::Color;
use fj_math::Vector;
use crate::{
geometry::SurfaceGeometry,
objects::{Cycle, Face, Region, Surface},
operations::{
insert::Insert, reverse::Reverse, transform::TransformObject,
},
storage::Handle,
Core,
};
use super::{SweepCache, SweepCycle};
pub trait SweepRegion {
fn sweep_region(
&self,
surface: &Handle<Surface>,
color: Option<Color>,
path: impl Into<Vector<3>>,
cache: &mut SweepCache,
core: &mut Core,
) -> SweptRegion;
}
impl SweepRegion for Region {
fn sweep_region(
&self,
surface: &Handle<Surface>,
color: Option<Color>,
path: impl Into<Vector<3>>,
cache: &mut SweepCache,
core: &mut Core,
) -> SweptRegion {
let path = path.into();
let mut faces = Vec::new();
let top_exterior = sweep_cycle(
self.exterior(),
&core.layers.geometry.of_surface(surface),
color,
&mut faces,
path,
cache,
core,
);
let top_interiors = self
.interiors()
.iter()
.map(|bottom_cycle| {
sweep_cycle(
bottom_cycle,
&core.layers.geometry.of_surface(surface),
color,
&mut faces,
path,
cache,
core,
)
})
.collect::<Vec<_>>();
let top_face = {
let top_surface = surface.translate(path, core).insert(core);
let top_region =
Region::new(top_exterior, top_interiors).insert(core);
Face::new(top_surface, top_region)
};
SweptRegion {
top_face,
side_faces: faces,
}
}
}
fn sweep_cycle(
bottom_cycle: &Cycle,
bottom_surface: &SurfaceGeometry,
color: Option<Color>,
faces: &mut Vec<Face>,
path: Vector<3>,
cache: &mut SweepCache,
core: &mut Core,
) -> Handle<Cycle> {
let swept_cycle = bottom_cycle.reverse(core).sweep_cycle(
bottom_surface,
color,
path,
cache,
core,
);
faces.extend(swept_cycle.faces);
swept_cycle.top_cycle.insert(core)
}
#[derive(Clone)]
pub struct SweptRegion {
pub side_faces: Vec<Face>,
pub top_face: Face,
}
impl SweptRegion {
pub fn all_faces(self) -> impl Iterator<Item = Face> {
self.side_faces.into_iter().chain([self.top_face])
}
}