pub enum OffsetNormal {
Raw,
Face {
same_sense: bool,
},
FaceStable {
same_sense: bool,
},
ExactAnalytic {
same_sense: bool,
},
}Expand description
Which unit normal the offset rides, and how it is recovered where the parametric normal degenerates.
Every variant names an existing in-tree formula and is bit-identical to it.
They differ ONLY where the parameter leaves the domain or the cross product
S_u × S_v collapses; a shared evaluator that silently picked one for
everybody would move behaviour at exactly the singular points the callers
each decided about on purpose.
Variants§
Raw
The bare S_u × S_v, normalized, through the C¹ domain extension
(deriv1_extended). Orientation is the caller’s business — the blend
march carries it in the sign of ρ instead (signed_radii), which is why
this variant must not apply same_sense.
No singular recovery: where the cross product collapses this is an error, deliberately, so the march keeps refusing exactly where it refuses today.
Bit-identical to blending::blend::stations::raw_normal (and to
evaluate_extended for the point).
Face
NurbsSurface::normal — the in-domain derivatives(u, v, 1) cross —
negated when same_sense is false. Clamped, not extended, and no
singular recovery.
Bit-identical to the let mut normal = surface.normal(u, v)?; if !face.same_sense { normal = normal.scale(-1.0) } block written out in
face_offset_revolution.rs, face_offset_freeform.rs,
face_offset_torus.rs and offset_shell/smooth_sync.rs::face_normal.
FaceStable
OffsetNormal::Face plus the singular-row recovery that
offset_surface depends on: nudge off a point where the normal is
undefined, and at a collapsed parameter row (a cone apex) walk deep
inward for the true per-ruling limit rather than accept the axis
direction the at-point cross degenerates to.
Bit-identical to the former offset::stable_face_normal, whose body
this is. The blend march must NOT inherit it — the recovery would
change the residual at poles, so it stays opt-in (audit slice 1,
“keep it as an opt-in flag”).
ExactAnalytic
The exact closed-form normal of the recognised analytic carrier,
oriented like OffsetNormal::Face.
This is the “exact per analytic surface type” lane: a sphere’s normal is
(p − centre)/r — defined at the poles, where S_u × S_v vanishes — a
cylinder’s is its radial direction, a cone’s is the meridian
perpendicular (defined even AT the apex, from the ruling’s own azimuth),
a torus’s is (p − tube centre)/r. Where there is no exact form (the
general Revolution, and every free-form patch) it falls back to
OffsetNormal::Face, so this variant is always at least as defined as
that one.
NurbsSurface::analytic memoizes per instance, so recognition is paid
once per surface, not once per point.
No consumer rides this lane yet. It exists as the exact half of the
evaluator’s contract and as the diagnostic’s comparator; switching a
caller onto it changes that caller’s last digits and is a separate,
measured step. See [offset_normal_diagnostic].
Trait Implementations§
Source§impl Clone for OffsetNormal
impl Clone for OffsetNormal
Source§fn clone(&self) -> OffsetNormal
fn clone(&self) -> OffsetNormal
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreimpl Copy for OffsetNormal
Source§impl Debug for OffsetNormal
impl Debug for OffsetNormal
impl Eq for OffsetNormal
Source§impl PartialEq for OffsetNormal
impl PartialEq for OffsetNormal
impl StructuralPartialEq for OffsetNormal
Auto Trait Implementations§
impl Freeze for OffsetNormal
impl RefUnwindSafe for OffsetNormal
impl Send for OffsetNormal
impl Sync for OffsetNormal
impl Unpin for OffsetNormal
impl UnsafeUnpin for OffsetNormal
impl UnwindSafe for OffsetNormal
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.