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
use fj_math::Point;

use crate::{
    insert::Insert,
    objects::{Face, FaceSet, Objects, Sketch, Surface},
    partial::HasPartial,
    storage::Handle,
};

use super::FaceBuilder;

/// API for building a [`Sketch`]
///
/// Also see [`Sketch::builder`].
pub struct SketchBuilder<'a> {
    /// The stores that the created objects are put in
    pub objects: &'a Objects,

    /// The surface that the [`Sketch`] is defined in
    pub surface: Option<Handle<Surface>>,

    /// The faces that make up the [`Sketch`]
    pub faces: FaceSet,
}

impl<'a> SketchBuilder<'a> {
    /// Build the [`Sketch`] with the provided [`Surface`]
    pub fn with_surface(mut self, surface: Handle<Surface>) -> Self {
        self.surface = Some(surface);
        self
    }

    /// Build the [`Sketch`] with the provided faces
    pub fn with_faces(
        mut self,
        faces: impl IntoIterator<Item = Handle<Face>>,
    ) -> Self {
        self.faces.extend(faces);
        self
    }

    /// Construct a polygon from a list of points
    pub fn with_polygon_from_points(
        mut self,
        points: impl IntoIterator<Item = impl Into<Point<2>>>,
    ) -> Self {
        let surface = self
            .surface
            .as_ref()
            .expect("Can't build `Sketch` without `Surface`");
        self.faces.extend([Face::partial()
            .with_surface(surface.clone())
            .with_exterior_polygon_from_points(points)
            .build(self.objects)
            .unwrap()
            .insert(self.objects)
            .unwrap()]);
        self
    }

    /// Build the [`Sketch`]
    pub fn build(self) -> Handle<Sketch> {
        self.objects
            .sketches
            .insert(Sketch::new(self.faces))
            .unwrap()
    }
}