Struct fj_kernel::partial::Partial

source ·
pub struct Partial<T: HasPartial> { /* private fields */ }
Expand description

Wrapper around a partial object

Controls access to the partial object. Can be cloned, to access the same partial object from multiple locations.

Implementations§

Construct a Partial with a default inner partial object

Examples found in repository?
src/partial/wrapper.rs (line 147)
146
147
148
    fn default() -> Self {
        Self::new()
    }
More examples
Hide additional examples
src/partial/objects/vertex.rs (line 57)
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
    fn default() -> Self {
        let surface = Partial::new();

        let curve = Partial::from_partial(PartialCurve {
            surface: surface.clone(),
            ..Default::default()
        });
        let surface_form = Partial::from_partial(PartialSurfaceVertex {
            surface,
            ..Default::default()
        });

        Self {
            position: None,
            curve,
            surface_form,
        }
    }
src/partial/objects/edge.rs (line 84)
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
    fn default() -> Self {
        let curve = Partial::<Curve>::new();

        let vertices = array::from_fn(|_| {
            Partial::from_partial(PartialVertex {
                curve: curve.clone(),
                ..Default::default()
            })
        });

        let global_curve = curve.read().global_form.clone();
        let global_vertices =
            vertices.each_ref_ext().map(|vertex: &Partial<Vertex>| {
                let surface_vertex = vertex.read().surface_form.clone();
                let global_vertex = surface_vertex.read().global_form.clone();
                global_vertex
            });

        let global_form = Partial::from_partial(PartialGlobalEdge {
            curve: global_curve,
            vertices: global_vertices,
        });

        Self {
            vertices,
            global_form,
        }
    }
src/builder/cycle.rs (line 83)
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
    fn add_half_edge(&mut self) -> Partial<HalfEdge> {
        let mut new_half_edge = Partial::<HalfEdge>::new();

        let (first_half_edge, mut last_half_edge) =
            match self.half_edges.first() {
                Some(first_half_edge) => {
                    let first_half_edge = first_half_edge.clone();
                    let last_half_edge = self
                        .half_edges
                        .last()
                        .cloned()
                        .unwrap_or_else(|| first_half_edge.clone());

                    (first_half_edge, last_half_edge)
                }
                None => (new_half_edge.clone(), new_half_edge.clone()),
            };

        {
            let shared_surface_vertex =
                new_half_edge.read().back().read().surface_form.clone();

            let mut last_half_edge = last_half_edge.write();

            last_half_edge.front_mut().write().surface_form =
                shared_surface_vertex;
            last_half_edge.infer_global_form();
        }

        {
            let shared_surface_vertex =
                first_half_edge.read().back().read().surface_form.clone();
            let shared_surface = shared_surface_vertex.read().surface.clone();

            let mut new_half_edge = new_half_edge.write();

            new_half_edge.front_mut().write().surface_form =
                shared_surface_vertex;
            new_half_edge.replace_surface(shared_surface);
            new_half_edge.infer_global_form();
        }

        self.half_edges.push(new_half_edge.clone());
        new_half_edge
    }

Construct a Partial from a partial object

Examples found in repository?
src/partial/wrapper.rs (line 33)
32
33
34
    pub fn new() -> Self {
        Self::from_partial(T::Partial::default())
    }
More examples
Hide additional examples
src/builder/solid.rs (line 29)
22
23
24
25
26
27
28
29
30
    fn with_cube_from_edge_length(
        &mut self,
        edge_length: impl Into<Scalar>,
        objects: &mut Service<Objects>,
    ) {
        let shell =
            PartialShell::create_cube_from_edge_length(edge_length, objects);
        self.shells.push(Partial::from_partial(shell));
    }
src/builder/sketch.rs (line 29)
21
22
23
24
25
26
27
28
29
30
    fn add_polygon_from_points(
        &mut self,
        surface: impl Into<Partial<Surface>>,
        points: impl IntoIterator<Item = impl Into<Point<2>>>,
    ) {
        let mut face = PartialFace::default();
        face.update_exterior_as_polygon(surface, points);

        self.faces.extend([Partial::from_partial(face)]);
    }
src/builder/face.rs (line 36)
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
    fn update_exterior_as_polygon(
        &mut self,
        surface: impl Into<Partial<Surface>>,
        points: impl IntoIterator<Item = impl Into<Point<2>>>,
    ) -> Vec<Partial<HalfEdge>> {
        let mut cycle = PartialCycle::default();
        let half_edges = cycle.update_as_polygon_from_points(surface, points);

        self.exterior = Partial::from_partial(cycle);

        half_edges
    }

    fn add_interior_polygon(
        &mut self,
        surface: impl Into<Partial<Surface>>,
        points: impl IntoIterator<Item = impl Into<Point<2>>>,
    ) {
        let mut cycle = PartialCycle::default();
        cycle.update_as_polygon_from_points(surface, points);

        self.interiors.push(Partial::from_partial(cycle));
    }
