//! Native analytic geometry policy; original-editor numerical parity is unverified. pub mod math; pub use math::{Aabb, DVec3, Equation, Policy}; use std::fmt; #[derive(Clone, Debug, PartialEq, Eq)] pub enum Error { NonFinite, Degenerate, InvalidPolicy, InvalidDimensions, InvalidBrush, Limit, Allocation, Overflow, FloatRange, InconsistentData, } impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "geometry: {self:?}") } } impl std::error::Error for Error {} pub type Result = std::result::Result; pub(crate) fn alloc(n: usize) -> Result> { let mut out = Vec::new(); out.try_reserve_exact(n).map_err(|_| Error::Allocation)?; Ok(out) } pub mod brush; #[derive(Clone, Copy, Debug)] pub struct ComputeLimits { pub max_planes: usize, pub max_vertices: usize, pub max_work: usize, pub max_owned_bytes: usize, } impl Default for ComputeLimits { fn default() -> Self { Self { max_planes: 64, max_vertices: 100_000, max_work: 10_000_000, max_owned_bytes: 128 * 1024 * 1024, } } } #[derive(Clone, Copy, Debug, Default)] pub struct Stats { pub work: usize, pub owned: usize, pub vertices: usize, } pub(crate) struct Budget { pub limits: ComputeLimits, pub stats: Stats, } impl Budget { fn work(&mut self, n: usize) -> Result<()> { self.stats.work = self.stats.work.checked_add(n).ok_or(Error::Overflow)?; if self.stats.work > self.limits.max_work { Err(Error::Limit) } else { Ok(()) } } fn bytes(&mut self, n: usize) -> Result<()> { self.stats.owned = self.stats.owned.checked_add(n).ok_or(Error::Overflow)?; if self.stats.owned > self.limits.max_owned_bytes { Err(Error::Limit) } else { Ok(()) } } fn reserve(&mut self, n: usize) -> Result> { self.bytes( n.checked_mul(std::mem::size_of::()) .ok_or(Error::Overflow)?, )?; alloc(n) } fn push(&mut self, out: &mut Vec, v: T) -> Result<()> { if out.len() == out.capacity() { let cap = out .capacity() .saturating_mul(2) .max(1) .min(self.limits.max_vertices); if cap <= out.len() { return Err(Error::Limit); } self.bytes( (cap - out.capacity()) .checked_mul(std::mem::size_of::()) .ok_or(Error::Overflow)?, )?; out.try_reserve_exact(cap - out.len()) .map_err(|_| Error::Allocation)?; } out.push(v); Ok(()) } } pub mod patch; pub mod ray; pub mod world;