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