Skip to main content

mesh_graph/ops/
subdivide.rs

1use hashbrown::HashSet;
2use tracing::instrument;
3
4use crate::{
5    HalfedgeId, MeshGraph, Selection, SelectionOps, VertexId, error_none, utils::unwrap_or_return,
6};
7
8#[cfg(feature = "rerun")]
9use crate::utils::vec3_array;
10
11impl MeshGraph {
12    /// Subdivide all edges until all of them are <= max_length.
13    /// Please note that you have to provide the squared value of max_length.
14    ///
15    /// This will schedule necessary updates to the QBVH but you have to call
16    /// `refit_bvh()` after the operation.
17    #[instrument(skip(self))]
18    pub fn subdivide_until_edges_below_max_length(
19        &mut self,
20        max_length_squared: f32,
21        marked_halfedge_ids: &mut HashSet<HalfedgeId>,
22        marked_vertex_ids: &mut HashSet<VertexId>,
23    ) {
24        let mut halfedges_to_subdivide = self.halfedges_map(|len_sqr| len_sqr > max_length_squared);
25
26        while !halfedges_to_subdivide.is_empty() {
27            let mut max_len = 0.0;
28            let mut max_he_id = HalfedgeId::default();
29
30            #[cfg(feature = "rerun")]
31            self.log_hes_rerun(
32                "subdivide/selection",
33                &halfedges_to_subdivide
34                    .iter()
35                    .map(|(he, _)| *he)
36                    .collect::<Vec<_>>(),
37            );
38
39            for (&he, &len) in &halfedges_to_subdivide {
40                if len > max_len {
41                    max_len = len;
42                    max_he_id = he;
43                }
44            }
45
46            halfedges_to_subdivide.remove(&max_he_id);
47
48            let mut affected_faces = Selection::default();
49
50            // already checked
51            let max_he = self.halfedges[max_he_id];
52            if let Some(face_id) = max_he.face {
53                affected_faces.insert(face_id);
54            }
55
56            if let Some(twin_id) = max_he.twin.or_else(error_none!("Twin missing"))
57                && let Some(twin_he) = self
58                    .halfedges
59                    .get(twin_id)
60                    .or_else(error_none!("Halfedge not found"))
61                && let Some(twin_face_id) = twin_he.face
62            {
63                affected_faces.insert(twin_face_id);
64            }
65
66            let subdivide_edge_result =
67                unwrap_or_return!(self.subdivide_edge(max_he_id), "Couldn't subdivide edge");
68
69            if marked_halfedge_ids.contains(&max_he_id) {
70                marked_halfedge_ids.extend(subdivide_edge_result.added_halfedges.iter().copied());
71                marked_vertex_ids.insert(subdivide_edge_result.added_vertex);
72            }
73
74            // #[cfg(feature = "rerun")]
75            // {
76            //     crate::RR
77            //         .log("meshgraph/subdivide", &rerun::Clear::recursive())
78            //         .unwrap();
79            //     crate::RR
80            //         .log("meshgraph/halfedge/subdivide", &rerun::Clear::recursive())
81            //         .unwrap();
82            //     crate::RR
83            //         .log("meshgraph/face/subdivide", &rerun::Clear::recursive())
84            //         .unwrap();
85            //     self.log_rerun();
86            // }
87
88            for new_he_id in subdivide_edge_result.added_halfedges {
89                // newly inserted in `self.subdivide_edge`
90                let new_he = self.halfedges[new_he_id];
91
92                if let Some(face_id) = new_he.face {
93                    affected_faces.insert(face_id);
94                }
95
96                let new_twin_id = unwrap_or_return!(new_he.twin, "New twin missing");
97                let new_twin =
98                    unwrap_or_return!(self.halfedges.get(new_twin_id), "New twin not found");
99
100                if let Some(face_id) = new_twin.face {
101                    affected_faces.insert(face_id);
102                    #[cfg(feature = "rerun")]
103                    self.log_face_rerun("subdivide/selected_new", face_id);
104                }
105            }
106
107            let mut new_hes_to_check = HashSet::new();
108
109            for he_id in affected_faces.resolve_to_halfedges(self) {
110                let he = unwrap_or_return!(self.halfedges.get(he_id), "Halfedge not found");
111                let twin_id = unwrap_or_return!(he.twin, "Twin missing");
112
113                new_hes_to_check.insert(he_id.min(twin_id));
114            }
115
116            for he_id in new_hes_to_check {
117                let he = self.halfedges[he_id]; // checked above
118
119                let len_sqr = he.length_squared(self);
120
121                if len_sqr > max_length_squared {
122                    #[cfg(feature = "rerun")]
123                    self.log_he_rerun("/subdivide/new_edge", he_id);
124
125                    halfedges_to_subdivide.insert(he_id, len_sqr);
126                }
127            }
128        }
129
130        #[cfg(feature = "rerun")]
131        self.log_rerun();
132    }
133
134    /// Subdivides an edge by computing it's center vertex. This also subdivides any adjacent triangles and
135    /// makes sure everything is properly reconnected. Works only on triangle meshes.
136    ///
137    /// Returns the id of the new halfedge which goes from the center vertex to the original edge's end vertex.
138    /// And also return the halfedges that are created by subdividing the adjacent faces. Only one of the two twin
139    /// halfedges per face subdivision is returned. In total the number `n` of halfedges returned is `1 <= n <= 3`.
140    /// (The one from dividing the halfedge and at most 2 from dividing the two adjacent faces).
141    ///
142    /// Also returns the created vertex id.
143    #[instrument(skip(self))]
144    pub fn subdivide_edge(&mut self, halfedge_id: HalfedgeId) -> Option<SubdivideEdge> {
145        let mut added_halfedges = Vec::with_capacity(3);
146
147        let he = self
148            .halfedges
149            .get(halfedge_id)
150            .or_else(error_none!("Halfedge not found"))?;
151        let twin_id = he.twin.or_else(error_none!("Twin halfedge not found"))?;
152
153        let start_v = he
154            .start_vertex(self)
155            .or_else(error_none!("Start vertex not found"))?;
156        let end_v = he.end_vertex;
157
158        let start_pos = self.positions[start_v];
159        let end_pos = self.positions[end_v];
160
161        let center_pos = (start_pos + end_pos) * 0.5;
162
163        #[cfg(feature = "rerun")]
164        {
165            crate::RR
166                .log(
167                    "meshgraph/subdivide/edge",
168                    &rerun::Arrows3D::from_vectors([vec3_array(end_pos - start_pos)])
169                        .with_origins([vec3_array(start_pos)]),
170                )
171                .unwrap();
172
173            crate::RR
174                .log(
175                    "meshgraph/subdivide/center",
176                    &rerun::Points3D::new([vec3_array(center_pos)]),
177                )
178                .unwrap();
179        }
180
181        let center_v = self.add_vertex(center_pos);
182        if let Some(normals) = &mut self.vertex_normals {
183            let start_normal = normals
184                .get(start_v)
185                .or_else(error_none!("Start normal not found"))?;
186            let end_normal = normals
187                .get(end_v)
188                .or_else(error_none!("End normal not found"))?;
189            normals.insert(center_v, (start_normal + end_normal).normalize());
190        }
191
192        let new_he = self.add_halfedge(center_v, end_v);
193        // inserted just above
194        self.vertices[center_v].outgoing_halfedge = Some(new_he);
195
196        added_halfedges.push(new_he);
197
198        if let Some(new_face_he) = self.subdivide_face(halfedge_id, new_he, center_v) {
199            added_halfedges.push(new_face_he);
200        }
201
202        let new_twin = self.add_halfedge(center_v, start_v);
203
204        if let Some(new_face_he) = self.subdivide_face(twin_id, new_twin, center_v) {
205            added_halfedges.push(new_face_he);
206        }
207
208        // inserted above
209        self.halfedges[new_he].twin = Some(twin_id);
210        self.halfedges
211            .get_mut(twin_id)
212            .or_else(error_none!("Twin halfedge not found"))?
213            .twin = Some(new_he);
214
215        // checked in the beginning of the function
216        self.halfedges[halfedge_id].twin = Some(new_twin);
217        // inserted above
218        self.halfedges[new_twin].twin = Some(halfedge_id);
219
220        // self.vertices[end_v].outgoing_halfedge = Some(new_twin);
221        // self.vertices[start_v].outgoing_halfedge = Some(new_he);
222
223        Some(SubdivideEdge {
224            added_halfedges,
225            added_vertex: center_v,
226        })
227    }
228
229    /// Subdivides a triangle into two halves. Used in [Self::subdivide_edge].
230    #[instrument(skip(self))]
231    fn subdivide_face(
232        &mut self,
233        existing_halfedge_id: HalfedgeId,
234        new_halfedge_id: HalfedgeId,
235        center_v: VertexId,
236    ) -> Option<HalfedgeId> {
237        let he = self
238            .halfedges
239            .get(existing_halfedge_id)
240            .or_else(error_none!("Halfedge not found"))?;
241
242        let face_id = he.face?;
243        self.faces
244            .get_mut(face_id)
245            .or_else(error_none!("Facee not found"))?
246            .halfedge = existing_halfedge_id;
247
248        // checked above
249        let next_he = self.halfedges[existing_halfedge_id]
250            .next
251            .or_else(error_none!("Next halfedge missing"))?;
252        let last_he = self
253            .halfedges
254            .get(next_he)
255            .or_else(error_none!("Next halfedge not found"))?
256            .next
257            .or_else(error_none!("Last halfedge not found"))?;
258
259        // rewire existing face
260        let new_he = self.add_halfedge(center_v, self.halfedges[next_he].end_vertex);
261
262        self.halfedges[existing_halfedge_id].next = Some(new_he);
263        self.halfedges[new_he].next = Some(last_he);
264        self.halfedges[new_he].face = Some(face_id);
265
266        let new_twin = self.add_halfedge(self.halfedges[next_he].end_vertex, center_v);
267
268        // insert new face
269        let new_face_id = self.add_face(new_halfedge_id, next_he, new_twin);
270
271        self.halfedges[new_twin].twin = Some(new_he);
272        self.halfedges[new_he].twin = Some(new_twin);
273
274        self.halfedges[existing_halfedge_id].end_vertex = center_v;
275
276        // checked above
277        let face = self.faces[face_id];
278        // freshly inserted
279        let new_face = self.faces[new_face_id];
280        self.bvh
281            .insert_or_update_partially(face.aabb(self), face.index, 0.0);
282        self.bvh
283            .insert_or_update_partially(new_face.aabb(self), new_face.index, 0.0);
284
285        #[cfg(feature = "rerun")]
286        {
287            self.log_he_rerun("subdivide/new_he", new_he);
288            self.log_he_rerun("subdivide/new_twin", new_twin);
289        }
290
291        Some(new_he)
292    }
293}
294
295pub struct SubdivideEdge {
296    /// All halfedges created by the subdivision.
297    added_halfedges: Vec<HalfedgeId>,
298    /// This is the center vertex of the subdivided edge that was created.
299    added_vertex: VertexId,
300}
301
302#[cfg(test)]
303mod tests {}