use crate::partition_element_records::PartitionElementRecord;
use std::collections::BTreeMap;
pub const BEAM_BODY_SOURCE_FIELD: &str = "m_beam_body_source";
pub const BEAM_BODY_COLUMN_CUT: &str = "partition_element_record_column_cut";
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct BeamColumnTrim {
pub axis: usize,
pub low_feet: f64,
pub high_feet: f64,
}
pub fn beam_column_trims(
beams: &[PartitionElementRecord],
columns: &[PartitionElementRecord],
) -> BTreeMap<u32, BeamColumnTrim> {
let mut out = BTreeMap::new();
for beam in beams {
let b = beam.bbox_feet;
let (along_x, along_y) = (b[3] - b[0], b[4] - b[1]);
if along_x == along_y {
continue;
}
let axis = usize::from(along_y > along_x);
let across = 1 - axis;
let middle = (b[across] + b[across + 3]) / 2.0;
let holding = |end: f64| -> Vec<&PartitionElementRecord> {
columns
.iter()
.filter(|column| {
let c = column.bbox_feet;
beam.references.contains(&u64::from(column.element_id))
&& c[axis] <= end
&& end <= c[axis + 3]
&& c[across] <= middle
&& middle <= c[across + 3]
&& c[2] < b[5]
&& b[2] < c[5]
})
.collect()
};
let (low_columns, high_columns) = (holding(b[axis]), holding(b[axis + 3]));
if low_columns.len() > 1 || high_columns.len() > 1 {
continue;
}
let low = low_columns
.first()
.map_or(b[axis], |column| column.bbox_feet[axis + 3]);
let high = high_columns
.first()
.map_or(b[axis + 3], |column| column.bbox_feet[axis]);
if (low_columns.is_empty() && high_columns.is_empty()) || low >= high {
continue;
}
out.insert(
beam.element_id,
BeamColumnTrim {
axis,
low_feet: low,
high_feet: high,
},
);
}
out
}