1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
use std::ops::Deref;

use fj_math::Point;

use crate::objects::{Cycle, Face, Surface};

/// API for building a [`Face`]
pub struct FaceBuilder {
    surface: Surface,
}

impl FaceBuilder {
    /// Construct an instance of `FaceBuilder`
    ///
    /// Also see [`Face::build`].
    pub fn new(surface: Surface) -> Self {
        Self { surface }
    }

    /// Construct a polygon from a list of points
    pub fn polygon_from_points(
        &self,
        points: impl IntoIterator<Item = impl Into<Point<2>>>,
    ) -> FacePolygon {
        let cycle = Cycle::build(self.surface).polygon_from_points(points);
        let face = Face::new(self.surface, cycle);

        FacePolygon { face }
    }
}

/// A polygon
#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct FacePolygon {
    face: Face,
}

impl FacePolygon {
    /// Add a hole to the polygon
    pub fn with_hole(
        mut self,
        points: impl IntoIterator<Item = impl Into<Point<2>>>,
    ) -> Self {
        let surface = *self.face.surface();
        self.face = self.face.with_interiors([
            Cycle::build(surface).polygon_from_points(points)
        ]);

        self
    }

    /// Consume the `Polygon` and return the [`Face`] it wraps
    pub fn into_face(self) -> Face {
        self.face
    }
}

impl From<FacePolygon> for Face {
    fn from(polygon: FacePolygon) -> Self {
        polygon.into_face()
    }
}

impl Deref for FacePolygon {
    type Target = Face;

    fn deref(&self) -> &Self::Target {
        &self.face
    }
}