src/partial/objects/vertex.rs (lines 59-62)
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
    fn default() -> Self {
        let surface = Partial::new();

        let curve = Partial::from_partial(PartialCurve {
            surface: surface.clone(),
            ..Default::default()
        });
        let surface_form = Partial::from_partial(PartialSurfaceVertex {
            surface,
            ..Default::default()
        });

        Self {
            position: None,
            curve,
            surface_form,
        }
    }
src/partial/objects/edge.rs (lines 87-90)
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
    fn default() -> Self {
        let curve = Partial::<Curve>::new();

        let vertices = array::from_fn(|_| {
            Partial::from_partial(PartialVertex {
                curve: curve.clone(),
                ..Default::default()
            })
        });

        let global_curve = curve.read().global_form.clone();
        let global_vertices =
            vertices.each_ref_ext().map(|vertex: &Partial<Vertex>| {
                let surface_vertex = vertex.read().surface_form.clone();
                let global_vertex = surface_vertex.read().global_form.clone();
                global_vertex
            });

        let global_form = Partial::from_partial(PartialGlobalEdge {
            curve: global_curve,
            vertices: global_vertices,
        });

        Self {
            vertices,
            global_form,
        }
    }

Construct a partial from a full object

Examples found in repository?
src/partial/wrapper.rs (line 154)
152
153
154
155
    fn from(full: Handle<T>) -> Self {
        let mut cache = FullToPartialCache::default();
        Self::from_full(full, &mut cache)
    }
More examples
Hide additional examples
src/partial/objects/solid.rs (line 21)
17
18
19
20
21
22
23
24
    fn from_full(solid: &Self::Full, cache: &mut FullToPartialCache) -> Self {
        Self {
            shells: solid
                .shells()
                .map(|shell| Partial::from_full(shell.clone(), cache))
                .collect(),
        }
    }
src/partial/objects/shell.rs (line 22)
17
18
19
20
21
22
23
24
25
    fn from_full(shell: &Self::Full, cache: &mut FullToPartialCache) -> Self {
        Self {
            faces: shell
                .faces()
                .into_iter()
                .map(|face| Partial::from_full(face.clone(), cache))
                .collect(),
        }
    }
src/partial/objects/sketch.rs (line 22)
17
18
19
20
21
22
23
24
25
    fn from_full(sketch: &Self::Full, cache: &mut FullToPartialCache) -> Self {
        Self {
            faces: sketch
                .faces()
                .into_iter()
                .map(|face| Partial::from_full(face.clone(), cache))
                .collect(),
        }
    }
src/partial/objects/cycle.rs (line 31)
26
27
28
29
30
31
32
33
34
    fn from_full(cycle: &Self::Full, cache: &mut FullToPartialCache) -> Self {
        Self {
            half_edges: cycle
                .half_edges()
                .cloned()
                .map(|half_edge| Partial::from_full(half_edge, cache))
                .collect(),
        }
    }
src/partial/objects/curve.rs (line 27)
24
25
26
27
28
29
30
    fn from_full(curve: &Self::Full, cache: &mut FullToPartialCache) -> Self {
        Self {
            path: Some(curve.path()),
            surface: Partial::from_full(curve.surface().clone(), cache),
            global_form: Partial::from_full(curve.global_form().clone(), cache),
        }
    }

Access the ID of this partial object

Examples found in repository?
src/partial/wrapper.rs (line 124)
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let name = {
            let type_name = type_name::<T::Partial>();
            match type_name.rsplit_once("::") {
                Some((_, name)) => name,
                None => type_name,
            }
        };
        let id = self.id().0;
        let object = self.read().clone();

        if f.alternate() {
            write!(f, "{name} @ {id:#x} => {object:#?}")?;
        } else {
            write!(f, "{name} @ {id:#x}")?;
        }

        Ok(())
    }

Access the partial object

