use binpack2d::guillotine::{pack_bins, RectHeuristic, SplitHeuristic};
use binpack2d::{BinError, BinPacker, Dimension};
use rand::prelude::*;
use std::time::Instant;
#[test]
fn bin_performance_guillotine() {
let choices = vec![
RectHeuristic::BestShortSideFit,
RectHeuristic::BestLongSideFit,
RectHeuristic::BestAreaFit,
RectHeuristic::WorstShortSideFit,
RectHeuristic::WorstLongSideFit,
RectHeuristic::WorstAreaFit,
];
let methods = vec![
SplitHeuristic::ShorterLeftoverAxis,
SplitHeuristic::LongerLeftoverAxis,
SplitHeuristic::MinimizeArea,
SplitHeuristic::MaximizeArea,
SplitHeuristic::ShorterAxis,
SplitHeuristic::LongerAxis,
];
const DIM: i32 = 512;
const SIZE: usize = 1_000;
let mut rng = StdRng::seed_from_u64(123456789);
let mut nodes = Vec::with_capacity(SIZE);
for i in 1..=SIZE {
nodes.push(Dimension::with_id(
i as isize,
rng.gen_range((DIM / 128).max(1)..(DIM / 16).max(2)),
rng.gen_range((DIM / 128).max(1)..(DIM / 16).max(2)),
0,
));
}
for choice in &choices {
for method in &methods {
let now = Instant::now();
let bins_result = pack_bins(&nodes, DIM, DIM, true, *choice, *method, false);
let elapsed = now.elapsed();
if let Ok(bins) = bins_result {
println!("Packed {SIZE} nodes into {} {DIM}x{DIM} bin(s), with choice \"{choice:?}\" and method \"{method:?}\": {} ms",
bins.len(), elapsed.as_millis());
for (idx, bin) in bins.iter().enumerate() {
println!(
"Bin {idx} contains {} nodes (occupancy: {})...",
bin.len(),
bin.occupancy()
);
}
} else if let Err(err) = bins_result {
println!("Error: {err}");
}
println!();
}
println!();
}
}
#[test]
fn bin_failure() {
let choice = RectHeuristic::BestAreaFit;
let method = SplitHeuristic::MinimizeArea;
let mut nodes = vec![
Dimension::with_padding(2, 4, 0),
Dimension::with_padding(6, 8, 1),
];
nodes.push(Dimension::with_padding(20, 12, 0));
let result1 = pack_bins(&nodes, 16, 16, true, choice, method, true);
assert_eq!(BinError::ItemTooBig, result1.err().unwrap());
let result2 = pack_bins(&nodes, 16, 16, true, choice, method, false);
assert_eq!(BinError::ItemTooBig, result2.err().unwrap());
nodes.pop();
nodes.push(Dimension::with_padding(0, 64, 0));
let result3 = pack_bins(&nodes, 16, 16, true, choice, method, true);
assert_eq!(BinError::ItemTooSmall, result3.err().unwrap());
let result4 = pack_bins(&nodes, 16, 16, true, choice, method, false);
assert_eq!(BinError::ItemTooSmall, result4.err().unwrap());
}