fj_kernel/operations/build/
face.rs1use fj_interop::ext::ArrayExt;
2use fj_math::Point;
3
4use crate::{
5 objects::{Cycle, Face, HalfEdge, Surface, Vertex},
6 operations::{
7 BuildCycle, BuildHalfEdge, BuildSurface, Insert, IsInserted,
8 IsInsertedNo,
9 },
10 services::Services,
11 storage::Handle,
12};
13
14pub trait BuildFace {
16 fn unbound(surface: Handle<Surface>, services: &mut Services) -> Face {
18 let exterior = Cycle::empty().insert(services);
19 Face::new(surface, exterior, [], None)
20 }
21
22 fn triangle(
24 points: [impl Into<Point<3>>; 3],
25 services: &mut Services,
26 ) -> Polygon<3> {
27 let [a, b, c] = points.map(Into::into);
28
29 let surface = Surface::plane_from_points([a, b, c]).insert(services);
30 let (exterior, edges, vertices) = {
31 let half_edges = [[a, b], [b, c], [c, a]].map(|points| {
32 let half_edge = HalfEdge::line_segment_from_global_points(
33 points, &surface, None, services,
34 );
35
36 half_edge.insert(services)
37 });
38 let vertices = half_edges
39 .each_ref_ext()
40 .map(|half_edge| half_edge.start_vertex().clone());
41
42 let cycle = Cycle::new(half_edges.clone()).insert(services);
43
44 (cycle, half_edges, vertices)
45 };
46
47 let face = Face::new(surface, exterior, [], None);
48
49 Polygon {
50 face,
51 edges,
52 vertices,
53 }
54 }
55}
56
57impl BuildFace for Face {}
58
59pub struct Polygon<const D: usize, I: IsInserted = IsInsertedNo> {
67 pub face: I::T<Face>,
69
70 pub edges: [Handle<HalfEdge>; D],
72
73 pub vertices: [Handle<Vertex>; D],
75}