Examples found in repository?
src/partial/objects/edge.rs (line 27)
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
    pub fn curve(&self) -> Partial<Curve> {
        let [vertex, _] = &self.vertices;
        vertex.read().curve.clone()
    }

    /// Access a reference to the half-edge's back vertex
    pub fn back(&self) -> &Partial<Vertex> {
        let [back, _] = &self.vertices;
        back
    }

    /// Access a reference to the half-edge's front vertex
    pub fn front(&self) -> &Partial<Vertex> {
        let [_, front] = &self.vertices;
        front
    }

    /// Access a mutable reference to the half-edge's back vertex
    pub fn back_mut(&mut self) -> &mut Partial<Vertex> {
        let [back, _] = &mut self.vertices;
        back
    }

    /// Access a mutable reference to the half-edge's front vertex
    pub fn front_mut(&mut self) -> &mut Partial<Vertex> {
        let [_, front] = &mut self.vertices;
        front
    }
}

impl PartialObject for PartialHalfEdge {
    type Full = HalfEdge;

    fn from_full(
        half_edge: &Self::Full,
        cache: &mut FullToPartialCache,
    ) -> Self {
        Self {
            vertices: half_edge
                .vertices()
                .clone()
                .map(|vertex| Partial::from_full(vertex, cache)),
            global_form: Partial::from_full(
                half_edge.global_form().clone(),
                cache,
            ),
        }
    }

    fn build(self, objects: &mut Service<Objects>) -> Self::Full {
        let vertices = self.vertices.map(|vertex| vertex.build(objects));
        let global_form = self.global_form.build(objects);

        HalfEdge::new(vertices, global_form)
    }
}

impl Default for PartialHalfEdge {
    fn default() -> Self {
        let curve = Partial::<Curve>::new();

        let vertices = array::from_fn(|_| {
            Partial::from_partial(PartialVertex {
                curve: curve.clone(),
                ..Default::default()
            })
        });

        let global_curve = curve.read().global_form.clone();
        let global_vertices =
            vertices.each_ref_ext().map(|vertex: &Partial<Vertex>| {
                let surface_vertex = vertex.read().surface_form.clone();
                let global_vertex = surface_vertex.read().global_form.clone();
                global_vertex
            });

        let global_form = Partial::from_partial(PartialGlobalEdge {
            curve: global_curve,
            vertices: global_vertices,
        });

        Self {
            vertices,
            global_form,
        }
    }
More examples
Hide additional examples
src/partial/objects/cycle.rs (line 19)
16
17
18
19
20
    pub fn surface(&self) -> Option<Partial<Surface>> {
        self.half_edges
            .first()
            .map(|half_edge| half_edge.read().curve().read().surface.clone())
    }
src/partial/wrapper.rs (line 125)
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let name = {
            let type_name = type_name::<T::Partial>();
            match type_name.rsplit_once("::") {
                Some((_, name)) => name,
                None => type_name,
            }
        };
        let id = self.id().0;
        let object = self.read().clone();

        if f.alternate() {
            write!(f, "{name} @ {id:#x} => {object:#?}")?;
        } else {
            write!(f, "{name} @ {id:#x}")?;
        }

        Ok(())
    }
src/builder/vertex.rs (line 48)
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
    fn infer_global_position(&mut self) -> Point<3> {
        let position_surface = self
            .position
            .expect("Can't infer global position without surface position");
        let surface = self
            .surface
            .read()
            .geometry
            .expect("Can't infer global position without surface geometry");

        let position_global =
            surface.point_from_surface_coords(position_surface);
        self.global_form.write().position = Some(position_global);

        position_global
    }
src/partial/objects/vertex.rs (line 44)
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
    fn build(mut self, objects: &mut Service<Objects>) -> Self::Full {
        let position = self
            .position
            .expect("Can't build `Vertex` without position");
        let curve = self.curve.build(objects);

        // Infer surface position, if not available.
        if self.surface_form.read().position.is_none() {
            self.surface_form.write().position =
                Some(curve.path().point_from_path_coords(position));
        }

        let surface_form = self.surface_form.build(objects);

        Vertex::new(position, curve, surface_form)
    }
}

impl Default for PartialVertex {
    fn default() -> Self {
        let surface = Partial::new();

        let curve = Partial::from_partial(PartialCurve {
            surface: surface.clone(),
            ..Default::default()
        });
        let surface_form = Partial::from_partial(PartialSurfaceVertex {
            surface,
            ..Default::default()
        });

        Self {
            position: None,
            curve,
            surface_form,
        }
    }
}

/// A partial [`SurfaceVertex`]
#[derive(Clone, Debug, Default)]
pub struct PartialSurfaceVertex {
    /// The position of the vertex on the surface
    pub position: Option<Point<2>>,

    /// The surface that the vertex is defined in
    pub surface: Partial<Surface>,

