Oracle: 25/29 (14 and 15 now match Fusion). Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
183 lines
4.6 KiB
Rust
183 lines
4.6 KiB
Rust
use truck_meshalgo::prelude::*;
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub enum Alternative<T, U> {
|
|
FirstType(T),
|
|
SecondType(U),
|
|
}
|
|
|
|
#[doc(hidden)]
|
|
#[macro_export]
|
|
macro_rules! impl_from {
|
|
($firsttype: ty, $secondtype: ty) => {
|
|
impl From<$firsttype> for $crate::alternative::Alternative<$firsttype, $secondtype> {
|
|
#[inline(always)]
|
|
fn from(t: $firsttype) -> Self { $crate::alternative::Alternative::FirstType(t) }
|
|
}
|
|
};
|
|
}
|
|
|
|
impl<T, U> From<U> for Alternative<T, U> {
|
|
#[inline(always)]
|
|
fn from(u: U) -> Self { Alternative::SecondType(u) }
|
|
}
|
|
|
|
// test for impl_from
|
|
impl_from!((), usize);
|
|
|
|
macro_rules! derive_method {
|
|
($method: tt, $return_type: ty, $($var: ident : $paramtype: ty),*) => {
|
|
fn $method (&self, $($var: $paramtype),*) -> $return_type {
|
|
match &self {
|
|
Alternative::FirstType(got) => got.$method($($var),*),
|
|
Alternative::SecondType(got) => got.$method($($var),*),
|
|
}
|
|
}
|
|
};
|
|
($method: tt <$x: ident : $y: path>, $return_type: ty, $($var: ident : $paramtype: ty),*) => {
|
|
fn $method<$x : $y>(&self, $($var: $paramtype),*) -> $return_type {
|
|
match &self {
|
|
Alternative::FirstType(got) => got.$method($($var),*),
|
|
Alternative::SecondType(got) => got.$method($($var),*),
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
impl<C0, C1> ParametricCurve for Alternative<C0, C1>
|
|
where
|
|
C0: ParametricCurve,
|
|
C1: ParametricCurve<Point = C0::Point, Vector = C0::Vector>,
|
|
{
|
|
type Point = C0::Point;
|
|
type Vector = C0::Vector;
|
|
derive_method!(subs, C0::Point, t: f64);
|
|
derive_method!(der, C0::Vector, t: f64);
|
|
derive_method!(der2, C0::Vector, t: f64);
|
|
derive_method!(
|
|
parameter_range,
|
|
(std::ops::Bound<f64>, std::ops::Bound<f64>),
|
|
);
|
|
}
|
|
|
|
impl<C0, C1> BoundedCurve for Alternative<C0, C1>
|
|
where
|
|
C0: BoundedCurve,
|
|
C1: BoundedCurve<Point = C0::Point, Vector = C0::Vector>,
|
|
{
|
|
}
|
|
|
|
impl<S0, S1> ParametricSurface for Alternative<S0, S1>
|
|
where
|
|
S0: ParametricSurface,
|
|
S1: ParametricSurface<Point = S0::Point, Vector = S0::Vector>,
|
|
{
|
|
type Point = S0::Point;
|
|
type Vector = S0::Vector;
|
|
derive_method!(subs, S0::Point, u: f64, v: f64);
|
|
derive_method!(uder, S0::Vector, u: f64, v: f64);
|
|
derive_method!(vder, S0::Vector, u: f64, v: f64);
|
|
derive_method!(uuder, S0::Vector, u: f64, v: f64);
|
|
derive_method!(uvder, S0::Vector, u: f64, v: f64);
|
|
derive_method!(vvder, S0::Vector, u: f64, v: f64);
|
|
}
|
|
|
|
impl<S0, S1> ParametricSurface3D for Alternative<S0, S1>
|
|
where
|
|
S0: ParametricSurface3D,
|
|
S1: ParametricSurface3D,
|
|
{
|
|
derive_method!(normal, Vector3, u: f64, v: f64);
|
|
}
|
|
|
|
impl<C0, C1> Cut for Alternative<C0, C1>
|
|
where
|
|
C0: Cut,
|
|
C1: Cut<Point = C0::Point, Vector = C0::Vector>,
|
|
{
|
|
fn cut(&mut self, t: f64) -> Self {
|
|
match self {
|
|
Self::FirstType(curve) => Self::FirstType(curve.cut(t)),
|
|
Self::SecondType(curve) => Self::SecondType(curve.cut(t)),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<C0, C1> ParameterDivision1D for Alternative<C0, C1>
|
|
where
|
|
C0: ParameterDivision1D,
|
|
C1: ParameterDivision1D<Point = C0::Point>,
|
|
{
|
|
type Point = C0::Point;
|
|
derive_method!(
|
|
parameter_division,
|
|
(Vec<f64>, Vec<C0::Point>),
|
|
range: (f64, f64),
|
|
tol: f64
|
|
);
|
|
}
|
|
|
|
impl<S0, S1> ParameterDivision2D for Alternative<S0, S1>
|
|
where
|
|
S0: ParameterDivision2D,
|
|
S1: ParameterDivision2D,
|
|
{
|
|
derive_method!(
|
|
parameter_division,
|
|
(Vec<f64>, Vec<f64>),
|
|
range: ((f64, f64), (f64, f64)),
|
|
tol: f64
|
|
);
|
|
}
|
|
|
|
impl<D: SPDimension, T, U> SearchParameter<D> for Alternative<T, U>
|
|
where
|
|
T: SearchParameter<D>,
|
|
U: SearchParameter<D, Point = T::Point>,
|
|
{
|
|
type Point = T::Point;
|
|
derive_method!(
|
|
search_parameter<H: Into<D::Hint>>,
|
|
Option<D::Parameter>,
|
|
point: T::Point,
|
|
hint: H,
|
|
trials: usize
|
|
);
|
|
}
|
|
|
|
impl<D: SPDimension, T, U> SearchNearestParameter<D> for Alternative<T, U>
|
|
where
|
|
T: SearchNearestParameter<D>,
|
|
U: SearchNearestParameter<D, Point = T::Point>,
|
|
{
|
|
type Point = T::Point;
|
|
derive_method!(
|
|
search_nearest_parameter<H: Into<D::Hint>>,
|
|
Option<D::Parameter>,
|
|
point: T::Point,
|
|
hint: H,
|
|
trials: usize
|
|
);
|
|
}
|
|
|
|
impl<T, U> Invertible for Alternative<T, U>
|
|
where
|
|
T: Invertible,
|
|
U: Invertible,
|
|
{
|
|
#[inline(always)]
|
|
fn invert(&mut self) {
|
|
match self {
|
|
Self::FirstType(entity) => entity.invert(),
|
|
Self::SecondType(entity) => entity.invert(),
|
|
}
|
|
}
|
|
#[inline(always)]
|
|
fn inverse(&self) -> Self {
|
|
match self {
|
|
Self::FirstType(entity) => Self::FirstType(entity.inverse()),
|
|
Self::SecondType(entity) => Self::SecondType(entity.inverse()),
|
|
}
|
|
}
|
|
}
|