1 // This file is part of libigl, a simple c++ geometry processing library.
2 //
3 // Copyright (C) 2014 Alec Jacobson <alecjacobson@gmail.com>
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public License
6 // v. 2.0. If a copy of the MPL was not distributed with this file, You can
7 // obtain one at http://mozilla.org/MPL/2.0/.
8 #include "signed_distance.h"
9 #include "get_seconds.h"
10 #include "per_edge_normals.h"
11 #include "parallel_for.h"
12 #include "per_face_normals.h"
13 #include "per_vertex_normals.h"
14 #include "point_mesh_squared_distance.h"
15 #include "pseudonormal_test.h"
16 
17 
18 template <
19   typename DerivedP,
20   typename DerivedV,
21   typename DerivedF,
22   typename DerivedS,
23   typename DerivedI,
24   typename DerivedC,
25   typename DerivedN>
signed_distance(const Eigen::MatrixBase<DerivedP> & P,const Eigen::MatrixBase<DerivedV> & V,const Eigen::MatrixBase<DerivedF> & F,const SignedDistanceType sign_type,const typename DerivedV::Scalar lower_bound,const typename DerivedV::Scalar upper_bound,Eigen::PlainObjectBase<DerivedS> & S,Eigen::PlainObjectBase<DerivedI> & I,Eigen::PlainObjectBase<DerivedC> & C,Eigen::PlainObjectBase<DerivedN> & N)26 IGL_INLINE void igl::signed_distance(
27   const Eigen::MatrixBase<DerivedP> & P,
28   const Eigen::MatrixBase<DerivedV> & V,
29   const Eigen::MatrixBase<DerivedF> & F,
30   const SignedDistanceType sign_type,
31   const typename DerivedV::Scalar lower_bound,
32   const typename DerivedV::Scalar upper_bound,
33   Eigen::PlainObjectBase<DerivedS> & S,
34   Eigen::PlainObjectBase<DerivedI> & I,
35   Eigen::PlainObjectBase<DerivedC> & C,
36   Eigen::PlainObjectBase<DerivedN> & N)
37 {
38   using namespace Eigen;
39   using namespace std;
40   const int dim = V.cols();
41   assert((V.cols() == 3||V.cols() == 2) && "V should have 3d or 2d positions");
42   assert((P.cols() == 3||P.cols() == 2) && "P should have 3d or 2d positions");
43   assert(V.cols() == P.cols() && "V should have same dimension as P");
44   // Only unsigned distance is supported for non-triangles
45   if(sign_type != SIGNED_DISTANCE_TYPE_UNSIGNED)
46   {
47     assert(F.cols() == dim && "F should have co-dimension 0 simplices");
48   }
49   typedef Eigen::Matrix<typename DerivedV::Scalar,1,3> RowVector3S;
50 
51   // Prepare distance computation
52   AABB<DerivedV,3> tree3;
53   AABB<DerivedV,2> tree2;
54   switch(dim)
55   {
56     default:
57     case 3:
58       tree3.init(V,F);
59       break;
60     case 2:
61       tree2.init(V,F);
62       break;
63   }
64 
65   Eigen::Matrix<typename DerivedV::Scalar,Eigen::Dynamic,3> FN,VN,EN;
66   Eigen::Matrix<typename DerivedF::Scalar,Eigen::Dynamic,2> E;
67   Eigen::Matrix<typename DerivedF::Scalar,Eigen::Dynamic,1> EMAP;
68   WindingNumberAABB<RowVector3S,DerivedV,DerivedF> hier3;
69   switch(sign_type)
70   {
71     default:
72       assert(false && "Unknown SignedDistanceType");
73     case SIGNED_DISTANCE_TYPE_UNSIGNED:
74       // do nothing
75       break;
76     case SIGNED_DISTANCE_TYPE_DEFAULT:
77     case SIGNED_DISTANCE_TYPE_WINDING_NUMBER:
78       switch(dim)
79       {
80         default:
81         case 3:
82           hier3.set_mesh(V,F);
83           hier3.grow();
84           break;
85         case 2:
86           // no precomp, no hierarchy
87           break;
88       }
89       break;
90     case SIGNED_DISTANCE_TYPE_PSEUDONORMAL:
91       switch(dim)
92       {
93         default:
94         case 3:
95           // "Signed Distance Computation Using the Angle Weighted Pseudonormal"
96           // [Bærentzen & Aanæs 2005]
97           per_face_normals(V,F,FN);
98           per_vertex_normals(V,F,PER_VERTEX_NORMALS_WEIGHTING_TYPE_ANGLE,FN,VN);
99           per_edge_normals(
100             V,F,PER_EDGE_NORMALS_WEIGHTING_TYPE_UNIFORM,FN,EN,E,EMAP);
101           break;
102         case 2:
103           FN.resize(F.rows(),2);
104           VN = DerivedV::Zero(V.rows(),2);
105           for(int e = 0;e<F.rows();e++)
106           {
107             // rotate edge vector
108             FN(e,0) =  (V(F(e,1),1)-V(F(e,0),1));
109             FN(e,1) = -(V(F(e,1),0)-V(F(e,0),0));
110             FN.row(e).normalize();
111             // add to vertex normal
112             VN.row(F(e,1)) += FN.row(e);
113             VN.row(F(e,0)) += FN.row(e);
114           }
115           // normalize to average
116           VN.rowwise().normalize();
117           break;
118       }
119       N.resize(P.rows(),dim);
120       break;
121   }
122   //
123   // convert to bounds on (unsiged) squared distances
124   typedef typename DerivedV::Scalar Scalar;
125   const Scalar max_abs = std::max(std::abs(lower_bound),std::abs(upper_bound));
126   const Scalar up_sqr_d = std::pow(max_abs,2.0);
127   const Scalar low_sqr_d =
128     std::pow(std::max(max_abs-(upper_bound-lower_bound),(Scalar)0.0),2.0);
129 
130   S.resize(P.rows(),1);
131   I.resize(P.rows(),1);
132   C.resize(P.rows(),dim);
133 
134   parallel_for(P.rows(),[&](const int p)
135   //for(int p = 0;p<P.rows();p++)
136   {
137     RowVector3S q3;
138     Eigen::Matrix<typename DerivedV::Scalar,1,2>  q2;
139     switch(P.cols())
140     {
141       default:
142       case 3:
143         q3.head(P.row(p).size()) = P.row(p);
144         break;
145       case 2:
146         q2 = P.row(p).head(2);
147         break;
148     }
149     typename DerivedV::Scalar s=1,sqrd=0;
150     Eigen::Matrix<typename DerivedV::Scalar,1,Eigen::Dynamic>  c;
151     RowVector3S c3;
152     Eigen::Matrix<typename DerivedV::Scalar,1,2>  c2;
153     int i=-1;
154     // in all cases compute squared unsiged distances
155     sqrd = dim==3?
156       tree3.squared_distance(V,F,q3,low_sqr_d,up_sqr_d,i,c3):
157       tree2.squared_distance(V,F,q2,low_sqr_d,up_sqr_d,i,c2);
158     if(sqrd >= up_sqr_d || sqrd <= low_sqr_d)
159     {
160       // Out of bounds gets a nan (nans on grids can be flood filled later using
161       // igl::flood_fill)
162       S(p) = std::numeric_limits<double>::quiet_NaN();
163       I(p) = F.rows()+1;
164       C.row(p).setConstant(0);
165     }else
166     {
167       // Determine sign
168       switch(sign_type)
169       {
170         default:
171           assert(false && "Unknown SignedDistanceType");
172         case SIGNED_DISTANCE_TYPE_UNSIGNED:
173           break;
174         case SIGNED_DISTANCE_TYPE_DEFAULT:
175         case SIGNED_DISTANCE_TYPE_WINDING_NUMBER:
176         {
177           Scalar w = 0;
178           if(dim == 3)
179           {
180             s = 1.-2.*hier3.winding_number(q3.transpose());
181           }else
182           {
183             assert(!V.derived().IsRowMajor);
184             assert(!F.derived().IsRowMajor);
185             s = 1.-2.*winding_number(V,F,q2);
186           }
187           break;
188         }
189         case SIGNED_DISTANCE_TYPE_PSEUDONORMAL:
190         {
191           RowVector3S n3;
192           Eigen::Matrix<typename DerivedV::Scalar,1,2>  n2;
193           dim==3 ?
194             pseudonormal_test(V,F,FN,VN,EN,EMAP,q3,i,c3,s,n3):
195             pseudonormal_test(V,E,EN,VN,q2,i,c2,s,n2);
196           Eigen::Matrix<typename DerivedV::Scalar,1,Eigen::Dynamic>  n;
197           (dim==3 ? n = n3 : n = n2);
198           N.row(p) = n;
199           break;
200         }
201       }
202       I(p) = i;
203       S(p) = s*sqrt(sqrd);
204       C.row(p) = (dim==3 ? c=c3 : c=c2);
205     }
206   }
207   ,10000);
208 }
209 
210 template <
211   typename DerivedP,
212   typename DerivedV,
213   typename DerivedF,
214   typename DerivedS,
215   typename DerivedI,
216   typename DerivedC,
217   typename DerivedN>
signed_distance(const Eigen::MatrixBase<DerivedP> & P,const Eigen::MatrixBase<DerivedV> & V,const Eigen::MatrixBase<DerivedF> & F,const SignedDistanceType sign_type,Eigen::PlainObjectBase<DerivedS> & S,Eigen::PlainObjectBase<DerivedI> & I,Eigen::PlainObjectBase<DerivedC> & C,Eigen::PlainObjectBase<DerivedN> & N)218 IGL_INLINE void igl::signed_distance(
219   const Eigen::MatrixBase<DerivedP> & P,
220   const Eigen::MatrixBase<DerivedV> & V,
221   const Eigen::MatrixBase<DerivedF> & F,
222   const SignedDistanceType sign_type,
223   Eigen::PlainObjectBase<DerivedS> & S,
224   Eigen::PlainObjectBase<DerivedI> & I,
225   Eigen::PlainObjectBase<DerivedC> & C,
226   Eigen::PlainObjectBase<DerivedN> & N)
227 {
228   typedef typename DerivedV::Scalar Scalar;
229   Scalar lower = std::numeric_limits<Scalar>::min();
230   Scalar upper = std::numeric_limits<Scalar>::max();
231   return signed_distance(P,V,F,sign_type,lower,upper,S,I,C,N);
232 }
233 
234 
235 template <
236   typename DerivedV,
237   typename DerivedF,
238   typename DerivedFN,
239   typename DerivedVN,
240   typename DerivedEN,
241   typename DerivedEMAP,
242   typename Derivedq>
signed_distance_pseudonormal(const AABB<DerivedV,3> & tree,const Eigen::MatrixBase<DerivedV> & V,const Eigen::MatrixBase<DerivedF> & F,const Eigen::MatrixBase<DerivedFN> & FN,const Eigen::MatrixBase<DerivedVN> & VN,const Eigen::MatrixBase<DerivedEN> & EN,const Eigen::MatrixBase<DerivedEMAP> & EMAP,const Eigen::MatrixBase<Derivedq> & q)243 IGL_INLINE typename DerivedV::Scalar igl::signed_distance_pseudonormal(
244   const AABB<DerivedV,3> & tree,
245   const Eigen::MatrixBase<DerivedV> & V,
246   const Eigen::MatrixBase<DerivedF> & F,
247   const Eigen::MatrixBase<DerivedFN> & FN,
248   const Eigen::MatrixBase<DerivedVN> & VN,
249   const Eigen::MatrixBase<DerivedEN> & EN,
250   const Eigen::MatrixBase<DerivedEMAP> & EMAP,
251   const Eigen::MatrixBase<Derivedq> & q)
252 {
253   typename DerivedV::Scalar s,sqrd;
254   Eigen::Matrix<typename DerivedV::Scalar,1,3> n,c;
255   int i = -1;
256   signed_distance_pseudonormal(tree,V,F,FN,VN,EN,EMAP,q,s,sqrd,i,c,n);
257   return s*sqrt(sqrd);
258 }
259 
260 template <
261   typename DerivedP,
262   typename DerivedV,
263   typename DerivedF,
264   typename DerivedFN,
265   typename DerivedVN,
266   typename DerivedEN,
267   typename DerivedEMAP,
268   typename DerivedS,
269   typename DerivedI,
270   typename DerivedC,
271   typename DerivedN>
signed_distance_pseudonormal(const Eigen::MatrixBase<DerivedP> & P,const Eigen::MatrixBase<DerivedV> & V,const Eigen::MatrixBase<DerivedF> & F,const AABB<DerivedV,3> & tree,const Eigen::MatrixBase<DerivedFN> & FN,const Eigen::MatrixBase<DerivedVN> & VN,const Eigen::MatrixBase<DerivedEN> & EN,const Eigen::MatrixBase<DerivedEMAP> & EMAP,Eigen::PlainObjectBase<DerivedS> & S,Eigen::PlainObjectBase<DerivedI> & I,Eigen::PlainObjectBase<DerivedC> & C,Eigen::PlainObjectBase<DerivedN> & N)272 IGL_INLINE void igl::signed_distance_pseudonormal(
273   const Eigen::MatrixBase<DerivedP> & P,
274   const Eigen::MatrixBase<DerivedV> & V,
275   const Eigen::MatrixBase<DerivedF> & F,
276   const AABB<DerivedV,3> & tree,
277   const Eigen::MatrixBase<DerivedFN> & FN,
278   const Eigen::MatrixBase<DerivedVN> & VN,
279   const Eigen::MatrixBase<DerivedEN> & EN,
280   const Eigen::MatrixBase<DerivedEMAP> & EMAP,
281   Eigen::PlainObjectBase<DerivedS> & S,
282   Eigen::PlainObjectBase<DerivedI> & I,
283   Eigen::PlainObjectBase<DerivedC> & C,
284   Eigen::PlainObjectBase<DerivedN> & N)
285 {
286   using namespace Eigen;
287   const size_t np = P.rows();
288   S.resize(np,1);
289   I.resize(np,1);
290   N.resize(np,3);
291   C.resize(np,3);
292   typedef typename AABB<DerivedV,3>::RowVectorDIMS RowVector3S;
293 # pragma omp parallel for if(np>1000)
294   for(std::ptrdiff_t p = 0;p<np;p++)
295   {
296     typename DerivedV::Scalar s,sqrd;
297     RowVector3S n,c;
298     int i = -1;
299     RowVector3S q = P.row(p);
300     signed_distance_pseudonormal(tree,V,F,FN,VN,EN,EMAP,q,s,sqrd,i,c,n);
301     S(p) = s*sqrt(sqrd);
302     I(p) = i;
303     N.row(p) = n;
304     C.row(p) = c;
305   }
306 }
307 
308 template <
309   typename DerivedV,
310   typename DerivedF,
311   typename DerivedFN,
312   typename DerivedVN,
313   typename DerivedEN,
314   typename DerivedEMAP,
315   typename Derivedq,
316   typename Scalar,
317   typename Derivedc,
318   typename Derivedn>
signed_distance_pseudonormal(const AABB<DerivedV,3> & tree,const Eigen::MatrixBase<DerivedV> & V,const Eigen::MatrixBase<DerivedF> & F,const Eigen::MatrixBase<DerivedFN> & FN,const Eigen::MatrixBase<DerivedVN> & VN,const Eigen::MatrixBase<DerivedEN> & EN,const Eigen::MatrixBase<DerivedEMAP> & EMAP,const Eigen::MatrixBase<Derivedq> & q,Scalar & s,Scalar & sqrd,int & i,Eigen::PlainObjectBase<Derivedc> & c,Eigen::PlainObjectBase<Derivedn> & n)319 IGL_INLINE void igl::signed_distance_pseudonormal(
320   const AABB<DerivedV,3> & tree,
321   const Eigen::MatrixBase<DerivedV> & V,
322   const Eigen::MatrixBase<DerivedF> & F,
323   const Eigen::MatrixBase<DerivedFN> & FN,
324   const Eigen::MatrixBase<DerivedVN> & VN,
325   const Eigen::MatrixBase<DerivedEN> & EN,
326   const Eigen::MatrixBase<DerivedEMAP> & EMAP,
327   const Eigen::MatrixBase<Derivedq> & q,
328   Scalar & s,
329   Scalar & sqrd,
330   int & i,
331   Eigen::PlainObjectBase<Derivedc> & c,
332   Eigen::PlainObjectBase<Derivedn> & n)
333 {
334   using namespace Eigen;
335   using namespace std;
336   //typedef Eigen::Matrix<typename DerivedV::Scalar,1,3> RowVector3S;
337   // Alec: Why was this constructor around q necessary?
338   //sqrd = tree.squared_distance(V,F,RowVector3S(q),i,(RowVector3S&)c);
339   // Alec: Why was this constructor around c necessary?
340   //sqrd = tree.squared_distance(V,F,q,i,(RowVector3S&)c);
341   sqrd = tree.squared_distance(V,F,q,i,c);
342   pseudonormal_test(V,F,FN,VN,EN,EMAP,q,i,c,s,n);
343 }
344 
345 template <
346   typename DerivedV,
347   typename DerivedE,
348   typename DerivedEN,
349   typename DerivedVN,
350   typename Derivedq,
351   typename Scalar,
352   typename Derivedc,
353   typename Derivedn>
signed_distance_pseudonormal(const AABB<DerivedV,2> & tree,const Eigen::MatrixBase<DerivedV> & V,const Eigen::MatrixBase<DerivedE> & E,const Eigen::MatrixBase<DerivedEN> & EN,const Eigen::MatrixBase<DerivedVN> & VN,const Eigen::MatrixBase<Derivedq> & q,Scalar & s,Scalar & sqrd,int & i,Eigen::PlainObjectBase<Derivedc> & c,Eigen::PlainObjectBase<Derivedn> & n)354 IGL_INLINE void igl::signed_distance_pseudonormal(
355   const AABB<DerivedV,2> & tree,
356   const Eigen::MatrixBase<DerivedV> & V,
357   const Eigen::MatrixBase<DerivedE> & E,
358   const Eigen::MatrixBase<DerivedEN> & EN,
359   const Eigen::MatrixBase<DerivedVN> & VN,
360   const Eigen::MatrixBase<Derivedq> & q,
361   Scalar & s,
362   Scalar & sqrd,
363   int & i,
364   Eigen::PlainObjectBase<Derivedc> & c,
365   Eigen::PlainObjectBase<Derivedn> & n)
366 {
367   using namespace Eigen;
368   using namespace std;
369   typedef Eigen::Matrix<typename DerivedV::Scalar,1,2> RowVector2S;
370   sqrd = tree.squared_distance(V,E,RowVector2S(q),i,(RowVector2S&)c);
371   pseudonormal_test(V,E,EN,VN,q,i,c,s,n);
372 }
373 
374 template <
375   typename DerivedV,
376   typename DerivedF,
377   typename Derivedq>
signed_distance_winding_number(const AABB<DerivedV,3> & tree,const Eigen::MatrixBase<DerivedV> & V,const Eigen::MatrixBase<DerivedF> & F,const igl::WindingNumberAABB<Derivedq,DerivedV,DerivedF> & hier,const Eigen::MatrixBase<Derivedq> & q)378 IGL_INLINE typename DerivedV::Scalar igl::signed_distance_winding_number(
379   const AABB<DerivedV,3> & tree,
380   const Eigen::MatrixBase<DerivedV> & V,
381   const Eigen::MatrixBase<DerivedF> & F,
382   const igl::WindingNumberAABB<Derivedq,DerivedV,DerivedF> & hier,
383   const Eigen::MatrixBase<Derivedq> & q)
384 {
385   typedef typename DerivedV::Scalar Scalar;
386   Scalar s,sqrd;
387   Eigen::Matrix<Scalar,1,3> c;
388   int i=-1;
389   signed_distance_winding_number(tree,V,F,hier,q,s,sqrd,i,c);
390   return s*sqrt(sqrd);
391 }
392 
393 
394 template <
395   typename DerivedV,
396   typename DerivedF,
397   typename Derivedq,
398   typename Scalar,
399   typename Derivedc>
signed_distance_winding_number(const AABB<DerivedV,3> & tree,const Eigen::MatrixBase<DerivedV> & V,const Eigen::MatrixBase<DerivedF> & F,const igl::WindingNumberAABB<Derivedq,DerivedV,DerivedF> & hier,const Eigen::MatrixBase<Derivedq> & q,Scalar & s,Scalar & sqrd,int & i,Eigen::PlainObjectBase<Derivedc> & c)400 IGL_INLINE void igl::signed_distance_winding_number(
401   const AABB<DerivedV,3> & tree,
402   const Eigen::MatrixBase<DerivedV> & V,
403   const Eigen::MatrixBase<DerivedF> & F,
404   const igl::WindingNumberAABB<Derivedq,DerivedV,DerivedF> & hier,
405   const Eigen::MatrixBase<Derivedq> & q,
406   Scalar & s,
407   Scalar & sqrd,
408   int & i,
409   Eigen::PlainObjectBase<Derivedc> & c)
410 {
411   using namespace Eigen;
412   using namespace std;
413   typedef Eigen::Matrix<typename DerivedV::Scalar,1,3> RowVector3S;
414   sqrd = tree.squared_distance(V,F,RowVector3S(q),i,(RowVector3S&)c);
415   const Scalar w = hier.winding_number(q.transpose());
416   s = 1.-2.*w;
417 }
418 
419 template <
420   typename DerivedV,
421   typename DerivedF,
422   typename Derivedq,
423   typename Scalar,
424   typename Derivedc>
signed_distance_winding_number(const AABB<DerivedV,2> & tree,const Eigen::MatrixBase<DerivedV> & V,const Eigen::MatrixBase<DerivedF> & F,const Eigen::MatrixBase<Derivedq> & q,Scalar & s,Scalar & sqrd,int & i,Eigen::PlainObjectBase<Derivedc> & c)425 IGL_INLINE void igl::signed_distance_winding_number(
426   const AABB<DerivedV,2> & tree,
427   const Eigen::MatrixBase<DerivedV> & V,
428   const Eigen::MatrixBase<DerivedF> & F,
429   const Eigen::MatrixBase<Derivedq> & q,
430   Scalar & s,
431   Scalar & sqrd,
432   int & i,
433   Eigen::PlainObjectBase<Derivedc> & c)
434 {
435   using namespace Eigen;
436   using namespace std;
437   typedef Eigen::Matrix<typename DerivedV::Scalar,1,2> RowVector2S;
438   sqrd = tree.squared_distance(V,F,RowVector2S(q),i,(RowVector2S&)c);
439   Scalar w;
440   // TODO: using .data() like this is very dangerous... This is assuming
441   // colmajor order
442   assert(!V.derived().IsRowMajor);
443   assert(!F.derived().IsRowMajor);
444   s = 1.-2.*winding_number(V,F,q);
445 }
446 
447 #ifdef IGL_STATIC_LIBRARY
448 // Explicit template instantiation
449 // generated by autoexplicit.sh
450 template void igl::signed_distance<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, igl::SignedDistanceType, Eigen::Matrix<double, -1, 3, 1, -1, 3>::Scalar, Eigen::Matrix<double, -1, 3, 1, -1, 3>::Scalar, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
451 // generated by autoexplicit.sh
452 template void igl::signed_distance<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<float, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<float, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, igl::SignedDistanceType, Eigen::Matrix<float, -1, 3, 0, -1, 3>::Scalar, Eigen::Matrix<float, -1, 3, 0, -1, 3>::Scalar, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
453 // generated by autoexplicit.sh
454 template void igl::signed_distance<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<float, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<float, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, igl::SignedDistanceType, Eigen::Matrix<float, -1, 3, 1, -1, 3>::Scalar, Eigen::Matrix<float, -1, 3, 1, -1, 3>::Scalar, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
455 template void igl::signed_distance<Eigen::Matrix<float, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<float, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<float, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, igl::SignedDistanceType, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&);
456 template void igl::signed_distance_pseudonormal<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, double, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3> >(igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, double&, double&, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&);
457 template void igl::signed_distance<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::SignedDistanceType, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&);
458 template Eigen::Matrix<double, -1, -1, 0, -1, -1>::Scalar igl::signed_distance_pseudonormal<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, 1, 3, 1, 1, 3> >(igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&);
459 template void igl::signed_distance_pseudonormal<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
460 template void igl::signed_distance<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::SignedDistanceType, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
461 template void igl::signed_distance_winding_number<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, double, Eigen::Matrix<double, 1, 3, 1, 1, 3> >(igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::WindingNumberAABB<Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, double&, double&, int&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&);
462 template Eigen::Matrix<double, -1, -1, 0, -1, -1>::Scalar igl::signed_distance_winding_number<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 3, 1, 0, 3, 1> >(igl::AABB<Eigen::Matrix<double, -1, -1, 0, -1, -1>, 3> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::WindingNumberAABB<Eigen::Matrix<double, 3, 1, 0, 3, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&);
463 #endif
464