    /// The global form of the vertex
    pub global_form: Partial<GlobalVertex>,
}

impl PartialObject for PartialSurfaceVertex {
    type Full = SurfaceVertex;

    fn from_full(
        surface_vertex: &Self::Full,
        cache: &mut FullToPartialCache,
    ) -> Self {
        Self {
            position: Some(surface_vertex.position()),
            surface: Partial::from_full(
                surface_vertex.surface().clone(),
                cache,
            ),
            global_form: Partial::from_full(
                surface_vertex.global_form().clone(),
                cache,
            ),
        }
    }

    fn build(mut self, objects: &mut Service<Objects>) -> Self::Full {
        if self.global_form.read().position.is_none() {
            self.infer_global_position();
        }

        let position = self
            .position
            .expect("Can't build `SurfaceVertex` without position");
        let surface = self.surface.build(objects);
        let global_form = self.global_form.build(objects);

        SurfaceVertex::new(position, surface, global_form)
    }
src/builder/edge.rs (line 57)
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
    fn update_as_circle_from_radius(&mut self, radius: impl Into<Scalar>) {
        let mut curve = self.curve();
        curve.write().update_as_circle_from_radius(radius);

        let path = curve
            .read()
            .path
            .expect("Expected path that was just created");

        let [a_curve, b_curve] =
            [Scalar::ZERO, Scalar::TAU].map(|coord| Point::from([coord]));

        let mut surface_vertex = {
            let [vertex, _] = &mut self.vertices;
            vertex.write().surface_form.clone()
        };
        surface_vertex.write().position =
            Some(path.point_from_path_coords(a_curve));

        for (vertex, point_curve) in
            self.vertices.each_mut_ext().zip_ext([a_curve, b_curve])
        {
            let mut vertex = vertex.write();
            vertex.position = Some(point_curve);
            vertex.surface_form = surface_vertex.clone();
        }

        self.infer_global_form();
    }

    fn update_as_line_segment_from_points(
        &mut self,
        surface: impl Into<Partial<Surface>>,
        points: [impl Into<Point<2>>; 2],
    ) {
        let surface = surface.into();

        for (vertex, point) in self.vertices.each_mut_ext().zip_ext(points) {
            let mut vertex = vertex.write();
            vertex.curve.write().surface = surface.clone();

            let mut surface_form = vertex.surface_form.write();
            surface_form.position = Some(point.into());
            surface_form.surface = surface.clone();
        }

        self.update_as_line_segment()
    }

    fn update_as_line_segment(&mut self) {
        let points_surface = self.vertices.each_ref_ext().map(|vertex| {
            vertex
                .read()
                .surface_form
                .read()
                .position
                .expect("Can't infer line segment without surface position")
        });

        self.curve()
            .write()
            .update_as_line_from_points(points_surface);

        for (vertex, position) in self.vertices.each_mut_ext().zip_ext([0., 1.])
        {
            vertex.write().position = Some([position].into());
        }

        self.infer_global_form();
    }

    fn infer_global_form(&mut self) -> Partial<GlobalEdge> {
        self.global_form.write().curve =
            self.curve().read().global_form.clone();
        self.global_form.write().vertices =
            self.vertices.each_ref_ext().map(|vertex| {
                vertex.read().surface_form.read().global_form.clone()
            });

        self.global_form.clone()
    }

Access the partial object mutably

Panics

Panics, if this method is called while the return value from a previous call to this method of Self::read is still borrowed.

Examples found in repository?
src/builder/vertex.rs (line 27)
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
    fn replace_surface(&mut self, surface: impl Into<Partial<Surface>>) {
        let surface = surface.into();

        self.curve.write().surface = surface.clone();
        self.surface_form.write().surface = surface;
    }
}

/// Builder API for [`PartialSurfaceVertex`]
pub trait SurfaceVertexBuilder {
    /// Infer the position of the surface vertex' global form
    ///
    /// Updates the global vertex referenced by this surface vertex with the
    /// inferred position, and also returns the position.
    fn infer_global_position(&mut self) -> Point<3>;
}

impl SurfaceVertexBuilder for PartialSurfaceVertex {
    fn infer_global_position(&mut self) -> Point<3> {
        let position_surface = self
            .position
            .expect("Can't infer global position without surface position");
        let surface = self
            .surface
            .read()
            .geometry
            .expect("Can't infer global position without surface geometry");

        let position_global =
            surface.point_from_surface_coords(position_surface);
        self.global_form.write().position = Some(position_global);

        position_global
    }
More examples
Hide additional examples
src/builder/edge.rs (line 48)
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
    fn replace_surface(&mut self, surface: impl Into<Partial<Surface>>) {
        let surface = surface.into();

        for vertex in &mut self.vertices {
            vertex.write().replace_surface(surface.clone());
        }
    }

