use axiolid_contracts::{
Backend, CancellationGranularity, ExecutionOptions, GeomResult, ScratchRequirement,
};
use axiolid_core::{Frame3, Point2};
use axiolid_mesh::TriMesh;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SectionLimits {
pub max_source_vertices: usize,
pub max_source_triangles: usize,
pub max_output_vertices: usize,
pub max_contours: usize,
}
impl SectionLimits {
pub const fn new(
max_source_vertices: usize,
max_source_triangles: usize,
max_output_vertices: usize,
max_contours: usize,
) -> Self {
Self {
max_source_vertices,
max_source_triangles,
max_output_vertices,
max_contours,
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct SectionContour {
pub points: Vec<Point2>,
closed: bool,
}
impl SectionContour {
pub fn new(points: Vec<Point2>) -> Self {
Self {
points,
closed: true,
}
}
pub const fn is_closed(&self) -> bool {
self.closed
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum SectionSource {
InputMesh,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SectionEvidence {
pub source: SectionSource,
pub source_triangles: usize,
pub output_vertices: usize,
pub output_contours: usize,
}
impl SectionEvidence {
pub const fn input_mesh(
source_triangles: usize,
output_vertices: usize,
output_contours: usize,
) -> Self {
Self {
source: SectionSource::InputMesh,
source_triangles,
output_vertices,
output_contours,
}
}
pub const fn is_derived_from_input_mesh(self) -> bool {
matches!(self.source, SectionSource::InputMesh)
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct SectionOutcome {
pub frame: Frame3,
pub contours: Vec<SectionContour>,
pub evidence: SectionEvidence,
}
impl SectionOutcome {
pub fn new(frame: Frame3, contours: Vec<SectionContour>, evidence: SectionEvidence) -> Self {
Self {
frame,
contours,
evidence,
}
}
}
pub trait MeshPlaneSection: Backend {
fn scratch_requirement(&self) -> ScratchRequirement {
ScratchRequirement::Unbounded
}
fn cancellation_granularity(&self) -> CancellationGranularity {
CancellationGranularity::None
}
fn section(
&self,
mesh: &TriMesh,
frame: Frame3,
limits: SectionLimits,
options: &ExecutionOptions,
) -> GeomResult<SectionOutcome>;
}