13#ifndef IGL_WINDINGNUMBERAABB_H
14#define IGL_WINDINGNUMBERAABB_H
48 const Eigen::MatrixBase<DerivedV> &
V,
49 const Eigen::MatrixBase<DerivedF> &
F);
52 const Eigen::MatrixBase<DerivedF> &
F);
58 const Eigen::MatrixBase<DerivedV> &
V,
59 const Eigen::MatrixBase<DerivedF> &
F);
61 inline bool inside(
const Point & p)
const;
62 inline virtual void grow();
85#ifndef WindingNumberAABB_MIN_F
86# define WindingNumberAABB_MIN_F 100
89template <
typename Po
int,
typename DerivedV,
typename DerivedF>
91 const Eigen::MatrixBase<DerivedV> & V,
92 const Eigen::MatrixBase<DerivedF> & F)
98template <
typename Po
int,
typename DerivedV,
typename DerivedF>
101 using namespace Eigen;
102 assert(max_corner.size() == 3);
103 assert(min_corner.size() == 3);
104 compute_min_max_corners();
105 Eigen::Matrix<typename DerivedV::Scalar,Eigen::Dynamic,1> dblA;
107 total_positive_area = dblA.sum()/2.0;
110template <
typename Po
int,
typename DerivedV,
typename DerivedF>
112 const Eigen::MatrixBase<DerivedV> & V,
113 const Eigen::MatrixBase<DerivedF> & F):
118 std::numeric_limits<typename DerivedV::Scalar>::infinity()),
119 split_method(MEDIAN_ON_LONGEST_AXIS)
124template <
typename Po
int,
typename DerivedV,
typename DerivedF>
127 const Eigen::MatrixBase<DerivedF> & F):
132 std::numeric_limits<typename DerivedV::Scalar>::infinity()),
133 split_method(MEDIAN_ON_LONGEST_AXIS)
138template <
typename Po
int,
typename DerivedV,
typename DerivedF>
142 using namespace Eigen;
144 this->delete_children();
151 this->getF().rows() <= (WindingNumberAABB_MIN_F>0?WindingNumberAABB_MIN_F:0) ||
152 (this->getcap().rows() - 2) >= this->getF().rows())
160 typename DerivedV::Scalar max_len =
161 -numeric_limits<typename DerivedV::Scalar>::infinity();
162 for(
int d = 0;d<min_corner.size();d++)
164 if( (max_corner[d] - min_corner[d]) > max_len )
166 max_len = (max_corner[d] - min_corner[d]);
171 Eigen::Matrix<typename DerivedV::Scalar,Eigen::Dynamic,Eigen::Dynamic> BC;
177 typename DerivedV::Scalar split_value;
181 case MEDIAN_ON_LONGEST_AXIS:
183 median(BC.col(max_d),split_value);
187 case CENTER_ON_LONGEST_AXIS:
188 split_value = 0.5*(max_corner[max_d] + min_corner[max_d]);
194 vector<int> id( this->getF().rows());
195 for(
int i = 0;i<this->getF().rows();i++)
197 if(BC(i,max_d) <= split_value)
206 const int lefts = (int)
count(
id.begin(),
id.end(),0);
207 const int rights = (int)
count(
id.begin(),
id.end(),1);
208 if(lefts == 0 || rights == 0)
213 assert(lefts+rights == this->getF().rows());
214 DerivedF leftF(lefts, this->getF().cols());
215 DerivedF rightF(rights,this->getF().cols());
218 for(
int i = 0;i<this->getF().rows();i++)
222 leftF.row(left_i++) = this->getF().row(i);
225 rightF.row(right_i++) = this->getF().row(i);
231 assert(right_i == rightF.rows());
232 assert(left_i == leftF.rows());
236 leftWindingNumberAABB->
grow();
237 this->children.push_back(leftWindingNumberAABB);
240 rightWindingNumberAABB->
grow();
241 this->children.push_back(rightWindingNumberAABB);
244template <
typename Po
int,
typename DerivedV,
typename DerivedF>
247 assert(p.size() == max_corner.size());
248 assert(p.size() == min_corner.size());
249 for(
int i = 0;i<p.size();i++)
254 if( p(i) < min_corner(i) || p(i) > max_corner(i))
262template <
typename Po
int,
typename DerivedV,
typename DerivedF>
267 for(
int d = 0;d<min_corner.size();d++)
269 min_corner[d] = numeric_limits<typename Point::Scalar>::infinity();
270 max_corner[d] = -numeric_limits<typename Point::Scalar>::infinity();
273 this->center = Point(0,0,0);
275 for(
int i = 0;i<this->getF().rows();i++)
277 for(
int j = 0;j<this->getF().cols();j++)
279 for(
int d = 0;d<min_corner.size();d++)
282 this->getV()(this->getF()(i,j),d) < min_corner[d] ?
283 this->getV()(this->getF()(i,j),d) : min_corner[d];
285 this->getV()(this->getF()(i,j),d) > max_corner[d] ?
286 this->getV()(this->getF()(i,j),d) : max_corner[d];
290 this->center += this->getV().row(this->getF()(i,j));
294 this->center.array() /= this->getF().size();
302 this->radius = (max_corner-min_corner).norm()/2.0;
305template <
typename Po
int,
typename DerivedV,
typename DerivedF>
306inline typename DerivedV::Scalar
313 return numeric_limits<typename DerivedV::Scalar>::infinity();
317 return numeric_limits<typename DerivedV::Scalar>::infinity();
320template <
typename Po
int,
typename DerivedV,
typename DerivedF>
321inline typename DerivedV::Scalar
323 const Point & p)
const
326 using namespace Eigen;
330 return numeric_limits<typename DerivedV::Scalar>::infinity();
338 Eigen::Matrix<typename DerivedV::Scalar,Eigen::Dynamic,Eigen::Dynamic>
341 Eigen::Matrix<typename DerivedF::Scalar,Eigen::Dynamic,Eigen::Dynamic>
345 min_corner[0],min_corner[1],min_corner[2],
346 min_corner[0],min_corner[1],max_corner[2],
347 min_corner[0],max_corner[1],min_corner[2],
348 min_corner[0],max_corner[1],max_corner[2],
349 max_corner[0],min_corner[1],min_corner[2],
350 max_corner[0],min_corner[1],max_corner[2],
351 max_corner[0],max_corner[1],min_corner[2],
352 max_corner[0],max_corner[1],max_corner[2];
374 Point p2c = 0.5*(min_corner+max_corner)-p;
375 for(
int i = 0;i<BFN.rows();i++)
377 if(p2c.dot(BFN.row(i)) > 0)
379 PBF.row(pbfi++) = BF.row(i);
382 PBF.conservativeResize(pbfi,PBF.cols());
392 template <>
inline igl::WindingNumberAABB<Eigen::Matrix<double, 1, 3, 1, 1, 3>,Eigen::Matrix<double, -1, 2, 0, -1, 2>,Eigen::Matrix<int, -1, 2, 0, -1, 2>>::WindingNumberAABB(
const Eigen::MatrixBase<Eigen::Matrix<double, -1, 2, 0, -1, 2>> & ,
const Eigen::MatrixBase<Eigen::Matrix<int, -1, 2, 0, -1, 2>> & ){};
393 template <>
inline void igl::WindingNumberAABB<Eigen::Matrix<double, 1, 3, 1, 1, 3>,Eigen::Matrix<double, -1, 2, 0, -1, 2>,Eigen::Matrix<int, -1, 2, 0, -1, 2>>::grow(){};
394 template <>
inline void igl::WindingNumberAABB<Eigen::Matrix<double, 1, 3, 1, 1, 3>,Eigen::Matrix<double, -1, 2, 0, -1, 2>,Eigen::Matrix<int, -1, 2, 0, -1, 2>>::init(){};
Class for building an AABB tree to implement the divide and conquer algorithm described in [Jacobson ...
Definition WindingNumberAABB.h:26
virtual void grow()
Definition WindingNumberAABB.h:139
Point min_corner
Definition WindingNumberAABB.h:28
DerivedV::Scalar total_positive_area
Definition WindingNumberAABB.h:30
void set_mesh(const Eigen::MatrixBase< DerivedV > &V, const Eigen::MatrixBase< DerivedF > &F)
Initialize the hierarchy to a given mesh.
Definition WindingNumberAABB.h:90
WindingNumberAABB()
Definition WindingNumberAABB.h:39
SplitMethod
Definition WindingNumberAABB.h:33
@ CENTER_ON_LONGEST_AXIS
Definition WindingNumberAABB.h:34
@ MEDIAN_ON_LONGEST_AXIS
Definition WindingNumberAABB.h:35
@ NUM_SPLIT_METHODS
Definition WindingNumberAABB.h:36
DerivedV::Scalar max_simple_abs_winding_number(const Point &p) const
Definition WindingNumberAABB.h:322
Point max_corner
Definition WindingNumberAABB.h:29
enum igl::WindingNumberAABB::SplitMethod split_method
bool inside(const Point &p) const
Definition WindingNumberAABB.h:245
void init()
Definition WindingNumberAABB.h:99
DerivedV::Scalar max_abs_winding_number(const Point &p) const
Definition WindingNumberAABB.h:307
void compute_min_max_corners()
Definition WindingNumberAABB.h:263
Space partitioning tree for computing winding number hierarchically.
Definition WindingNumberTree.h:25
Eigen::Matrix< typename DerivedF::Scalar, Eigen::Dynamic, Eigen::Dynamic > MatrixXF
Definition WindingNumberTree.h:45
const WindingNumberTree * parent
Definition WindingNumberTree.h:38
DerivedV & V
Definition WindingNumberTree.h:49
virtual void set_mesh(const Eigen::MatrixBase< DerivedV > &V, const Eigen::MatrixBase< DerivedF > &F)
Definition WindingNumberTree.h:189
Eigen::Matrix< typename DerivedV::Scalar, Eigen::Dynamic, Eigen::Dynamic > MatrixXS
Definition WindingNumberTree.h:42
MatrixXF F
Definition WindingNumberTree.h:53
void per_face_normals(const Eigen::MatrixBase< DerivedV > &V, const Eigen::MatrixBase< DerivedF > &F, const Eigen::MatrixBase< DerivedZ > &Z, Eigen::PlainObjectBase< DerivedN > &N)
Compute face normals via vertex position list, face list.
void winding_number(const Eigen::MatrixBase< DerivedV > &V, const Eigen::MatrixBase< DerivedF > &F, const Eigen::MatrixBase< DerivedO > &O, Eigen::PlainObjectBase< DerivedW > &W)
Computes the generalized winding number at each dim-dimensional query point in O with respect to the ...
void doublearea(const Eigen::MatrixBase< DerivedV > &V, const Eigen::MatrixBase< DerivedF > &F, Eigen::PlainObjectBase< DeriveddblA > &dblA)
Computes twice the area for each input triangle or quad.
void count(const Eigen::SparseMatrix< XType > &X, const int dim, Eigen::SparseVector< SType > &S)
Count the number of non-zeros in the columns or rows of a sparse matrix.
void barycenter(const Eigen::MatrixBase< DerivedV > &V, const Eigen::MatrixBase< DerivedF > &F, Eigen::PlainObjectBase< DerivedBC > &BC)
Computes the barycenter of every simplex.
bool median(const Eigen::MatrixBase< DerivedV > &V, mType &m)
Compute the median of an eigen vector.