    fn update_as_circle_from_radius(&mut self, radius: impl Into<Scalar>) {
        let mut curve = self.curve();
        curve.write().update_as_circle_from_radius(radius);

        let path = curve
            .read()
            .path
            .expect("Expected path that was just created");

        let [a_curve, b_curve] =
            [Scalar::ZERO, Scalar::TAU].map(|coord| Point::from([coord]));

        let mut surface_vertex = {
            let [vertex, _] = &mut self.vertices;
            vertex.write().surface_form.clone()
        };
        surface_vertex.write().position =
            Some(path.point_from_path_coords(a_curve));

        for (vertex, point_curve) in
            self.vertices.each_mut_ext().zip_ext([a_curve, b_curve])
        {
            let mut vertex = vertex.write();
            vertex.position = Some(point_curve);
            vertex.surface_form = surface_vertex.clone();
        }

        self.infer_global_form();
    }

    fn update_as_line_segment_from_points(
        &mut self,
        surface: impl Into<Partial<Surface>>,
        points: [impl Into<Point<2>>; 2],
    ) {
        let surface = surface.into();

        for (vertex, point) in self.vertices.each_mut_ext().zip_ext(points) {
            let mut vertex = vertex.write();
            vertex.curve.write().surface = surface.clone();

            let mut surface_form = vertex.surface_form.write();
            surface_form.position = Some(point.into());
            surface_form.surface = surface.clone();
        }

        self.update_as_line_segment()
    }

    fn update_as_line_segment(&mut self) {
        let points_surface = self.vertices.each_ref_ext().map(|vertex| {
            vertex
                .read()
                .surface_form
                .read()
                .position
                .expect("Can't infer line segment without surface position")
        });

        self.curve()
            .write()
            .update_as_line_from_points(points_surface);

        for (vertex, position) in self.vertices.each_mut_ext().zip_ext([0., 1.])
        {
            vertex.write().position = Some([position].into());
        }

        self.infer_global_form();
    }

    fn infer_global_form(&mut self) -> Partial<GlobalEdge> {
        self.global_form.write().curve =
            self.curve().read().global_form.clone();
        self.global_form.write().vertices =
            self.vertices.each_ref_ext().map(|vertex| {
                vertex.read().surface_form.read().global_form.clone()
            });

        self.global_form.clone()
    }
src/partial/objects/vertex.rs (line 45)
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
    fn build(mut self, objects: &mut Service<Objects>) -> Self::Full {
        let position = self
            .position
            .expect("Can't build `Vertex` without position");
        let curve = self.curve.build(objects);

        // Infer surface position, if not available.
        if self.surface_form.read().position.is_none() {
            self.surface_form.write().position =
                Some(curve.path().point_from_path_coords(position));
        }

        let surface_form = self.surface_form.build(objects);

        Vertex::new(position, curve, surface_form)
    }
src/builder/cycle.rs (line 62)
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
    fn update_as_polygon_from_points(
        &mut self,
        surface: impl Into<Partial<Surface>>,
        points: impl IntoIterator<Item = impl Into<Point<2>>>,
    ) -> Vec<Partial<HalfEdge>> {
        let surface = surface.into();
        let mut points = points.into_iter().map(Into::into);

        let mut half_edges = Vec::new();

        if let Some(point) = points.next() {
            let mut half_edge = self.add_half_edge_from_point_to_start(point);
            half_edge.write().replace_surface(surface);
            half_edges.push(half_edge);
        }

        for point in points {
            let half_edge = self.add_half_edge_from_point_to_start(point);
            half_edges.push(half_edge);
        }

        self.update_as_polygon();

        half_edges
    }

    fn update_as_polygon(&mut self) {
        for half_edge in &mut self.half_edges {
            half_edge.write().update_as_line_segment();
        }
    }

