use cadmpeg_core::decode::{u64_from_index, DecodeContext, ResourceLimit, ScopedReservation};
use super::PcurveNurbsPoles;
use crate::math::Point2;
use crate::units::FinitePoint2;
#[derive(Debug)]
pub struct PcurveEvaluatorLanes<'ctx> {
points: Vec<Point2>,
weights: Option<Vec<f64>>,
_storage: ScopedReservation<'ctx>,
}
impl<'ctx> PcurveEvaluatorLanes<'ctx> {
pub fn new(
ctx: &'ctx DecodeContext<'_>,
poles: &PcurveNurbsPoles<FinitePoint2>,
point_operation: &'static str,
weight_operation: &'static str,
) -> Result<Self, ResourceLimit> {
ctx.charge_work_limit(0, point_operation)?;
let mut storage = ctx.reserve_scoped_limit(0, point_operation)?;
let mut points = Vec::new();
ctx.reserve_scoped_vec_limit(&mut storage, &mut points, poles.count(), point_operation)?;
let mut weights = None;
match poles {
PcurveNurbsPoles::Polynomial { points: source } => {
for point in source {
ctx.charge_work_limit(
u64_from_index(std::mem::size_of::<Point2>()),
point_operation,
)?;
points.push(point.get());
}
}
PcurveNurbsPoles::Rational { points: source } => {
for pole in source {
ctx.charge_work_limit(
u64_from_index(std::mem::size_of::<Point2>()),
point_operation,
)?;
points.push(pole.point.get());
}
let mut copied = Vec::new();
ctx.reserve_scoped_vec_limit(
&mut storage,
&mut copied,
source.len(),
weight_operation,
)?;
for pole in source {
ctx.charge_work_limit(
u64_from_index(std::mem::size_of::<f64>()),
weight_operation,
)?;
copied.push(pole.weight.get());
}
weights = Some(copied);
}
}
Ok(Self {
points,
weights,
_storage: storage,
})
}
pub fn points(&self) -> &[Point2] {
&self.points
}
pub fn weights(&self) -> Option<&[f64]> {
self.weights.as_deref()
}
}
#[cfg(test)]
mod tests;