use axiolid_brep::{Curve2Id, ExactBRep};
use axiolid_core::{Interval, Scalar};
use axiolid_nurbs::{
CertifiedSurfaceSurfaceIntersection3, CertifiedSurfaceSurfaceIntersectionOptions,
TransverseSurfaceSurfaceTrace3,
};
use axiolid_topology::{EdgeId, FaceId};
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct CertifiedSurfacePairSplitOptions {
intersection: CertifiedSurfaceSurfaceIntersectionOptions,
max_surface_residual: Scalar,
}
impl CertifiedSurfacePairSplitOptions {
pub fn new(
intersection: CertifiedSurfaceSurfaceIntersectionOptions,
max_surface_residual: Scalar,
) -> Result<Self, axiolid_contracts::GeomError> {
if !max_surface_residual.is_finite() || max_surface_residual <= 0.0 {
return Err(axiolid_contracts::GeomError::InvalidInput(
"surface-pair split residual must be finite and positive".into(),
));
}
Ok(Self {
intersection,
max_surface_residual,
})
}
pub(super) fn intersection_options(self) -> CertifiedSurfaceSurfaceIntersectionOptions {
self.intersection
}
pub(super) fn max_surface_residual(self) -> Scalar {
self.max_surface_residual
}
}
impl Default for CertifiedSurfacePairSplitOptions {
fn default() -> Self {
Self {
intersection: CertifiedSurfaceSurfaceIntersectionOptions::default(),
max_surface_residual: 1.0e-7,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SurfacePairMember {
First,
Second,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct EmbeddedFaceCurve {
pub face: FaceId,
pub edge: EdgeId,
pub pcurve: Curve2Id,
pub interval: Interval,
}
#[derive(Debug, Clone, PartialEq)]
pub struct CertifiedTrimmedSurfacePair3 {
pub brep: ExactBRep,
pub intersection_edge: EdgeId,
pub split_surface: SurfacePairMember,
pub split_faces: [FaceId; 2],
pub unsplit_face: FaceId,
pub embedded_curve: EmbeddedFaceCurve,
pub trace: TransverseSurfaceSurfaceTrace3,
pub max_surface_residual_upper_bound: Scalar,
pub visited_patch_pairs: u32,
pub boundary_queries: u32,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SurfacePairSplitUnresolvedReason {
IntersectionUnresolved,
UnsupportedTraceCount,
UnsupportedEndpointOwnership,
ResidualExceedsPolicy,
DegenerateRepresentative,
}
#[allow(clippy::large_enum_variant)]
#[derive(Debug, Clone, PartialEq)]
#[non_exhaustive]
pub enum CertifiedSurfacePairSplit3 {
Empty {
visited_patch_pairs: u32,
boundary_queries: u32,
},
Split(CertifiedTrimmedSurfacePair3),
Unresolved {
intersection: CertifiedSurfaceSurfaceIntersection3,
reason: SurfacePairSplitUnresolvedReason,
},
}