    fn add_half_edge(&mut self) -> Partial<HalfEdge> {
        let mut new_half_edge = Partial::<HalfEdge>::new();

        let (first_half_edge, mut last_half_edge) =
            match self.half_edges.first() {
                Some(first_half_edge) => {
                    let first_half_edge = first_half_edge.clone();
                    let last_half_edge = self
                        .half_edges
                        .last()
                        .cloned()
                        .unwrap_or_else(|| first_half_edge.clone());

                    (first_half_edge, last_half_edge)
                }
                None => (new_half_edge.clone(), new_half_edge.clone()),
            };

        {
            let shared_surface_vertex =
                new_half_edge.read().back().read().surface_form.clone();

            let mut last_half_edge = last_half_edge.write();

            last_half_edge.front_mut().write().surface_form =
                shared_surface_vertex;
            last_half_edge.infer_global_form();
        }

        {
            let shared_surface_vertex =
                first_half_edge.read().back().read().surface_form.clone();
            let shared_surface = shared_surface_vertex.read().surface.clone();

            let mut new_half_edge = new_half_edge.write();

            new_half_edge.front_mut().write().surface_form =
                shared_surface_vertex;
            new_half_edge.replace_surface(shared_surface);
            new_half_edge.infer_global_form();
        }

        self.half_edges.push(new_half_edge.clone());
        new_half_edge
    }

