honeycomb_kernels/grisubal/routines/
compute_new_edges.rs

1//! Step 4 implementation
2//!
3//! Rebuild information about the edge that will be inserted into the map. This is done by using
4//! the list of "atomic" segments to search for connections between intersections, discarding
5//! regular points and registering points of interests.
6
7use honeycomb_core::cmap::{CMap2, DartIdType};
8use honeycomb_core::geometry::CoordsFloat;
9
10use crate::grisubal::model::{Geometry2, GeometryVertex, MapEdge};
11
12use super::Segments;
13
14pub(crate) fn generate_edge_data<T: CoordsFloat>(
15    cmap: &CMap2<T>,
16    geometry: &Geometry2<T>,
17    new_segments: &Segments,
18    intersection_darts: &[DartIdType],
19) -> Vec<MapEdge<T>> {
20    new_segments
21        .iter()
22        .filter(|(k, _)| {
23            matches!(
24                k,
25                GeometryVertex::Intersec(_) | GeometryVertex::IntersecCorner(..)
26            )
27        })
28        .map(|(start, v)| {
29            let mut end = v;
30            let mut intermediates = Vec::new();
31            // while we land on regular vertices, go to the next
32            while !matches!(
33                end,
34                GeometryVertex::Intersec(_) | GeometryVertex::IntersecCorner(_)
35            ) {
36                match end {
37                    GeometryVertex::PoI(vid) => {
38                        // save the PoI as an intermediate & update end point
39                        intermediates.push(geometry.vertices[*vid]);
40                        end = &new_segments[end];
41                    }
42                    GeometryVertex::Regular(_) => {
43                        // skip; update end point
44                        end = &new_segments[end];
45                    }
46                    GeometryVertex::Intersec(_) | GeometryVertex::IntersecCorner(..) => {
47                        unreachable!() // outer while should prevent this from happening
48                    }
49                }
50            }
51
52            let d_start = match start {
53                GeometryVertex::Intersec(d_start_idx) => {
54                    cmap.beta::<2>(intersection_darts[*d_start_idx])
55                }
56                GeometryVertex::IntersecCorner(d_in) => {
57                    cmap.beta::<2>(cmap.beta::<1>(cmap.beta::<2>(*d_in)))
58                }
59                _ => unreachable!(), // unreachable due to filter
60            };
61            let d_end = match end {
62                GeometryVertex::Intersec(d_end_idx) => intersection_darts[*d_end_idx],
63                GeometryVertex::IntersecCorner(d_in) => *d_in,
64                _ => unreachable!(), // unreachable due to filter
65            };
66
67            // the data in this structure can be used to entirely deduce the new connections that should be made
68            // at STEP 3
69
70            MapEdge {
71                start: d_start,
72                intermediates,
73                end: d_end,
74            }
75        })
76        .collect()
77}