use std::{array, borrow::Borrow};
use fj_interop::ext::ArrayExt;
use fj_math::{Point, Scalar};
use crate::{
objects::{Cycle, Face, HalfEdge, Region, Surface, Vertex},
operations::{
build::{BuildCycle, BuildRegion, BuildSurface},
insert::{Insert, IsInserted, IsInsertedNo},
},
storage::Handle,
Core,
};
pub trait BuildFace {
fn unbound(surface: Handle<Surface>, core: &mut Core) -> Face {
let exterior = Cycle::empty().insert(core);
let region = Region::new(exterior, []).insert(core);
Face::new(surface, region)
}
fn circle(
surface: Handle<Surface>,
center: impl Into<Point<2>>,
radius: impl Into<Scalar>,
core: &mut Core,
) -> Face {
let region = Region::circle(center, radius, core).insert(core);
Face::new(surface, region)
}
fn triangle(
points: [impl Into<Point<3>>; 3],
core: &mut Core,
) -> Polygon<3> {
let (surface, points_surface) =
Surface::plane_from_points(points, core);
let face = Face::polygon(surface, points_surface, core);
let half_edges = {
let mut edges =
face.region().exterior().half_edges().iter().cloned();
let array = array::from_fn(|_| edges.next()).map(|edge| {
edge.expect("Just asserted that there are three edges")
});
assert!(edges.next().is_none());
array
};
let vertices = half_edges
.each_ref_ext()
.map(|edge: &Handle<HalfEdge>| edge.start_vertex().clone());
Polygon {
face,
half_edges,
vertices,
}
}
fn polygon<P, Ps>(
surface: Handle<Surface>,
points: Ps,
core: &mut Core,
) -> Face
where
P: Into<Point<2>>,
Ps: IntoIterator<Item = P>,
Ps::IntoIter: Clone + ExactSizeIterator,
{
let region = Region::polygon(points, core).insert(core);
Face::new(surface, region)
}
}
impl BuildFace for Face {}
pub struct Polygon<const D: usize, I: IsInserted = IsInsertedNo> {
pub face: I::T<Face>,
pub half_edges: [Handle<HalfEdge>; D],
pub vertices: [Handle<Vertex>; D],
}
impl<const D: usize, I: IsInserted> Polygon<D, I> {
pub fn replace_face(&self, face: I::T<Face>) -> Self {
let half_edges = array::from_fn(|i| {
face.borrow()
.region()
.exterior()
.half_edges()
.nth(i)
.expect("Operation should not have changed length of cycle")
.clone()
});
let vertices = array::from_fn(|i| {
face.borrow()
.region()
.exterior()
.half_edges()
.nth(i)
.expect("Operation should not have changed length of cycle")
.start_vertex()
.clone()
});
Self {
face,
half_edges,
vertices,
}
}
}