jagua_rs/probs/spp/io/
import.rs

1use crate::entities::Item;
2use crate::geometry::shape_modification::ShapeModifyConfig;
3use crate::io::import::Importer;
4use crate::probs::spp::entities::{SPInstance, Strip};
5use crate::probs::spp::io::ext_repr::ExtSPInstance;
6use anyhow::{Result, ensure};
7use itertools::Itertools;
8use rayon::prelude::*;
9
10/// Imports an instance into the library
11pub fn import(importer: &Importer, ext_instance: &ExtSPInstance) -> Result<SPInstance> {
12    let items: Vec<(Item, usize)> = {
13        let mut items = ext_instance
14            .items
15            .par_iter()
16            .map(|ext_item| {
17                let item = importer.import_item(&ext_item.base)?;
18                let demand = ext_item.demand as usize;
19                Ok((item, demand))
20            })
21            .collect::<Result<Vec<(Item, usize)>>>()?;
22
23        items.sort_by_key(|(item, _)| item.id);
24        items.retain(|(_, demand)| *demand > 0);
25
26        ensure!(
27            items.iter().enumerate().all(|(i, (item, _))| item.id == i),
28            "All items should have consecutive IDs starting from 0. IDs: {:?}",
29            items.iter().map(|(item, _)| item.id).sorted().collect_vec()
30        );
31        ensure!(
32            !items.is_empty(),
33            "ExtSPInstance must have at least one item with positive demand"
34        );
35
36        items
37    };
38
39    let total_item_area = items
40        .iter()
41        .map(|(item, demand)| item.area() * *demand as f32)
42        .sum::<f32>();
43
44    let fixed_height = ext_instance.strip_height;
45
46    // Initialize the base width for 100% density
47    let width = total_item_area / fixed_height;
48
49    let base_strip = Strip::new(
50        fixed_height,
51        importer.cde_config,
52        ShapeModifyConfig {
53            offset: importer.shape_modify_config.offset,
54            simplify_tolerance: None,
55            narrow_concavity_cutoff_ratio: None,
56        },
57        width,
58    )?;
59
60    Ok(SPInstance::new(items, base_strip))
61}