geo_booleanop/boolean/
subdivide_segments.rs1use super::compare_segments::compare_segments;
2use super::compute_fields::compute_fields;
3use super::helper::{BoundingBox, Float};
4use super::possible_intersection::possible_intersection;
5use super::sweep_event::SweepEvent;
6use super::Operation;
7use crate::splay::SplaySet;
8use std::collections::BinaryHeap;
9use std::rc::Rc;
10
11#[cfg(feature = "debug-booleanop")]
12use super::sweep_event::JsonDebug;
13
14pub fn subdivide<F>(
15 event_queue: &mut BinaryHeap<Rc<SweepEvent<F>>>,
16 sbbox: &BoundingBox<F>,
17 cbbox: &BoundingBox<F>,
18 operation: Operation,
19) -> Vec<Rc<SweepEvent<F>>>
20where
21 F: Float,
22{
23 let mut sweep_line = SplaySet::<Rc<SweepEvent<F>>, _>::new(compare_segments);
24 let mut sorted_events: Vec<Rc<SweepEvent<F>>> = Vec::new();
25 let rightbound = sbbox.max.x.min(cbbox.max.x);
26
27 while let Some(event) = event_queue.pop() {
28 #[cfg(feature = "debug-booleanop")]
29 {
30 println!("\n{{\"processEvent\": {}}}", event.to_json_debug());
31 }
32 sorted_events.push(event.clone());
33
34 if operation == Operation::Intersection && event.point.x > rightbound
35 || operation == Operation::Difference && event.point.x > sbbox.max.x
36 {
37 break;
38 }
39
40 if event.is_left() {
41 sweep_line.insert(event.clone());
42
43 let maybe_prev = sweep_line.prev(&event);
44 let maybe_next = sweep_line.next(&event);
45
46 compute_fields(&event, maybe_prev, operation);
47
48 if let Some(next) = maybe_next {
49 #[cfg(feature = "debug-booleanop")]
50 {
51 println!("{{\"seNextEvent\": {}}}", next.to_json_debug());
52 }
53 if possible_intersection(&event, &next, event_queue) == 2 {
54 compute_fields(&event, maybe_prev, operation);
56 compute_fields(&next, Some(&event), operation);
57 }
58 }
59
60 if let Some(prev) = maybe_prev {
61 #[cfg(feature = "debug-booleanop")]
62 {
63 println!("{{\"sePrevEvent\": {}}}", prev.to_json_debug());
64 }
65 if possible_intersection(&prev, &event, event_queue) == 2 {
66 let maybe_prev_prev = sweep_line.prev(&prev);
67 compute_fields(&prev, maybe_prev_prev, operation);
69 compute_fields(&event, Some(prev), operation);
70 }
71 }
72 } else if let Some(other_event) = event.get_other_event() {
73 debug_assert!(
76 sweep_line.contains(&other_event),
77 "Sweep line misses event to be removed"
78 );
79 if sweep_line.contains(&other_event) {
80 let maybe_prev = sweep_line.prev(&other_event).cloned();
81 let maybe_next = sweep_line.next(&other_event).cloned();
82
83 if let (Some(prev), Some(next)) = (maybe_prev, maybe_next) {
84 #[cfg(feature = "debug-booleanop")]
85 {
86 println!("Possible post intersection");
87 println!("{{\"sePostNextEvent\": {}}}", next.to_json_debug());
88 println!("{{\"sePostPrevEvent\": {}}}", prev.to_json_debug());
89 }
90 possible_intersection(&prev, &next, event_queue);
91 }
92
93 #[cfg(feature = "debug-booleanop")]
94 {
95 println!("{{\"removing\": {}}}", other_event.to_json_debug());
96 }
97 sweep_line.remove(&other_event);
98 }
99 }
100 }
101
102 sorted_events
103}