    fn add_half_edge_from_point_to_start(
        &mut self,
        point: impl Into<Point<2>>,
    ) -> Partial<HalfEdge> {
        let mut half_edge = self.add_half_edge();

        half_edge
            .write()
            .back_mut()
            .write()
            .surface_form
            .write()
            .position = Some(point.into());

        half_edge
    }
src/builder/shell.rs (line 63)
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
    fn create_cube_from_edge_length(
        edge_length: impl Into<Scalar>,
        objects: &mut Service<Objects>,
    ) -> Self {
        let edge_length = edge_length.into();

        // Let's define some short-hands. We're going to need them a lot.
        const Z: Scalar = Scalar::ZERO;
        let h = edge_length / 2.;

        let bottom_face = {
            let surface =
                objects.surfaces.xy_plane().translate([Z, Z, -h], objects);

            let mut face = PartialFace::default();
            face.update_exterior_as_polygon(
                surface,
                [[-h, -h], [h, -h], [h, h], [-h, h]],
            );

            face
        };

        let (side_faces, top_edges) = {
            let side_surfaces = bottom_face
                .exterior
                .read()
                .half_edges
                .iter()
                .map(|half_edge| {
                    let [a, b] =
                        half_edge.read().vertices.clone().map(|mut vertex| {
                            vertex
                                .write()
                                .surface_form
                                .write()
                                .infer_global_position()
                        });
                    let c = a + [Z, Z, edge_length];

                    let (surface, _) =
                        PartialSurface::plane_from_points([a, b, c]);
                    Partial::from_partial(surface)
                })
                .collect::<Vec<_>>();

            let bottom_edges = bottom_face
                .exterior
                .read()
                .half_edges
                .iter()
                .zip(&side_surfaces)
                .map(|(half_edge, surface)| {
                    let global_edge = half_edge.read().global_form.clone();

                    let mut half_edge = PartialHalfEdge::default();

                    half_edge.curve().write().global_form =
                        global_edge.read().curve.clone();

                    for (vertex, global_form) in half_edge
                        .vertices
                        .iter_mut()
                        .zip(&global_edge.read().vertices)
                    {
                        vertex.write().surface_form.write().global_form =
                            global_form.clone();
                    }

                    half_edge.global_form = global_edge;

                    half_edge.update_as_line_segment_from_points(
                        surface.clone(),
                        [[Z, Z], [edge_length, Z]],
                    );

                    Partial::from_partial(half_edge)
                })
                .collect::<Vec<_>>();

            let side_edges_up = bottom_edges
                .clone()
                .into_iter()
                .zip(&side_surfaces)
                .map(|(bottom, surface): (Partial<HalfEdge>, _)| {
                    let from_surface = {
                        let [_, from] = &bottom.read().vertices;
                        let from = from.read();
                        from.surface_form.clone()
                    };
                    let to_position = from_surface.read().position.unwrap()
                        + [Z, edge_length];

                    let mut half_edge = PartialHalfEdge::default();

                    half_edge.curve().write().surface = surface.clone();

                    {
                        let [from, to] = &mut half_edge.vertices;
                        from.write().surface_form = from_surface;

                        let mut to = to.write();
                        let mut to_surface = to.surface_form.write();
                        to_surface.position = Some(to_position);
                        to_surface.surface = surface.clone();
                    }

                    half_edge.infer_global_form();
                    half_edge.update_as_line_segment();

                    Partial::from_partial(half_edge)
                })
                .collect::<Vec<_>>();

            let side_edges_down = {
                let mut sides_up_prev = side_edges_up.clone();
                sides_up_prev.rotate_right(1);

                bottom_edges
                    .clone()
                    .into_iter()
                    .zip(sides_up_prev)
                    .zip(&side_surfaces)
                    .map(
                        |((bottom, side_up_prev), surface): (
                            (_, Partial<HalfEdge>),
                            _,
                        )| {
                            let [_, from] =
                                side_up_prev.read().vertices.clone();
                            let [to, _] = bottom.read().vertices.clone();

                            let from_global = from
                                .read()
                                .surface_form
                                .read()
                                .global_form
                                .clone();
                            let to_surface = to.read().surface_form.clone();

                            let mut half_edge = PartialHalfEdge::default();

                            half_edge.curve().write().surface = surface.clone();
                            half_edge.curve().write().global_form =
                                side_up_prev
                                    .read()
                                    .curve()
                                    .read()
                                    .global_form
                                    .clone();

                            {
                                let [from, to] = &mut half_edge.vertices;

                                let mut from = from.write();
                                let mut from_surface =
                                    from.surface_form.write();
                                from_surface.position = Some(
                                    to_surface.read().position.unwrap()
                                        + [Z, edge_length],
                                );
                                from_surface.surface = surface.clone();
                                from_surface.global_form = from_global;

                                to.write().surface_form = to_surface;
                            }

                            half_edge.infer_global_form();
                            half_edge.update_as_line_segment();

                            Partial::from_partial(half_edge)
                        },
                    )
                    .collect::<Vec<_>>()
            };

            let top_edges = side_edges_up
                .clone()
                .into_iter()
                .zip(side_edges_down.clone())
                .map(|(side_up, side_down): (_, Partial<HalfEdge>)| {
                    let [_, from] = side_up.read().vertices.clone();
                    let [to, _] = side_down.read().vertices.clone();

                    let from_surface = from.read().surface_form.clone();
                    let to_surface = to.read().surface_form.clone();

                    let mut half_edge = PartialHalfEdge::default();

                    half_edge.curve().write().surface =
                        from_surface.read().surface.clone();

                    half_edge.global_form.write().vertices = [
                        from_surface.read().global_form.clone(),
                        to_surface.read().global_form.clone(),
                    ];

                    {
                        let [from, to] = &mut half_edge.vertices;
                        from.write().surface_form = from_surface;
                        to.write().surface_form = to_surface;
                    }

                    half_edge.update_as_line_segment();

                    Partial::from_partial(half_edge)
                })
                .collect::<Vec<_>>();

            let side_faces = bottom_edges
                .into_iter()
                .zip(side_edges_up)
                .zip(top_edges.clone())
                .zip(side_edges_down)
                .map(|(((bottom, side_up), top), side_down)| {
                    let mut cycle = PartialCycle::default();
                    cycle.half_edges.extend([bottom, side_up, top, side_down]);

                    PartialFace {
                        exterior: Partial::from_partial(cycle),
                        ..Default::default()
                    }
                })
                .collect::<Vec<_>>();

            (side_faces, top_edges)
        };

        let top_face = {
            let surface = Partial::from(
                objects.surfaces.xy_plane().translate([Z, Z, h], objects),
            );

            let mut top_edges = top_edges;
            top_edges.reverse();

            let surface_vertices = {
                let points = [[-h, -h], [-h, h], [h, h], [h, -h]];

                let mut edges = top_edges.iter();
                let half_edges = array::from_fn(|_| edges.next().unwrap());

                let [a, b, c, d] = points
                    .into_iter_fixed()
                    .zip(half_edges)
                    .collect::<[_; 4]>()
                    .map(|(point, edge)| {
                        let [vertex, _] = edge.read().vertices.clone();
                        let global_vertex = vertex
                            .read()
                            .surface_form
                            .read()
                            .global_form
                            .clone();

                        Partial::from_partial(PartialSurfaceVertex {
                            position: Some(point.into()),
                            surface: surface.clone(),

                            global_form: global_vertex,
                        })
                    });

                [a.clone(), b, c, d, a]
            };

            let mut half_edges = Vec::new();
            for (surface_vertices, edge) in surface_vertices
                .as_slice()
                .array_windows_ext()
                .zip(top_edges)
            {
                let global_form = edge.read().global_form.clone();

                let mut half_edge = PartialHalfEdge::default();

                half_edge.curve().write().surface = surface.clone();
                half_edge.curve().write().global_form =
                    global_form.read().curve.clone();

                half_edge.global_form = global_form;

                for (vertex, surface_form) in half_edge
                    .vertices
                    .each_mut_ext()
                    .zip_ext(surface_vertices.each_ref_ext())
                {
                    vertex.write().surface_form = surface_form.clone();
                }

                half_edge.update_as_line_segment();

                half_edges.push(Partial::from_partial(half_edge));
            }

            PartialFace {
                exterior: Partial::from_partial(PartialCycle { half_edges }),
                ..Default::default()
            }
        };

        PartialShell {
            faces: [bottom_face]
                .into_iter()
                .chain(side_faces)
                .chain([top_face])
                .map(Partial::from_partial)
                .collect(),
        }
    }

Build a full object from this partial one

Panics

Panics, if a call to Self::write would panic.

Examples found in repository?
src/partial/objects/shell.rs (line 28)
27
28
29
30
    fn build(self, objects: &mut Service<Objects>) -> Self::Full {
        let faces = self.faces.into_iter().map(|face| face.build(objects));
        Shell::new(faces)
    }
More examples
Hide additional examples
src/partial/objects/sketch.rs (line 28)
27
28
29
30
    fn build(self, objects: &mut Service<Objects>) -> Self::Full {
        let faces = self.faces.into_iter().map(|face| face.build(objects));
        Sketch::new(faces)
    }
src/partial/objects/solid.rs (line 27)
26
27
28
29
    fn build(self, objects: &mut Service<Objects>) -> Self::Full {
        let shells = self.shells.into_iter().map(|shell| shell.build(objects));
        Solid::new(shells)
    }
src/partial/objects/cycle.rs (line 40)
36
37
38
39
40
41
42
43
    fn build(self, objects: &mut Service<Objects>) -> Self::Full {
        let half_edges = self
            .half_edges
            .into_iter()
            .map(|half_edge| half_edge.build(objects));

        Cycle::new(half_edges)
    }
src/partial/objects/edge.rs (line 75)
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
    fn build(self, objects: &mut Service<Objects>) -> Self::Full {
        let vertices = self.vertices.map(|vertex| vertex.build(objects));
        let global_form = self.global_form.build(objects);

        HalfEdge::new(vertices, global_form)
    }
}

