i_overlay/split/
solver_tree.rs1use alloc::vec::Vec;
2use i_tree::ExpiredVal;
3use crate::geom::line_range::LineRange;
4use crate::geom::x_segment::XSegment;
5use crate::segm::segment::Segment;
6use crate::segm::winding::WindingCount;
7use crate::split::snap_radius::SnapRadius;
8use crate::split::solver::SplitSolver;
9use i_tree::seg::exp::{SegExpCollection, SegRange};
10use i_tree::seg::tree::SegExpTree;
11use crate::core::solver::Solver;
12
13#[derive(Debug, Clone, Copy)]
14struct IdSegment {
15 id: usize,
16 x_segment: XSegment,
17}
18
19impl ExpiredVal<i32> for IdSegment {
20 #[inline]
21 fn expiration(&self) -> i32 {
22 self.x_segment.b.x
23 }
24}
25
26impl SplitSolver {
27 pub(super) fn tree_split<C: WindingCount>(
28 &mut self,
29 snap_radius: SnapRadius,
30 segments: &mut Vec<Segment<C>>,
31 solver: &Solver
32 ) -> bool {
33 let range: SegRange<i32> = segments.ver_range().into();
34 let mut tree: SegExpTree<i32, i32, IdSegment> = if let Some(tree) = SegExpTree::new(range) {
35 tree
36 } else {
37 return self.list_split(snap_radius, segments, solver);
38 };
39
40 let mut reusable_buffer = Vec::new();
41
42 let mut need_to_fix = true;
43 let mut any_intersection = false;
44
45 let mut snap_radius = snap_radius;
46
47 while need_to_fix && segments.len() > 2 {
48 need_to_fix = false;
49 self.marks.clear();
50
51 let radius = snap_radius.radius();
52
53 for (i, si) in segments.iter().enumerate() {
54 let time = si.x_segment.a.x;
55 let si_range = si.x_segment.y_range().into();
56 for sj in tree.iter_by_range(si_range, time) {
57 let (this_index, scan_index, this, scan) = if si.x_segment < sj.x_segment {
58 (i, sj.id, &si.x_segment, &sj.x_segment)
59 } else {
60 (sj.id, i, &sj.x_segment, &si.x_segment)
61 };
62
63 let is_round = SplitSolver::cross(
64 this_index,
65 scan_index,
66 this,
67 scan,
68 &mut self.marks,
69 radius,
70 );
71
72 need_to_fix = is_round || need_to_fix;
73 }
74
75 tree.insert_by_range(si_range, si.id_segment(i));
76 }
77
78 if self.marks.is_empty() {
79 return any_intersection;
80 }
81
82 any_intersection = true;
83 tree.clear();
84
85 self.apply(segments, &mut reusable_buffer, solver);
86
87 snap_radius.increment();
88 }
89
90 any_intersection
91 }
92}
93
94impl From<LineRange> for SegRange<i32> {
95 #[inline]
96 fn from(value: LineRange) -> Self {
97 Self {
98 min: value.min,
99 max: value.max,
100 }
101 }
102}
103
104trait VerticalRange {
105 fn ver_range(&self) -> LineRange;
106}
107
108impl<C: Send> VerticalRange for Vec<Segment<C>> {
109 fn ver_range(&self) -> LineRange {
110 let mut min_y = self[0].x_segment.a.y;
111 let mut max_y = min_y;
112
113 for edge in self.iter() {
114 min_y = min_y.min(edge.x_segment.a.y);
115 max_y = max_y.max(edge.x_segment.a.y);
116 min_y = min_y.min(edge.x_segment.b.y);
117 max_y = max_y.max(edge.x_segment.b.y);
118 }
119
120 LineRange {
121 min: min_y,
122 max: max_y,
123 }
124 }
125}
126
127impl<C: Send> Segment<C> {
128 #[inline]
129 fn id_segment(&self, id: usize) -> IdSegment {
130 IdSegment {
131 id,
132 x_segment: self.x_segment,
133 }
134 }
135}