use super::cells::{CellComplex, Wall, Windings, ANTI, NORMAL};
use super::intersection_graph::{IntersectionGraph, Piece};
use crate::types::{OpType, WindingRule};
pub fn in_result(op: OpType, rule: WindingRule, w: [i32; 2]) -> bool {
let inside = |v: i32| match rule {
WindingRule::Positive => v >= 1,
WindingRule::Nonzero => v != 0,
};
let (a, b) = (inside(w[0]), inside(w[1]));
match op {
OpType::Add => a || b,
OpType::Intersect => a && b,
OpType::Subtract => a && !b,
}
}
pub fn extract(
graph: &IntersectionGraph,
complex: &CellComplex,
wind: &Windings,
op: OpType,
rule: WindingRule,
) -> Vec<Piece> {
let mut out = Vec::new();
for &Wall { rep, .. } in &complex.walls {
let (cn, ca) = (complex.cell(rep, NORMAL), complex.cell(rep, ANTI));
if cn == ca || !wind.known[cn] || !wind.known[ca] {
continue;
}
let (in_n, in_a) = (
in_result(op, rule, wind.w[cn]),
in_result(op, rule, wind.w[ca]),
);
if in_n == in_a {
continue; }
let piece = &graph.pieces[rep];
let vi = if in_a {
piece.vi
} else {
[piece.vi[0], piece.vi[2], piece.vi[1]]
};
out.push(Piece {
mesh: piece.mesh,
tri: piece.tri,
vi,
});
}
out
}