use axiolid_core::{Point2, Point3, Scalar, Vec3};
use crate::NodeId;
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum TrimSelector {
Parameter(Scalar),
Point2(Point2),
Point3(Point3),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum TrimmingPreference {
Parameter,
Cartesian,
Unspecified,
}
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Transition {
Discontinuous,
Continuous,
ContinuousSameGradient,
ContinuousSameGradientSameCurvature,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct CurveSegment {
pub curve: NodeId,
pub same_sense: bool,
pub transition: Transition,
}
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq)]
pub enum CurveRelation {
Composite { segments: Vec<CurveSegment> },
Trimmed {
basis: NodeId,
start: Vec<TrimSelector>,
end: Vec<TrimSelector>,
sense_agreement: bool,
preference: TrimmingPreference,
},
Offset {
basis: NodeId,
distance: Scalar,
reference_direction: Option<Vec3>,
},
SurfaceCurve {
curve_3d: NodeId,
sides: SurfaceSides,
master: MasterRepresentation,
},
ParameterCurve {
basis_surface: NodeId,
reference_curve: NodeId,
},
}
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum MasterRepresentation {
Curve3d,
ParameterCurveS1,
ParameterCurveS2,
Both,
Unspecified,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct SurfaceSides {
first: (NodeId, NodeId),
second: Option<(NodeId, NodeId)>,
}
impl SurfaceSides {
#[must_use]
pub const fn one(surface: NodeId, pcurve: NodeId) -> Self {
Self {
first: (surface, pcurve),
second: None,
}
}
#[must_use]
pub const fn two(
first_surface: NodeId,
first_pcurve: NodeId,
second_surface: NodeId,
second_pcurve: NodeId,
) -> Self {
Self {
first: (first_surface, first_pcurve),
second: Some((second_surface, second_pcurve)),
}
}
#[must_use]
pub const fn first(&self) -> (NodeId, NodeId) {
self.first
}
#[must_use]
pub const fn second(&self) -> Option<(NodeId, NodeId)> {
self.second
}
#[must_use]
pub const fn is_two_sided(&self) -> bool {
self.second.is_some()
}
#[must_use]
pub fn references(&self) -> Vec<NodeId> {
let mut out = vec![self.first.0, self.first.1];
if let Some((surface, pcurve)) = self.second {
out.extend([surface, pcurve]);
}
out
}
}
impl CurveRelation {
pub(crate) fn references(&self, out: &mut Vec<NodeId>) {
match self {
Self::Composite { segments } => out.extend(segments.iter().map(|item| item.curve)),
Self::Trimmed { basis, .. } | Self::Offset { basis, .. } => out.push(*basis),
Self::SurfaceCurve {
curve_3d, sides, ..
} => {
out.push(*curve_3d);
out.extend(sides.references());
}
Self::ParameterCurve {
basis_surface,
reference_curve,
} => out.extend([*basis_surface, *reference_curve]),
}
}
}