libigl v2.5.0
Loading...
Searching...
No Matches
igl::WindingNumberAntipodalScene< Scalar > Class Template Reference

Precomputed scene for the Antipodal Method generalized winding number. More...

#include <WindingNumberAntipodalScene.h>

Public Types

using Point = Eigen::Matrix<Scalar, 1, 3>
using Direction = Eigen::Matrix<Scalar, 1, 3>

Public Member Functions

template<typename DerivedV, typename DerivedF>
 WindingNumberAntipodalScene (const Eigen::MatrixBase< DerivedV > &V, const Eigen::MatrixBase< DerivedF > &F, const Direction &x0=default_x0())
 Build a scene from a 3D triangle mesh.
template<typename Intersector, typename Derivedp>
Scalar winding_number (const Intersector &intersector, const Eigen::MatrixBase< Derivedp > &p) const
 Single-point query: full generalized winding number at p (fractional + signed integer crossings).
template<typename Intersector, typename DerivedO, typename DerivedW>
void winding_number (const Intersector &intersector, const Eigen::MatrixBase< DerivedO > &O, Eigen::PlainObjectBase< DerivedW > &W) const
 Batch query, parallelized via igl::parallel_for.
const Directionx0 () const
 Reference direction x0 used to evaluate this scene.
size_t num_boundary_segments () const
 Number of weighted boundary edge segments.
size_t num_faces () const
 Number of triangles in the original mesh.

Static Public Member Functions

static Direction default_x0 ()
 Default reference direction: normalize(1, sqrt(2), sqrt(3)).
static Scalar half_solid_angle_unorm (const Direction &x1, const Point &v0, const Point &v1)
 Half the signed solid angle subtended by the spherical triangle (x1, v0, v1) at the origin, via the unnormalized Van Oosterom-Strackee formula.
template<typename DerivedV, typename DerivedF>
static void build_boundary_segments (const Eigen::MatrixBase< DerivedV > &V, const Eigen::MatrixBase< DerivedF > &F, std::vector< WeightedSeg > &out)
 Extract the open boundary as oriented, weighted edge segments.

Public Attributes

std::vector< WeightedSeg > m_boundary
Direction m_x0
size_t m_face_count = 0

Detailed Description

template<typename Scalar>
class igl::WindingNumberAntipodalScene< Scalar >

Precomputed scene for the Antipodal Method generalized winding number.

The scene stores only the weighted open-boundary edges of the input triangle mesh and a fixed antipodal reference direction x0. Closed (manifold) meshes have an empty boundary and the fractional term is exactly zero.

Querying the winding number additionally requires an Intersector that returns the signed ray-mesh crossing count along (p, x0) over the original mesh; the scene itself is intersector-agnostic. See igl::embree::EmbreeIntersector::signedIntersectionsRay for an optimized concrete implementation.

Intersector concept

A type I satisfies the concept when it exposes:

  • using OriginType = ...; (3D row vector type)
  • using DirectionType = ...; (3D row vector type)
  • int signedIntersectionsRay( OriginType origin, DirectionType direction, /* defaulted tnear, tfar, mask */) const;

winding_number casts query point/direction to the intersector's types at the call site, so a double-precision scene against a float-only intersector works without an adaptor.

Member Typedef Documentation

◆ Point

template<typename Scalar>
using igl::WindingNumberAntipodalScene< Scalar >::Point = Eigen::Matrix<Scalar, 1, 3>

◆ Direction

template<typename Scalar>
using igl::WindingNumberAntipodalScene< Scalar >::Direction = Eigen::Matrix<Scalar, 1, 3>

Constructor & Destructor Documentation

◆ WindingNumberAntipodalScene()

template<typename Scalar>
template<typename DerivedV, typename DerivedF>
igl::WindingNumberAntipodalScene< Scalar >::WindingNumberAntipodalScene ( const Eigen::MatrixBase< DerivedV > & V,
const Eigen::MatrixBase< DerivedF > & F,
const Direction & x0 = default_x0() )
inline

