///|
pub(all) struct Cut {
demand_id : String
ordinal : Int32
start : Int32
end : Int32
kerf_end : Int32
} derive(Debug, Eq)
///|
pub extend Cut with @debug.Debug::{to_repr}
///|
pub extend Cut with Eq::{equal, not_equal}
///|
pub(all) struct BarMap {
bar : Int32
stock_id : String
usable_start : Int32
usable_end : Int32
cuts : Array[Cut]
remnant_start : Int32
remnant_end : Int32
reusable : Bool
} derive(Debug)
///|
pub extend BarMap with @debug.Debug::{to_repr}
///|
/// Half-open coordinates, in demand input order, with a kerf after every cut.
pub fn cutting_map(p : Problem, plan : Plan) -> Result[Array[BarMap], String] {
match audit(p, plan) {
Err(e) => return Err(e)
Ok(_) => ()
}
let result : Array[BarMap] = []
let ordinals = Array::make(p.demands.length(), 0)
for bi, a in plan.bars {
let s = p.stocks[a.stock]
let mut cursor = s.trim_start
let cuts : Array[Cut] = []
for di, n in a.counts {
for _ in 0..= p.min_remnant,
})
}
Ok(result)
}
///|
/// Verify exported coordinates without trusting the planner's interval arithmetic.
pub fn verify_cutting_map(
p : Problem,
plan : Plan,
maps : Array[BarMap],
) -> Bool {
let expected = match cutting_map(p, plan) {
Err(_) => return false
Ok(v) => v
}
if maps.length() != expected.length() {
return false
}
for i, a in maps {
let e = expected[i]
if a.bar != e.bar ||
a.stock_id != e.stock_id ||
a.usable_start != e.usable_start ||
a.usable_end != e.usable_end ||
a.cuts != e.cuts ||
a.remnant_start != e.remnant_start ||
a.remnant_end != e.remnant_end ||
a.reusable != e.reusable {
return false
}
}
true
}