use fj_math::Point;
use crate::{
objects::{Face, Shell},
operations::{
BuildFace, Insert, IsInserted, IsInsertedNo, IsInsertedYes, JoinCycle,
Polygon, UpdateFace,
},
services::Services,
};
pub trait BuildShell {
fn tetrahedron(
points: [impl Into<Point<3>>; 4],
services: &mut Services,
) -> TetrahedronShell {
let [a, b, c, d] = points.map(Into::into);
let abc = Face::triangle([a, b, c], services);
let bad =
Face::triangle([b, a, d], services).update_exterior(|cycle| {
cycle
.join_to(abc.face.exterior(), 0..=0, 0..=0, services)
.insert(services)
});
let dac =
Face::triangle([d, a, c], services).update_exterior(|cycle| {
cycle
.join_to(abc.face.exterior(), 1..=1, 2..=2, services)
.join_to(bad.face.exterior(), 0..=0, 1..=1, services)
.insert(services)
});
let cbd =
Face::triangle([c, b, d], services).update_exterior(|cycle| {
cycle
.join_to(abc.face.exterior(), 0..=0, 1..=1, services)
.join_to(bad.face.exterior(), 1..=1, 2..=2, services)
.join_to(dac.face.exterior(), 2..=2, 2..=2, services)
.insert(services)
});
let triangles =
[abc, bad, dac, cbd].map(|triangle| triangle.insert(services));
let shell =
Shell::new(triangles.iter().map(|triangle| triangle.face.clone()));
let [abc, bad, dac, cbd] = triangles;
TetrahedronShell {
shell,
abc,
bad,
dac,
cbd,
}
}
}
impl BuildShell for Shell {}
pub struct TetrahedronShell<I: IsInserted = IsInsertedNo> {
pub shell: I::T<Shell>,
pub abc: Polygon<3, IsInsertedYes>,
pub bad: Polygon<3, IsInsertedYes>,
pub dac: Polygon<3, IsInsertedYes>,
pub cbd: Polygon<3, IsInsertedYes>,
}