honeycomb_kernels/grisubal/routines/
process_intersecs_data.rs1use std::collections::HashMap;
10
11use honeycomb_core::cmap::{CMap2, DartIdType, EdgeIdType, NULL_DART_ID};
12use honeycomb_core::geometry::CoordsFloat;
13
14use super::{DartSlices, IntersectionsPerEdge};
15
16pub(crate) fn group_intersections_per_edge<T: CoordsFloat>(
19 cmap: &mut CMap2<T>,
20 intersection_metadata: Vec<(DartIdType, T)>,
21) -> (IntersectionsPerEdge<T>, DartSlices) {
22 let mut edge_intersec: HashMap<EdgeIdType, Vec<(usize, T, DartIdType)>> = HashMap::new();
24 intersection_metadata
25 .into_iter()
26 .filter(|(_, t)| !t.is_nan())
27 .enumerate()
28 .for_each(|(idx, (dart_id, mut t))| {
29 let edge_id = cmap.edge_id(dart_id);
31 if edge_id != dart_id {
33 t = T::one() - t;
34 }
35 if let Some(storage) = edge_intersec.get_mut(&edge_id) {
36 storage.push((idx, t, dart_id));
38 } else {
39 edge_intersec.insert(edge_id, vec![(idx, t, dart_id)]);
41 }
42 });
43
44 for vs in edge_intersec.values_mut() {
46 vs.sort_by(|(_, t1, _), (_, t2, _)| t1.partial_cmp(t2).expect("E: unreachable"));
48 }
49
50 let n_darts_per_seg: Vec<_> = edge_intersec.values().map(|vs| 2 * vs.len()).collect();
52 let n_tot: usize = n_darts_per_seg.iter().sum();
53 let tmp = cmap.add_free_darts(n_tot) as usize;
54 let prefix_sum: Vec<usize> = n_darts_per_seg
58 .iter()
59 .scan(0, |state, &n_d| {
60 *state += n_d;
61 Some(*state - n_d) })
63 .collect();
64
65 #[allow(clippy::cast_possible_truncation)]
66 let dart_slices: Vec<Vec<DartIdType>> = n_darts_per_seg
67 .iter()
68 .zip(prefix_sum.iter())
69 .map(|(n_d, start)| {
70 ((tmp + start) as DartIdType..(tmp + start + n_d) as DartIdType).collect::<Vec<_>>()
71 })
72 .collect();
73
74 (edge_intersec, dart_slices)
75}
76
77pub(crate) fn compute_intersection_ids<T: CoordsFloat>(
78 n_intersec: usize,
79 edge_intersec: &IntersectionsPerEdge<T>,
80 dart_slices: &DartSlices,
81) -> Vec<DartIdType> {
82 let mut res = vec![NULL_DART_ID; n_intersec];
83 for ((edge_id, vs), new_darts) in edge_intersec.iter().zip(dart_slices.iter()) {
84 let hl = new_darts.len() / 2; let fh = &new_darts[..hl]; let sh = &new_darts[hl..]; for (i, (id, _, old_dart_id)) in vs.iter().enumerate() {
89 res[*id] = if *old_dart_id == *edge_id {
91 fh[i]
92 } else {
93 sh[hl - 1 - i]
94 };
95 }
96 }
97 res
98}