fj_core/operations/build/
face.rs1use std::{array, borrow::Borrow};
2
3use fj_interop::ext::ArrayExt;
4use fj_math::{Point, Scalar};
5
6use crate::{
7 objects::{Cycle, Face, HalfEdge, Region, Surface, Vertex},
8 operations::{
9 build::{BuildCycle, BuildRegion, BuildSurface},
10 insert::{Insert, IsInserted, IsInsertedNo},
11 },
12 storage::Handle,
13 Core,
14};
15
16pub trait BuildFace {
22 fn unbound(surface: Handle<Surface>, core: &mut Core) -> Face {
24 let exterior = Cycle::empty().insert(core);
25 let region = Region::new(exterior, []).insert(core);
26 Face::new(surface, region)
27 }
28
29 fn circle(
31 surface: Handle<Surface>,
32 center: impl Into<Point<2>>,
33 radius: impl Into<Scalar>,
34 core: &mut Core,
35 ) -> Face {
36 let region = Region::circle(center, radius, core).insert(core);
37 Face::new(surface, region)
38 }
39
40 fn triangle(
42 points: [impl Into<Point<3>>; 3],
43 core: &mut Core,
44 ) -> Polygon<3> {
45 let (surface, points_surface) =
46 Surface::plane_from_points(points, core);
47
48 let face = Face::polygon(surface, points_surface, core);
49
50 let half_edges = {
51 let mut edges =
52 face.region().exterior().half_edges().iter().cloned();
53
54 let array = array::from_fn(|_| edges.next()).map(|edge| {
55 edge.expect("Just asserted that there are three edges")
56 });
57
58 assert!(edges.next().is_none());
59
60 array
61 };
62 let vertices = half_edges
63 .each_ref_ext()
64 .map(|edge: &Handle<HalfEdge>| edge.start_vertex().clone());
65
66 Polygon {
67 face,
68 half_edges,
69 vertices,
70 }
71 }
72
73 fn polygon<P, Ps>(
75 surface: Handle<Surface>,
76 points: Ps,
77 core: &mut Core,
78 ) -> Face
79 where
80 P: Into<Point<2>>,
81 Ps: IntoIterator<Item = P>,
82 Ps::IntoIter: Clone + ExactSizeIterator,
83 {
84 let region = Region::polygon(points, core).insert(core);
85 Face::new(surface, region)
86 }
87}
88
89impl BuildFace for Face {}
90
91pub struct Polygon<const D: usize, I: IsInserted = IsInsertedNo> {
99 pub face: I::T<Face>,
101
102 pub half_edges: [Handle<HalfEdge>; D],
104
105 pub vertices: [Handle<Vertex>; D],
107}
108
109impl<const D: usize, I: IsInserted> Polygon<D, I> {
110 pub fn replace_face(&self, face: I::T<Face>) -> Self {
115 let half_edges = array::from_fn(|i| {
116 face.borrow()
117 .region()
118 .exterior()
119 .half_edges()
120 .nth(i)
121 .expect("Operation should not have changed length of cycle")
122 .clone()
123 });
124 let vertices = array::from_fn(|i| {
125 face.borrow()
129 .region()
130 .exterior()
131 .half_edges()
132 .nth(i)
133 .expect("Operation should not have changed length of cycle")
134 .start_vertex()
135 .clone()
136 });
137
138 Self {
139 face,
140 half_edges,
141 vertices,
142 }
143 }
144}