use crate::data::PolyData;
#[derive(Debug, Clone, Default)]
pub struct PartitionedDataSet {
pub partitions: Vec<PolyData>,
pub partition_names: Vec<String>,
}
impl PartitionedDataSet {
pub fn new() -> Self {
Self::default()
}
pub fn add_partition(&mut self, name: &str, data: PolyData) {
self.partition_names.push(name.to_string());
self.partitions.push(data);
}
pub fn partition(&self, idx: usize) -> Option<&PolyData> {
self.partitions.get(idx)
}
pub fn partition_by_name(&self, name: &str) -> Option<&PolyData> {
self.partition_names
.iter()
.position(|n| n == name)
.and_then(|idx| self.partitions.get(idx))
}
pub fn num_partitions(&self) -> usize {
self.partitions.len()
}
pub fn merge(&self) -> PolyData {
let mut result = PolyData::new();
let mut point_offset: i64 = 0;
for part in &self.partitions {
for i in 0..part.points.len() {
result.points.push(part.points.get(i));
}
for ci in 0..part.polys.num_cells() {
let cell = part.polys.cell(ci);
let offset_cell: Vec<i64> = cell.iter().map(|&id| id + point_offset).collect();
result.polys.push_cell(&offset_cell);
}
for ci in 0..part.lines.num_cells() {
let cell = part.lines.cell(ci);
let offset_cell: Vec<i64> = cell.iter().map(|&id| id + point_offset).collect();
result.lines.push_cell(&offset_cell);
}
for ci in 0..part.verts.num_cells() {
let cell = part.verts.cell(ci);
let offset_cell: Vec<i64> = cell.iter().map(|&id| id + point_offset).collect();
result.verts.push_cell(&offset_cell);
}
point_offset += part.points.len() as i64;
}
result
}
}
#[derive(Debug, Clone, Default)]
pub struct PartitionedDataSetCollection {
pub datasets: Vec<PartitionedDataSet>,
}
impl PartitionedDataSetCollection {
pub fn new() -> Self {
Self::default()
}
pub fn add(&mut self, dataset: PartitionedDataSet) {
self.datasets.push(dataset);
}
pub fn num_datasets(&self) -> usize {
self.datasets.len()
}
pub fn dataset(&self, idx: usize) -> Option<&PartitionedDataSet> {
self.datasets.get(idx)
}
}
#[cfg(test)]
mod tests {
use super::*;
fn triangle(offset: f64) -> PolyData {
PolyData::from_triangles(
vec![
[offset, 0.0, 0.0],
[offset + 1.0, 0.0, 0.0],
[offset + 0.5, 1.0, 0.0],
],
vec![[0, 1, 2]],
)
}
#[test]
fn add_and_query_partitions() {
let mut pds = PartitionedDataSet::new();
pds.add_partition("left", triangle(0.0));
pds.add_partition("right", triangle(5.0));
assert_eq!(pds.num_partitions(), 2);
assert!(pds.partition(0).is_some());
assert!(pds.partition(2).is_none());
assert!(pds.partition_by_name("left").is_some());
assert!(pds.partition_by_name("missing").is_none());
}
#[test]
fn merge_partitions() {
let mut pds = PartitionedDataSet::new();
pds.add_partition("a", triangle(0.0));
pds.add_partition("b", triangle(5.0));
let merged = pds.merge();
assert_eq!(merged.points.len(), 6);
assert_eq!(merged.polys.num_cells(), 2);
let cell1 = merged.polys.cell(1);
assert_eq!(cell1, &[3, 4, 5]);
}
#[test]
fn collection() {
let mut coll = PartitionedDataSetCollection::new();
let mut pds = PartitionedDataSet::new();
pds.add_partition("part0", triangle(0.0));
coll.add(pds);
assert_eq!(coll.num_datasets(), 1);
assert_eq!(coll.dataset(0).unwrap().num_partitions(), 1);
}
}