impl Default for PartialHalfEdge {
    fn default() -> Self {
        let curve = Partial::<Curve>::new();

        let vertices = array::from_fn(|_| {
            Partial::from_partial(PartialVertex {
                curve: curve.clone(),
                ..Default::default()
            })
        });

        let global_curve = curve.read().global_form.clone();
        let global_vertices =
            vertices.each_ref_ext().map(|vertex: &Partial<Vertex>| {
                let surface_vertex = vertex.read().surface_form.clone();
                let global_vertex = surface_vertex.read().global_form.clone();
                global_vertex
            });

        let global_form = Partial::from_partial(PartialGlobalEdge {
            curve: global_curve,
            vertices: global_vertices,
        });

        Self {
            vertices,
            global_form,
        }
    }
}

/// A partial [`GlobalEdge`]
#[derive(Clone, Debug, Default)]
pub struct PartialGlobalEdge {
    /// The curve that defines the edge's geometry
    pub curve: Partial<GlobalCurve>,

    /// The vertices that bound the edge on the curve
    pub vertices: [Partial<GlobalVertex>; 2],
}

impl PartialObject for PartialGlobalEdge {
    type Full = GlobalEdge;

    fn from_full(
        global_edge: &Self::Full,
        cache: &mut FullToPartialCache,
    ) -> Self {
        Self {
            curve: Partial::from_full(global_edge.curve().clone(), cache),
            vertices: global_edge
                .vertices()
                .access_in_normalized_order()
                .map(|vertex| Partial::from_full(vertex, cache)),
        }
    }

    fn build(self, objects: &mut Service<Objects>) -> Self::Full {
        let curve = self.curve.build(objects);
        let vertices = self.vertices.map(|vertex| vertex.build(objects));

        GlobalEdge::new(curve, vertices)
    }
src/partial/objects/curve.rs (line 34)
32
33
34
35
36
37
38
    fn build(self, objects: &mut Service<Objects>) -> Self::Full {
        let path = self.path.expect("Need path to build curve");
        let surface = self.surface.build(objects);
        let global_form = self.global_form.build(objects);

        Curve::new(surface, path, global_form)
    }

Trait Implementations§

Returns a copy of the value. Read more
Performs copy-assignment from source. Read more
Formats the value using the given formatter. Read more
Returns the “default value” for a type. Read more
Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more
Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Should always be Self
The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
Checks if self is actually part of its subset T (and can be converted to it).
Use with care! Same as self.to_subset but without any property checks. Always succeeds.
The inclusion map: converts self to the equivalent element of its superset.
The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.