use std::collections::{BTreeMap, BTreeSet};
use crate::face::{FaceId, FaceVertices};
use usage::{AsUsage, Usage};
use super::{point_in_line, LineFaces, LineId, Lines};
pub enum LineFaceConnectionsTag {}
pub type LineFaceConnections = Usage<LineFaceConnectionsTag, BTreeMap<LineId, BTreeSet<FaceId>>>;
pub fn line_face_connections(
lines: &Lines,
line_faces: &LineFaces,
face_vertices: &FaceVertices,
) -> LineFaceConnections {
let mut line_face_connections = BTreeMap::<LineId, BTreeSet<FaceId>>::default();
for (lhs_id, lhs) in lines.iter() {
let lhs_face = &line_faces[lhs_id];
line_face_connections
.entry(*lhs_id)
.or_default()
.insert(*lhs_face);
let lhs_v0 = &face_vertices[lhs_face][lhs.i0];
let lhs_v1 = &face_vertices[lhs_face][lhs.i1];
for (rhs_id, rhs) in lines.iter() {
if lhs_id == rhs_id {
continue;
}
let rhs_face = &line_faces[rhs_id];
line_face_connections
.entry(*rhs_id)
.or_default()
.insert(*rhs_face);
let rhs_v0 = &face_vertices[rhs_face][rhs.i0];
let rhs_v1 = &face_vertices[rhs_face][rhs.i1];
let lhs_contain_rhs =
point_in_line(rhs_v0, lhs_v0, lhs_v1) && point_in_line(rhs_v1, lhs_v0, lhs_v1);
let rhs_contain_lhs =
point_in_line(lhs_v0, rhs_v0, rhs_v1) && point_in_line(lhs_v1, rhs_v0, rhs_v1);
let eq = lhs_contain_rhs || rhs_contain_lhs;
if eq {
line_face_connections
.entry(*lhs_id)
.or_default()
.insert(*rhs_face);
line_face_connections
.entry(*rhs_id)
.or_default()
.insert(*lhs_face);
}
}
}
LineFaceConnectionsTag::as_usage(line_face_connections)
}