Build a scene from a 3D triangle mesh.

Parameters
[in]V#V by 3 list of vertex positions
[in]F#F by 3 list of triangle indices
[in]x0unit reference direction (defaults to a fixed non-axis-aligned vector)

Member Function Documentation

◆ winding_number() [1/2]

template<typename Scalar>
template<typename Intersector, typename Derivedp>
Scalar igl::WindingNumberAntipodalScene< Scalar >::winding_number ( const Intersector & intersector,
const Eigen::MatrixBase< Derivedp > & p ) const
inline

Single-point query: full generalized winding number at p (fractional + signed integer crossings).

◆ winding_number() [2/2]

template<typename Scalar>
template<typename Intersector, typename DerivedO, typename DerivedW>
void igl::WindingNumberAntipodalScene< Scalar >::winding_number ( const Intersector & intersector,
const Eigen::MatrixBase< DerivedO > & O,
Eigen::PlainObjectBase< DerivedW > & W ) const
inline

Batch query, parallelized via igl::parallel_for.

Parameters
[in]intersectorConcept-compatible intersector built over the same mesh used to construct the scene. Must be safe to query concurrently.
[in]O#O by 3 list of query points
[out]W#O by 1 list of winding numbers

◆ x0()

template<typename Scalar>
const Direction & igl::WindingNumberAntipodalScene< Scalar >::x0 ( ) const
inline

Reference direction x0 used to evaluate this scene.

◆ num_boundary_segments()

template<typename Scalar>
size_t igl::WindingNumberAntipodalScene< Scalar >::num_boundary_segments ( ) const
inline

Number of weighted boundary edge segments.

◆ num_faces()

template<typename Scalar>
size_t igl::WindingNumberAntipodalScene< Scalar >::num_faces ( ) const
inline

Number of triangles in the original mesh.

◆ default_x0()

template<typename Scalar>
Direction igl::WindingNumberAntipodalScene< Scalar >::default_x0 ( )
inlinestatic

Default reference direction: normalize(1, sqrt(2), sqrt(3)).

A fixed non-axis-aligned unit vector; any unit vector works per the paper; this choice avoids accidental alignment with axis-aligned geometry.

◆ half_solid_angle_unorm()

template<typename Scalar>
Scalar igl::WindingNumberAntipodalScene< Scalar >::half_solid_angle_unorm ( const Direction & x1,
const Point & v0,
const Point & v1 )
inlinestatic

Half the signed solid angle subtended by the spherical triangle (x1, v0, v1) at the origin, via the unnormalized Van Oosterom-Strackee formula.

x1 is expected to be a unit vector (the antipodal "south pole" -x0); v0, v1 need not be normalized. Callers accumulate per-edge contributions and divide by 2π.

◆ build_boundary_segments()

template<typename Scalar>
template<typename DerivedV, typename DerivedF>
void igl::WindingNumberAntipodalScene< Scalar >::build_boundary_segments ( const Eigen::MatrixBase< DerivedV > & V,
const Eigen::MatrixBase< DerivedF > & F,
std::vector< WeightedSeg > & out )
inlinestatic

Extract the open boundary as oriented, weighted edge segments.

Each undirected edge {min, max} accumulates +1 for every triangle that traverses it as min→max and -1 for every traversal max→min. Interior edges of an oriented manifold cancel to zero and are dropped. Surviving edges are emitted with positive weight; the segment direction is flipped when the net count is negative so the weight is always > 0. Non-manifold (≥3 incident triangles per edge) is handled the same way. The surviving net count becomes the weight.

Member Data Documentation

◆ m_boundary

template<typename Scalar>
std::vector<WeightedSeg> igl::WindingNumberAntipodalScene< Scalar >::m_boundary

◆ m_x0

template<typename Scalar>
Direction igl::WindingNumberAntipodalScene< Scalar >::m_x0

◆ m_face_count

template<typename Scalar>
size_t igl::WindingNumberAntipodalScene< Scalar >::m_face_count = 0

The documentation for this class was generated from the following file: