1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
use super::helper::Float;
use super::sweep_event::{EdgeType, ResultTransition, SweepEvent};
use super::Operation;
use std::rc::Rc;
pub fn compute_fields<F>(event: &Rc<SweepEvent<F>>, maybe_prev: Option<&Rc<SweepEvent<F>>>, operation: Operation)
where
F: Float,
{
if let Some(prev) = maybe_prev {
if event.is_subject == prev.is_subject {
event.set_in_out(!prev.is_in_out(), prev.is_other_in_out());
} else if prev.is_vertical() {
event.set_in_out(!prev.is_other_in_out(), !prev.is_in_out());
} else {
event.set_in_out(!prev.is_other_in_out(), prev.is_in_out());
}
if prev.is_in_result() && !prev.is_vertical() {
event.set_prev_in_result(prev);
} else if let Some(prev_of_prev) = prev.get_prev_in_result() {
event.set_prev_in_result(&prev_of_prev);
} else {
event.unset_prev_in_result();
}
} else {
event.set_in_out(false, true);
event.unset_prev_in_result();
}
let in_result = in_result(event, operation);
let result_transition = if !in_result {
ResultTransition::None
} else {
determine_result_transition(&event, operation)
};
event.set_result_transition(result_transition);
#[cfg(feature = "debug-booleanop")]
{
println!(
"{{\"computeFields\": {{\"inOut\": {}, \"otherOut\": {}, \"resultTransition\": \"{:?}\", \"edgeType\": \"{:?}\"}}}}",
event.is_in_out(),
event.is_other_in_out(),
event.get_result_transition(),
event.get_edge_type(),
);
}
}
fn in_result<F>(event: &SweepEvent<F>, operation: Operation) -> bool
where
F: Float,
{
match event.get_edge_type() {
EdgeType::Normal => match operation {
Operation::Intersection => !event.is_other_in_out(),
Operation::Union => event.is_other_in_out(),
Operation::Difference => {
(event.is_subject && event.is_other_in_out()) || (!event.is_subject && !event.is_other_in_out())
}
Operation::Xor => true,
},
EdgeType::SameTransition => operation == Operation::Intersection || operation == Operation::Union,
EdgeType::DifferentTransition => operation == Operation::Difference,
EdgeType::NonContributing => false,
}
}
fn determine_result_transition<F>(event: &SweepEvent<F>, operation: Operation) -> ResultTransition
where
F: Float,
{
let this_in = !event.is_in_out();
let that_in = !event.is_other_in_out();
let is_in = match operation {
Operation::Intersection => this_in && that_in,
Operation::Union => this_in || that_in,
Operation::Xor => this_in ^ that_in,
Operation::Difference =>
{
if event.is_subject {
this_in && !that_in
} else {
that_in && !this_in
}
}
};
if is_in {
ResultTransition::OutIn
} else {
ResultTransition::InOut
}
}