00001
00002
00003
00004
00005
00006
00007
00008 #ifndef TRISPLINE_H_
00009 #define TRISPLINE_H_
00010
00011 #include <Eigen/Core>
00012
00013 #define BIG_V_ 0
00014
00015 namespace ParametricSurface {
00016
00017 template<size_t IndexA, size_t IndexB, size_t IndexC>
00018 class TriangleInst
00019 {
00020 protected:
00021 Eigen::Vector3f* pts_;
00022
00023 public:
00024 TriangleInst(Eigen::Vector3f* pts_):
00025 pts_(pts_)
00026 {}
00027
00028 inline Eigen::Vector3f tri(const Eigen::Vector3f &bc) {
00029 return ptA()*bc(0) + ptB()*bc(1) + ptC()*bc(2);
00030 }
00031
00032 inline Eigen::Vector3f normal() {
00033 Eigen::Vector3f r = (ptB()-ptA()).cross(ptC()-ptA());
00034 r.normalize();
00035 return r;
00036 }
00037
00038 inline Eigen::Vector3f &ptA() {return pts_[IndexA];}
00039 inline Eigen::Vector3f &ptB() {return pts_[IndexB];}
00040 inline Eigen::Vector3f &ptC() {return pts_[IndexC];}
00041
00042 };
00043
00044 template<int RowSize, int Index>
00045 class TriangleIndex {
00046 public:
00047 enum {a=(Index-1), b=(Index), c=(Index+RowSize)};
00048 };
00049
00050 template<int RowSize, int Index>
00051 class Triangle
00052 {
00053
00054 TriangleInst<TriangleIndex<RowSize,Index>::a, TriangleIndex<RowSize,Index>::b, TriangleIndex<RowSize,Index>::c > b;
00055 Triangle<RowSize, Index-1> tri_;
00056 Triangle<RowSize-1, Index-1> tri2_;
00057
00058 public:
00059
00060 Triangle(Eigen::Vector3f* pts_):
00061 b(pts_), tri_(pts_), tri2_(pts_+RowSize) {}
00062
00063 };
00064
00065 template<int RowSize>
00066 class Triangle<RowSize,0>
00067 {
00068 TriangleInst<TriangleIndex<RowSize,0>::a, TriangleIndex<RowSize,0>::b, TriangleIndex<RowSize,0>::c > b;
00069
00070 public:
00071
00072 Triangle(Eigen::Vector3f* pts_):
00073 b(pts_) {}
00074
00075 };
00076
00077
00078
00079 template<int X, int Y>
00080 class TriangleCoord {
00081 public:
00082 enum {x=X, y=Y, ind=y*(y+1)/2+x};
00083 };
00084
00085 template<typename Ca, typename Cb, typename Cc, int Round, int Depth>
00086 class TriangleC {
00087 TriangleC<
00088 Ca,
00089 TriangleCoord<Cb::x-1,Cb::y>,
00090 TriangleCoord<Cc::x,Cc::y+1>,
00091 0,
00092 Depth-1
00093 > tri_a_;
00094 TriangleC<
00095 TriangleCoord<Ca::x+1,Ca::y>,
00096 Cb,
00097 TriangleCoord<Cc::x+1,Cc::y+1>,
00098 0,
00099 Depth-1
00100 > tri_b_;
00101 TriangleC<
00102 TriangleCoord<Ca::x,Ca::y-1>,
00103 TriangleCoord<Cb::x-1,Cb::y-1>,
00104 Cc,
00105 0,
00106 Depth-1
00107 > tri_c_;
00108 public:
00109
00110 inline Eigen::Vector4f operator()(const Eigen::Vector3f &bc, const Eigen::Vector4f* pts_) const {
00111 return tri_a_(bc, pts_)*bc( (0+Round)%3 ) + tri_b_(bc, pts_)*bc( (1+Round)%3 ) + tri_c_(bc, pts_)*bc( (2+Round)%3 );
00112 }
00113
00114 inline Eigen::Vector3f normalAt(const Eigen::Vector3f &bc, const Eigen::Vector4f* pts_) const {
00115 const Eigen::Vector3f a = tri_a_(bc, pts_).head(3), b=tri_b_(bc, pts_).head(3), c=tri_c_(bc, pts_).head(3);
00116 return (b-a).cross(c-a);
00117 }
00118
00119 inline Eigen::Vector3f normalAt2(const Eigen::Vector3f &bc, const Eigen::Vector4f* pts_) const {
00120 const Eigen::Vector3f a = normalAt(bc, pts_).head(3), b=normalAt(bc, pts_).head(3), c=normalAt(bc, pts_).head(3);
00121 return (b-a).cross(c-a);
00122 }
00123
00124 inline Eigen::Matrix4f normalAtUV(const Eigen::Vector3f &bc, const Eigen::Vector4f* pts_, const Eigen::Vector2f *_uv) const {
00125 const Eigen::Vector3f a = tri_a_(bc, pts_).head(3), b=tri_b_(bc, pts_).head(3), c=tri_c_(bc, pts_).head(3);
00126 Eigen::Matrix4f M;
00127
00128 Eigen::Vector2f uv[3] =
00129 {
00130 _uv[0]*bc(0) + (_uv[1]+_uv[0])*0.5f*bc(1) + (_uv[2]+_uv[0])*0.5f*bc(2),
00131 _uv[1]*bc(1) + (_uv[0]+_uv[1])*0.5f*bc(0) + (_uv[2]+_uv[1])*0.5f*bc(2),
00132 _uv[2]*bc(2) + (_uv[1]+_uv[2])*0.5f*bc(1) + (_uv[0]+_uv[2])*0.5f*bc(0)
00133 };
00134
00135 std::cout<<"uv\n";
00136 for(int i=0; i<3; i++) std::cout<<uv[i]<<"\n";
00137
00138 std::cout<<"bc\n"<<bc<<"\n";
00139 std::cout<<"a\n"<<a<<"\n";
00140 std::cout<<"b\n"<<b<<"\n";
00141 std::cout<<"c\n"<<c<<"\n";
00142
00143 float f = (uv[2](1)-uv[1](1));
00144 std::cout<<"f1 "<<f<<"\n";
00145 if(std::abs(f)>0.00001f)
00146 M.col(1).head<3>() = (uv[2](1)-uv[0](1))/f*(b-c) + c - a;
00147 else
00148 M.col(1).head<3>() = b-c;
00149 f = (uv[2](0)-uv[1](0));
00150 if(std::abs(f)>0.00001f)
00151 M.col(2).head<3>() = (uv[2](0)-uv[0](0))/f*(b-c) + c - a;
00152 else
00153 M.col(2).head<3>() = b-c;
00154
00155 {
00156 const Eigen::Vector3f a = pts_[Ca::ind].head(3), b=pts_[Cb::ind].head(3), c=pts_[Cc::ind].head(3);
00157 std::cout<<"a\n"<<a<<"\n";
00158 std::cout<<"b\n"<<b<<"\n";
00159 std::cout<<"c\n"<<c<<"\n";
00160 M.col(3).head<3>() = (b-a).cross(c-a);
00161 M.col(3).head<3>().normalize();
00162 }
00163 M.col(1)(3) = M.col(1).head<3>().dot(M.col(3).head<3>());
00164 M.col(2)(3) = M.col(2).head<3>().dot(M.col(3).head<3>());
00165 M.col(3).head<3>() = (b-a).cross(c-a);
00166
00167 return M;
00168 }
00169
00170 inline size_t getIndA() const {return Ca::ind;}
00171 inline size_t getIndB() const {return Cb::ind;}
00172 inline size_t getIndC() const {return Cc::ind;}
00173
00174 void print(const Eigen::Vector4f* pts_) const {
00175 tri_a_.print(pts_);
00176 tri_b_.print(pts_);
00177 tri_c_.print(pts_);
00178 }
00179
00180 };
00181
00182 template<typename Ca, typename Cb, typename Cc, int Round>
00183 class TriangleC<Ca,Cb,Cc,Round,0> {
00184 public:
00185
00186 inline Eigen::Vector4f operator()(const Eigen::Vector3f &bc, const Eigen::Vector4f* pts_) const {
00187 return pts_[Ca::ind]*bc( (0+Round)%3 ) + pts_[Cb::ind]*bc( (1+Round)%3 ) + pts_[Cc::ind]*bc( (2+Round)%3 );
00188 }
00189
00190 inline Eigen::Vector4f normalAt(const Eigen::Vector3f &bc, const Eigen::Vector4f* pts_) const {
00191 const Eigen::Vector4f a = pts_[Ca::ind], b=pts_[Cb::ind], c=pts_[Cc::ind];
00192 return (b-a).cross(c-a);
00193 }
00194
00195
00196 void print(const Eigen::Vector4f* pts_) const {
00197 #if 0
00198 printf("x y (%d, %d)\n", Ca::x, Ca::y);
00199 printf("x y (%d, %d)\n", Cb::x, Cb::y);
00200 printf("x y (%d, %d)\n", Cc::x, Cc::y);
00201 #endif
00202 printf("adding (%d, %d, %d):\n", Ca::ind, Cb::ind, Cc::ind);
00203 std::cout<<" "<<pts_[Ca::ind]<<"\n";
00204 std::cout<<" "<<pts_[Cb::ind]<<"\n";
00205 std::cout<<" "<<pts_[Cc::ind]<<"\n";
00206 }
00207 };
00208
00209
00210 class _Line {
00211 public:
00212 Eigen::Vector3f u, o;
00213
00214 _Line() {}
00215 _Line(const Eigen::Vector3f &u, const Eigen::Vector3f &o):u(u),o(o) {}
00216
00217 inline Eigen::Vector3f at(const float f) const {
00218 return f*u+o;
00219 }
00220
00221 inline Eigen::Vector3f intersection(const Eigen::Vector3f &n, const Eigen::Vector3f &o2, const Eigen::Vector3f &ip) {
00222 const float d = u.dot(n);
00223 #if DEBUG_OUT_
00224 std::cout<<"n\n"<<n<<"\n";
00225 std::cout<<"u\n"<<u<<"\n";
00226 #endif
00227 if( std::abs(d)< 0.0001f )
00228 return ip;
00229 const float f = (o2).dot(n)/(2*d);
00230 #if DEBUG_OUT_
00231 std::cout<<"f "<<f<<" "<<u.dot(n)<<"\n";
00232 #endif
00233 return at( f );
00234 }
00235 };
00236
00237 class _Plane {
00238 public:
00239 Eigen::Vector3f n, o;
00240
00241 _Plane(const Eigen::Vector3f &n, const Eigen::Vector3f &o):n(n),o(o) {}
00242
00243 inline Eigen::Vector3f intersection(const _Line &l, float &x) {
00244 #if DEBUG_OUT_
00245 std::cout<<"np\n"<<n<<"\n";
00246 #endif
00247 const float d=l.u.dot(n);
00248 if( std::abs(d)< 0.0001f )
00249 return 0.5f*(o+l.o);
00250 return l.at( x=(o-l.o).dot(n)/d );
00251 }
00252
00253 inline _Line intersection(const _Plane &p) {
00254 _Line lr( n.cross( p.n ), Eigen::Vector3f::Zero() );
00255 #if 0
00256 const float dot = n.dot( p.n );
00257 const float h2 = p.n.dot( p.o-o );
00258 const float dot2 = (1-dot*dot);
00259 if(dot2) {
00260 lr.o =
00261 ( (-h2*dot)*n + (h2)*p.n )/dot2 + o;
00262 }
00263 else
00264 ROS_ASSERT(0);
00265 #else
00266
00267 if(lr.u.squaredNorm()<0.0001f) {
00268 lr.o = o;
00269 lr.u = p.o-o;
00270 return lr;
00271 }
00272
00273
00274 const float d1 = -n.dot(o);
00275 const float d2 = -p.n.dot(p.o);
00276
00277 int m = 0;
00278 if( std::abs(lr.u(1))>std::abs(lr.u(m)) ) m=1;
00279 if( std::abs(lr.u(2))>std::abs(lr.u(m)) ) m=2;
00280
00281 switch (m) {
00282 case 0:
00283 lr.o(1) = (d2*n(2) - d1*p.n(2))/ lr.u(0);
00284 lr.o(2) = (d1*p.n(1) - d2*n(1))/ lr.u(0);
00285 break;
00286 case 1:
00287 lr.o(0) = (d1*p.n(2) - d2*n(2))/ lr.u(1);
00288 lr.o(2) = (d2*n(0) - d1*p.n(0))/ lr.u(1);
00289 break;
00290 case 2:
00291 lr.o(0) = (d2*n(1) - d1*p.n(1))/ lr.u(2);
00292 lr.o(1) = (d1*p.n(0) - d2*n(0))/ lr.u(2);
00293 break;
00294 }
00295 #endif
00296
00297 #if DEBUG_OUT_
00298 std::cout<<"PLANE INTERSECTION\n";
00299 std::cout<<"o\n"<<lr.o<<"\n";
00300 std::cout<<"u\n"<<lr.u<<"\n";
00301 std::cout<<"n1\n"<<n<<"\n";
00302 std::cout<<"n2\n"<<p.n<<"\n";
00303 #endif
00304
00305 return lr;
00306 }
00307 };
00308
00309 class SplineFade
00310 {
00311 public:
00312 Eigen::Vector4f pts_[2];
00313
00314 inline Eigen::Vector3f delta() const {return (pts_[0]-pts_[1]).head<3>();}
00315
00316 void test_setup(const Eigen::Vector3f &a, const Eigen::Vector3f &b,
00317 const Eigen::Vector3f &na, const Eigen::Vector3f &nb,
00318 const Eigen::Vector3f &na2, const Eigen::Vector3f &nb2,
00319 _Line &l1, _Line &l2)
00320 {
00321 _Plane p1(na,a);
00322 _Plane p2(nb,b);
00323
00324 _Plane p1x(na2,0.5f*(a+b));
00325 _Plane p2x(nb2,0.5f*(a+b));
00326
00327 l1 = p1x.intersection(p1);
00328 l2 = p2x.intersection(p2);
00329
00330 l1 = _Line(na2,0.5f*(a+b));
00331 l2 = _Line(nb2,0.5f*(a+b));
00332 }
00333
00334 void setup(const Eigen::Vector3f &a, const Eigen::Vector3f &b,
00335 const Eigen::Vector3f &na, const Eigen::Vector3f &nb,
00336 const Eigen::Vector3f &na2, const Eigen::Vector3f &nb2,
00337 const float max_curvature)
00338 {
00339 _Plane p1(na,a);
00340 _Plane p2(nb,b);
00341
00342 #if 0
00343 Eigen::Vector3f i1 = p1.intersection( _Line(na,b) );
00344 Eigen::Vector3f i2 = p2.intersection( _Line(nb,a) );
00345 #endif
00346
00347 #if DEBUG_OUT_
00348
00349 std::cout<<"a\n"<<a<<"\n";
00350
00351 std::cout<<"b\n"<<b<<"\n";
00352 #endif
00353
00354 #if 0
00355 pts_[0] = _Line( (i1-a), a ).intersection( na2, b-a, i1 );
00356 pts_[1] = _Line( (i2-b), b ).intersection( nb2, a-b, i2 );
00357 #elif 0
00358 _Plane p1x(na.cross(a-b),a);
00359 _Plane p2x(nb.cross(b-a),b);
00360
00361 pts_[0] = p1x.intersection(p1).intersection( na2, b-a, i1 );
00362 pts_[1] = p2x.intersection(p2).intersection( nb2, a-b, i2 );
00363 #else
00364
00365 #if 0
00366 _Plane p1x(na2,0.5f*(a+b));
00367 _Plane p2x(nb2,0.5f*(a+b));
00368
00369 _Line l1 = p1x.intersection(p1);
00370 _Line l2 = p2x.intersection(p2);
00371
00372 Eigen::Matrix3f M;
00373
00374 #if 0
00375 M.col(0) = -l1.u;
00376 M.col(1) = l2.u;
00377 M.col(2) = l1.u.cross(l2.u);
00378
00379 #if DEBUG_OUT_
00380 std::cout<<"M\n"<<M<<"\n";
00381 std::cout<<"r\n"<<(l1.o-l2.o)<<"\n";
00382 std::cout<<"M-1\n"<<M.inverse()<<"\n";
00383 #endif
00384
00385 Eigen::Vector3f v=M.inverse()*(l1.o-l2.o);
00386
00387 #if DEBUG_OUT_
00388 std::cout<<"v\n"<<v<<"\n";
00389 #endif
00390
00391 if(pcl_isfinite(v.sum())) {
00392 pts_[0] = l1.at(v(0));
00393 pts_[1] = l2.at(v(1));
00394 }
00395 else {
00396 pts_[0] = l1.o;
00397 pts_[1] = l2.o;
00398 }
00399 #else
00400 M.col(0) = -l1.u;
00401 M.col(1) = a-b;
00402 M.col(2) = l1.u.cross(M.col(1));
00403
00404 Eigen::Vector3f v=M.inverse()*(l1.o-b);
00405 std::cout<<"vA\n"<<v<<"\n";
00406 std::cout<<"u\n"<<l1.u<<"\n";
00407 std::cout<<"o\n"<<l1.o<<"\n";
00408
00409 if(pcl_isfinite(v(0)) && std::abs(v(0))<100000.f) {
00410 pts_[0] = l1.at(v(0));
00411 }
00412 else {
00413 pts_[0] = (a+b)*0.5f;
00414 }
00415
00416 M.col(0) = -l2.u;
00417 M.col(1) = a-b;
00418 M.col(2) = l2.u.cross(M.col(1));
00419
00420 v=M.inverse()*(l2.o-b);
00421 std::cout<<"vB\n"<<v<<"\n";
00422 std::cout<<"u\n"<<l2.u<<"\n";
00423 std::cout<<"o\n"<<l2.o<<"\n";
00424
00425 if(pcl_isfinite(v(0)) && std::abs(v(0))<10000.f) {
00426 pts_[1] = l2.at(v(0));
00427 }
00428 else {
00429 pts_[1] = (a+b)*0.5f;
00430 }
00431 #endif
00432
00433 #else
00434
00435 float x, l;
00436 pts_[0].head<3>() = p1.intersection(_Line(na2,0.5f*(a+b)),x);
00437 l = 2*x*x*na2.squaredNorm() / (a-b).squaredNorm();
00438 if(l>max_curvature*max_curvature){
00439 pts_[0].head<3>() = (pts_[0].head<3>()-a)*max_curvature/std::sqrt(l) + a;
00440
00441 }
00442 pts_[1].head<3>() = p2.intersection(_Line(nb2,0.5f*(a+b)),x);
00443 l = 2*x*x*nb2.squaredNorm() / (a-b).squaredNorm();
00444 if(l>max_curvature*max_curvature) {
00445 pts_[1].head<3>() = (pts_[1].head<3>()-b)*max_curvature/std::sqrt(l) + b;
00446
00447 }
00448
00449
00450
00451
00452
00453
00454
00455
00456 ROS_ASSERT(pcl_isfinite(pts_[0].head<3>().sum()));
00457 ROS_ASSERT(pcl_isfinite(pts_[1].head<3>().sum()));
00458 #endif
00459
00460 #endif
00461
00462 #if DEBUG_OUT_
00463 print();
00464 #endif
00465 }
00466
00467 void transform(const Eigen::Matrix3f &rot, const Eigen::Vector3f &tr) {
00468 pts_[0].head<3>() = rot*pts_[0].head<3>()+tr;
00469 pts_[1].head<3>() = rot*pts_[1].head<3>()+tr;
00470 }
00471
00472 inline Eigen::Vector4f operator()(const float a, const float b) {
00473 float f = a/(a+b);
00474 if(!pcl_isfinite(f)||f<0) f=0.f;
00475 if(f>1) f=1;
00476 return f*pts_[0] + (1.f-f)*pts_[1];
00477 }
00478
00479 void print() const {
00480 std::cout<<"SF1\n"<<pts_[0]<<"\n";
00481 std::cout<<"SF2\n"<<pts_[1]<<"\n";
00482 }
00483
00484 };
00485
00486 template<int Order>
00487 class TriSpline
00488 {
00489 protected:
00490 enum {PT_SIZE=(Order+1)*(Order+2)/2, ORDER=Order};
00491
00492 Eigen::Vector4f pts_[PT_SIZE];
00493
00494
00495
00496 TriangleC<
00497 TriangleCoord<0,Order>,
00498 TriangleCoord<Order,Order>,
00499 TriangleCoord<0,0>,
00500 0,
00501 Order-1
00502 > tri_;
00503
00504
00505
00506
00507
00508 inline static size_t indAB(const size_t x, const size_t y) {
00509 return y*(y+1)/2+x;
00510 }
00511
00512 public:
00513 TriSpline()
00514 {
00515 for(int i=0; i<PT_SIZE; i++)
00516 pts_[i].fill(1);
00517 }
00518
00519 virtual ~TriSpline() {}
00520
00521 virtual Eigen::Vector3f operator()(const Eigen::Vector3f &bc) const {
00522 return tri_(bc, pts_).head(3);
00523 }
00524
00525 virtual Eigen::Vector3f normalAt(const Eigen::Vector3f &bc) const {
00526 return tri_.normalAt(bc, pts_).head(3);
00527 }
00528
00529 virtual Eigen::Vector3f normalAt2(const Eigen::Vector3f &bc) const {
00530 return tri_.normalAt2(bc, pts_).head(3);
00531 }
00532
00533 virtual void transform(const Eigen::Matrix3f &rot, const Eigen::Vector3f &tr) {
00534 for(int i=0; i<PT_SIZE; i++)
00535 pts_[i].head(3) = rot*pts_[i].head(3)+tr;
00536 }
00537
00538 };
00539
00540 class TriSpline2_Fade : public TriSpline<2> {
00541 Eigen::Vector3f n_[3], n2_[3];
00542 Eigen::Vector2f uv_[3];
00543 SplineFade sf_[3];
00544 Eigen::Matrix2f _T_;
00545
00546 Eigen::Vector3f m_, weight_;
00547
00548 void setup(const float max_curvature) {
00549 size_t ind[3] = { indAB(0,ORDER), indAB(ORDER,ORDER), indAB(0,0) };
00550
00551 for(int i=0; i<3; i++) {
00552 sf_[i].setup( pts_[ind[i]].head<3>(), pts_[ind[(i+1)%3]].head<3>(),
00553 n_[i], n_[(i+1)%3],
00554 n2_[i], n2_[(i+1)%3], max_curvature);
00555 m_ += pts_[ind[i]].head<3>();
00556 }
00557
00558 m_/=3;
00559 }
00560
00561 public:
00562
00563 void test_setup(_Line *l) {
00564 size_t ind[3] = { indAB(0,ORDER), indAB(ORDER,ORDER), indAB(0,0) };
00565
00566 for(int i=0; i<3; i++) {
00567 sf_[i].test_setup( pts_[ind[i]].head<3>(), pts_[ind[(i+1)%3]].head<3>(),
00568 n_[i], n_[(i+1)%3],
00569 n2_[i], n2_[(i+1)%3],
00570 l[i*2+0],l[i*2+1]);
00571 }
00572 }
00573
00574 inline Eigen::Vector3f getEdge(const int i) {
00575 static const size_t ind[3] = { indAB(0,ORDER), indAB(ORDER,ORDER), indAB(0,0) };
00576 return pts_[ind[i]].head<3>();
00577 }
00578
00579 inline SplineFade getFade(const int i) {return sf_[i];}
00580 inline Eigen::Vector3f getNormal(const int i) {return n_[i];}
00581 inline Eigen::Vector2f getUV(const int i) {return uv_[i];}
00582 inline Eigen::Vector3f getNormal2(const int i) {return n2_[i];}
00583
00584 TriSpline2_Fade(const Eigen::Vector3f &a, const Eigen::Vector3f &b, const Eigen::Vector3f &c,
00585 const Eigen::Vector3f &na, const Eigen::Vector3f &nb, const Eigen::Vector3f &nc,
00586 const Eigen::Vector3f &na2, const Eigen::Vector3f &nb2, const Eigen::Vector3f &nc2,
00587 const Eigen::Vector2f &uva, const Eigen::Vector2f &uvb, const Eigen::Vector2f &uvc,
00588 const Eigen::Vector3f &w, const float max_curvature = 10000.f
00589 ): weight_(w)
00590 {
00591 pts_[indAB(0,ORDER)].head<3>() = a;
00592 pts_[indAB(ORDER,ORDER)].head<3>() = b;
00593 pts_[indAB(0,0)].head<3>() = c;
00594
00595 n_[0] = na;
00596 n_[1] = nb;
00597 n_[2] = nc;
00598
00599 n2_[0] = na2;
00600 n2_[1] = nb2;
00601 n2_[2] = nc2;
00602
00603 uv_[0] = uva;
00604 uv_[1] = uvb;
00605 uv_[2] = uvc;
00606
00607
00608 _T_.col(0) = uva-uvc;
00609 _T_.col(1) = uvb-uvc;
00610 _T_ = _T_.inverse().eval();
00611
00612 if(!pcl_isfinite(_T_.sum())) {
00613 ROS_WARN("_T_ is invalid");
00614 _T_.fill(0);
00615 _T_(0,0)=_T_(1,1)=1;
00616 }
00617
00618 setup(max_curvature);
00619 }
00620
00621 inline Eigen::Vector3f getWeight() const {return weight_;}
00622
00623 virtual Eigen::Vector3f operator()(const Eigen::Vector3f &bc) {
00624 pts_[indAB(ORDER/2,ORDER)] = sf_[0](bc(0),bc(1));
00625 pts_[indAB(ORDER/2,ORDER/2)] = sf_[1](bc(1),bc(2));
00626 pts_[indAB(0,ORDER/2)] = sf_[2](bc(2),bc(0));
00627 #if DEBUG_OUT_
00628 tri_.print(pts_);
00629 #endif
00630 return tri_(bc, pts_).head(3);
00631 }
00632
00633 virtual Eigen::Vector3f normalAt(const Eigen::Vector3f &bc) {
00634 pts_[indAB(ORDER/2,ORDER)] = sf_[0](bc(0),bc(1));
00635 pts_[indAB(ORDER/2,ORDER/2)] = sf_[1](bc(1),bc(2));
00636 pts_[indAB(0,ORDER/2)] = sf_[2](bc(2),bc(0));
00637 return tri_.normalAt(bc, pts_);
00638 }
00639
00640 virtual Eigen::Vector3f normalAt2(const Eigen::Vector3f &bc) {
00641 pts_[indAB(ORDER/2,ORDER)] = sf_[0](bc(0),bc(1));
00642 pts_[indAB(ORDER/2,ORDER/2)] = sf_[1](bc(1),bc(2));
00643 pts_[indAB(0,ORDER/2)] = sf_[2](bc(2),bc(0));
00644 return tri_.normalAt2(bc, pts_);
00645 }
00646
00647 virtual Eigen::Matrix4f normalAtUV(const Eigen::Vector3f &bc) {
00648 pts_[indAB(ORDER/2,ORDER)] = sf_[0](bc(0),bc(1));
00649 pts_[indAB(ORDER/2,ORDER/2)] = sf_[1](bc(1),bc(2));
00650 pts_[indAB(0,ORDER/2)] = sf_[2](bc(2),bc(0));
00651 return tri_.normalAtUV(bc, pts_, uv_);
00652 }
00653
00654 Eigen::Matrix3f delta() const {
00655 Eigen::Matrix3f M;
00656 for(int i=0; i<3; i++)
00657 M.col(i) = sf_[i].delta();
00658 return M;
00659 }
00660
00661 Eigen::Vector3f operator()(const Eigen::Vector2f &pt) {
00662
00663 Eigen::Vector3f br;
00664 br.head<2>() = _T_*(pt-uv_[2]);
00665 br(2) = 1-br(0)-br(1);
00666
00667
00668 Eigen::Vector3f v=(*this)(br);
00669 #if BIG_V_
00670 if(v.squaredNorm()>70 || !pcl_isfinite(v.sum())) {
00671 std::cout<<"BIG v\n"<<v<<"\n";
00672 std::cout<<"uv\n"<<pt<<"\n";
00673 std::cout<<"bc\n"<<br<<"\n";
00674 std::cout<<"T\n"<<_T_<<"\n";
00675 size_t ind[3] = { indAB(0,ORDER), indAB(ORDER,ORDER), indAB(0,0) };
00676
00677 for(int i=0; i<3; i++) {
00678 std::cout<<"cp\n"<<pts_[ind[i]]<<"\n";
00679 std::cout<<"uv\n"<<uv_[i]<<"\n";
00680 }
00681 }
00682 #endif
00683 return v;
00684 }
00685
00686 Eigen::Vector3f normalAt(const Eigen::Vector2f &pt) {
00687
00688 Eigen::Matrix<float,3,2> M = normalBC( _T_*(pt-uv_[2]) );
00689
00690 return M.col(0).cross( M.col(1) );
00691 }
00692
00693 Eigen::Vector3f UV2BC(const Eigen::Vector2f &pt) const {
00694
00695 Eigen::Vector3f br;
00696 br.head<2>() = _T_*(pt-uv_[2]);
00697 br(2) = 1-br(0)-br(1);
00698
00699 return br;
00700 }
00701
00702 Eigen::Vector3f normalAt2(const Eigen::Vector2f &pt) {
00703 Eigen::Vector2f v = _T_*(pt-uv_[2]);
00704 Eigen::Matrix<float,3,2> M1 = normalBC( v );
00705 Eigen::Matrix<float,3,2> M2 = normal2BC( v );
00706
00707 M1.col(0) = -( M2.col(0).cross(M1.col(1)) ).cross( M2.col(1).cross(M1.col(0)) );
00708
00709
00710
00711 if(!pcl_isfinite(M1.col(0).sum())) {
00712 std::cout<<"INF v\n"<<M1<<"\n";
00713 std::cout<<"M1\n"<<normalBC( v )<<"\n";
00714 std::cout<<"M2\n"<<normal2BC( v )<<"\n";
00715 std::cout<<"uv\n"<<pt<<"\n";
00716 std::cout<<"bc\n"<<v<<"\n";
00717 std::cout<<"T\n"<<_T_<<"\n";
00718 size_t ind[3] = { indAB(0,ORDER), indAB(ORDER,ORDER), indAB(0,0) };
00719
00720 for(int i=0; i<3; i++) {
00721 std::cout<<"cp\n"<<pts_[ind[i]]<<"\n";
00722 std::cout<<"uv\n"<<uv_[i]<<"\n";
00723 }
00724 }
00725
00726 if(!pcl_isfinite(M1.col(0).sum()))
00727 return Eigen::Vector3f::Zero();
00728
00729 return M1.col(0);
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751 }
00752
00753 virtual void transform(const Eigen::Matrix3f &rot, const Eigen::Vector3f &tr) {
00754 TriSpline<2>::transform(rot, tr);
00755 for(int i=0; i<3; i++) {
00756
00757 n_[i] = rot*n_[i];
00758 n2_[i] = rot*n2_[i];
00759 sf_[i].transform(rot,tr);
00760 }
00761
00762 m_ = rot*m_ + tr;
00763 }
00764
00765 inline Eigen::Vector3f getMid() const {return m_;}
00766
00767 inline Eigen::Vector2f getMidUV() const {return (uv_[0]+uv_[1]+uv_[2])/3;}
00768
00769 Eigen::Matrix4f normalAtUV(const Eigen::Vector2f &pt) {
00770 for(int i=0; i<3; i++)
00771 sf_[i].print();
00772
00773
00774 Eigen::Vector3f br;
00775
00776 br.head<2>() = _T_*(pt-uv_[2]);
00777 br(2) = 1-br(0)-br(1);
00778
00779 Eigen::Matrix4f M = normalAtUV(br);
00780 M.col(0).head<3>() = (*this)(br);
00781
00782
00783 return M;
00784 }
00785
00786 inline float POW2(const float f) {return f*f;}
00787 inline float POW3(const float f) {return f*f*f;}
00788
00789 inline Eigen::Matrix<float,3,2> normal(const Eigen::Vector2f &uv) {
00790 Eigen::Matrix3f M;
00791 M.topLeftCorner<3,2>() = normalBC(_T_*(uv-uv_[2]));
00792 M.col(2) = M.col(0).cross(M.col(1));
00793
00794 Eigen::Matrix<float,3,2> R;
00795 Eigen::Vector3f v;
00796 v(2)=0;
00797
00798 v.head<2>() = _T_.col(0);
00799 R.col(0) = M*v;
00800
00801 v.head<2>() = _T_.col(1);
00802 R.col(1) = M*v;
00803
00804 if(!pcl_isfinite(R.sum())) {
00805 std::cout<<"INF v\n"<<R<<"\n";
00806 std::cout<<"uv\n"<<uv<<"\n";
00807 std::cout<<"bc\n"<<(_T_*(uv-uv_[2]))<<"\n";
00808 std::cout<<"T\n"<<_T_<<"\n";
00809 size_t ind[3] = { indAB(0,ORDER), indAB(ORDER,ORDER), indAB(0,0) };
00810
00811 for(int i=0; i<3; i++) {
00812 std::cout<<"cp\n"<<pts_[ind[i]]<<"\n";
00813 std::cout<<"uv\n"<<uv_[i]<<"\n";
00814 }
00815 }
00816
00817 return R;
00818 }
00819
00820 inline Eigen::Matrix<float,3,2> normalBC(const Eigen::Vector2f &bc) {
00821 Eigen::Matrix<float,3,2> M;
00822 static const size_t ind[3] = { indAB(0,ORDER), indAB(ORDER,ORDER), indAB(0,0) };
00823
00824 #if 0
00825 if(std::abs(bc(0)-1)<0.0001f) {
00826
00827
00828
00829 M.col(0) = -(-bc(1)-bc(0)+1)*pts_[ind[2]]+(-bc(1)-bc(0)+1)*(-pts_[ind[2]]+bc(0)*(sf_[2].pts_[1]/(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))+(bc(0)*sf_[2].pts_[1])/(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1)))+bc(0)*((-bc(1)-bc(0)+1)*(sf_[2].pts_[1]/(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))-(bc(0)*sf_[2].pts_[1])/(1-bc(1))-((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1))+bc(1)*(-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+sf_[0].pts_[0]/(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))+pts_[ind[0]])+(-bc(1)-bc(0)+1)*((bc(0)*sf_[2].pts_[1])/(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1)))-bc(0)*((bc(0)*sf_[2].pts_[1])/(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1)))+bc(1)*(-(sf_[1].pts_[1]+sf_[1].pts_[0])/2+bc(0)*(-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+sf_[0].pts_[0]/(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))+(bc(1)*sf_[0].pts_[1])/(bc(1)+bc(0))+(bc(0)*sf_[0].pts_[0])/(bc(1)+bc(0)))-(bc(1)*(sf_[1].pts_[1]+sf_[1].pts_[0]))/2+bc(1)*((bc(1)*sf_[0].pts_[1])/(bc(1)+bc(0))+(bc(0)*sf_[0].pts_[0])/(bc(1)+bc(0)))+bc(0)*pts_[ind[0]];
00830 M.col(1) = -(-bc(1)-bc(0)+1)*pts_[ind[2]]+(-bc(1)-bc(0)+1)*(-pts_[ind[2]]+bc(0)*((bc(0)*sf_[2].pts_[1])/POW2(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW2(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))+(sf_[1].pts_[1]+sf_[1].pts_[0])/2)+bc(1)*(pts_[ind[1]]-(sf_[1].pts_[1]+sf_[1].pts_[0])/2+bc(0)*(sf_[0].pts_[1]/(bc(1)+bc(0))-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0))))+bc(1)*pts_[ind[1]]+bc(0)*((-bc(1)-bc(0)+1)*((bc(0)*sf_[2].pts_[1])/POW2(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW2(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))-(bc(0)*sf_[2].pts_[1])/(1-bc(1))-((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1))+bc(1)*(sf_[0].pts_[1]/(bc(1)+bc(0))-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))+(bc(1)*sf_[0].pts_[1])/(bc(1)+bc(0))+(bc(0)*sf_[0].pts_[0])/(bc(1)+bc(0)))-bc(0)*((bc(0)*sf_[2].pts_[1])/(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1)))-(bc(1)*(sf_[1].pts_[1]+sf_[1].pts_[0]))/2+((-bc(1)-bc(0)+1)*(sf_[1].pts_[1]+sf_[1].pts_[0]))/2+bc(0)*((bc(1)*sf_[0].pts_[1])/(bc(1)+bc(0))+(bc(0)*sf_[0].pts_[0])/(bc(1)+bc(0)));
00831
00832
00833 }
00834 else if(std::abs(bc(1)-1)<0.0001f) {
00835
00836
00837
00838 M.col(0) = -(-bc(1)-bc(0)+1)*pts_[ind[2]]+(-bc(1)-bc(0)+1)*(-pts_[ind[2]]+(sf_[2].pts_[1]+sf_[2].pts_[0])/2+bc(1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW2(1-bc(0))-sf_[1].pts_[1]/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/POW2(1-bc(0))))+bc(0)*(-(sf_[2].pts_[1]+sf_[2].pts_[0])/2+bc(1)*(-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+sf_[0].pts_[0]/(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))+pts_[ind[0]])+((-bc(1)-bc(0)+1)*(sf_[2].pts_[1]+sf_[2].pts_[0]))/2-(bc(0)*(sf_[2].pts_[1]+sf_[2].pts_[0]))/2+bc(1)*((-bc(1)-bc(0)+1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW2(1-bc(0))-sf_[1].pts_[1]/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/POW2(1-bc(0)))-((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))-(bc(1)*sf_[1].pts_[0])/(1-bc(0))+bc(0)*(-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+sf_[0].pts_[0]/(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))+(bc(1)*sf_[0].pts_[1])/(bc(1)+bc(0))+(bc(0)*sf_[0].pts_[0])/(bc(1)+bc(0)))-bc(1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/(1-bc(0)))+bc(1)*((bc(1)*sf_[0].pts_[1])/(bc(1)+bc(0))+(bc(0)*sf_[0].pts_[0])/(bc(1)+bc(0)))+bc(0)*pts_[ind[0]];
00839 M.col(1) = -(-bc(1)-bc(0)+1)*pts_[ind[2]]+(-bc(1)-bc(0)+1)*(-pts_[ind[2]]+bc(1)*(sf_[1].pts_[0]/(1-bc(0))-sf_[1].pts_[1]/(1-bc(0)))+((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/(1-bc(0)))+bc(1)*(pts_[ind[1]]+(-bc(1)-bc(0)+1)*(sf_[1].pts_[0]/(1-bc(0))-sf_[1].pts_[1]/(1-bc(0)))-((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))-(bc(1)*sf_[1].pts_[0])/(1-bc(0))+bc(0)*(sf_[0].pts_[1]/(bc(1)+bc(0))-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0))))+bc(1)*pts_[ind[1]]+bc(0)*(-(sf_[2].pts_[1]+sf_[2].pts_[0])/2+bc(1)*(sf_[0].pts_[1]/(bc(1)+bc(0))-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))+(bc(1)*sf_[0].pts_[1])/(bc(1)+bc(0))+(bc(0)*sf_[0].pts_[0])/(bc(1)+bc(0)))-(bc(0)*(sf_[2].pts_[1]+sf_[2].pts_[0]))/2-bc(1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/(1-bc(0)))+(-bc(1)-bc(0)+1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/(1-bc(0)))+bc(0)*((bc(1)*sf_[0].pts_[1])/(bc(1)+bc(0))+(bc(0)*sf_[0].pts_[0])/(bc(1)+bc(0)));
00840
00841
00842 }
00843 else if( std::abs(bc(0)+bc(1))<0.0001f) {
00844
00845
00846
00847 M.col(0) = -(-bc(1)-bc(0)+1)*pts_[ind[2]]+(-bc(1)-bc(0)+1)*(-pts_[ind[2]]+bc(0)*(sf_[2].pts_[1]/(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))+(bc(0)*sf_[2].pts_[1])/(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1))+bc(1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW2(1-bc(0))-sf_[1].pts_[1]/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/POW2(1-bc(0))))+bc(0)*((-bc(1)-bc(0)+1)*(sf_[2].pts_[1]/(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))-(bc(0)*sf_[2].pts_[1])/(1-bc(1))-((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1))+pts_[ind[0]])+(-bc(1)-bc(0)+1)*((bc(0)*sf_[2].pts_[1])/(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1)))-bc(0)*((bc(0)*sf_[2].pts_[1])/(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1)))+bc(1)*((-bc(1)-bc(0)+1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW2(1-bc(0))-sf_[1].pts_[1]/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/POW2(1-bc(0)))-((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))-(bc(1)*sf_[1].pts_[0])/(1-bc(0))+(sf_[0].pts_[1]+sf_[0].pts_[0])/2)-bc(1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/(1-bc(0)))+(bc(1)*(sf_[0].pts_[1]+sf_[0].pts_[0]))/2+bc(0)*pts_[ind[0]];
00848 M.col(1) = -(-bc(1)-bc(0)+1)*pts_[ind[2]]+(-bc(1)-bc(0)+1)*(-pts_[ind[2]]+bc(0)*((bc(0)*sf_[2].pts_[1])/POW2(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW2(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))+bc(1)*(sf_[1].pts_[0]/(1-bc(0))-sf_[1].pts_[1]/(1-bc(0)))+((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/(1-bc(0)))+bc(1)*(pts_[ind[1]]+(-bc(1)-bc(0)+1)*(sf_[1].pts_[0]/(1-bc(0))-sf_[1].pts_[1]/(1-bc(0)))-((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))-(bc(1)*sf_[1].pts_[0])/(1-bc(0)))+bc(1)*pts_[ind[1]]+bc(0)*((-bc(1)-bc(0)+1)*((bc(0)*sf_[2].pts_[1])/POW2(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW2(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))-(bc(0)*sf_[2].pts_[1])/(1-bc(1))-((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1))+(sf_[0].pts_[1]+sf_[0].pts_[0])/2)-bc(0)*((bc(0)*sf_[2].pts_[1])/(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1)))-bc(1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/(1-bc(0)))+(-bc(1)-bc(0)+1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/(1-bc(0)))+(bc(0)*(sf_[0].pts_[1]+sf_[0].pts_[0]))/2;
00849
00850
00851 }
00852 else {
00853 M.col(0) = -(-bc(1)-bc(0)+1)*pts_[ind[2]]+(-bc(1)-bc(0)+1)*(-pts_[ind[2]]+bc(0)*(sf_[2].pts_[1]/(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))+(bc(0)*sf_[2].pts_[1])/(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1))+bc(1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW2(1-bc(0))-sf_[1].pts_[1]/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/POW2(1-bc(0))))+bc(0)*
00854 ((-bc(1)-bc(0)+1)*(sf_[2].pts_[1]/(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))-(bc(0)*sf_[2].pts_[1])/(1-bc(1))-((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1))+bc(1)*(-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+sf_[0].pts_[0]/(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))+pts_[ind[0]])+(-bc(1)-bc(0)+1)*((bc(0)*sf_[2].pts_[1])/(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1)))-bc(0)*((bc(0)*sf_[2].pts_[1])/(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1)))+bc(1)*
00855 ((-bc(1)-bc(0)+1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW2(1-bc(0))-sf_[1].pts_[1]/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/POW2(1-bc(0)))-((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))-(bc(1)*sf_[1].pts_[0])/(1-bc(0))+bc(0)*(-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+sf_[0].pts_[0]/(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))+(bc(1)*sf_[0].pts_[1])/(bc(1)+bc(0))+(bc(0)*sf_[0].pts_[0])/(bc(1)+bc(0)))-bc(1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/(1-bc(0)))+bc(1)*((bc(1)*sf_[0].pts_[1])/(bc(1)+bc(0))+(bc(0)*sf_[0].pts_[0])/(bc(1)+bc(0)))+bc(0)*pts_[ind[0]];
00856 M.col(1) = -(-bc(1)-bc(0)+1)*pts_[ind[2]]+(-bc(1)-bc(0)+1)*(-pts_[ind[2]]+bc(0)*((bc(0)*sf_[2].pts_[1])/POW2(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW2(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))+bc(1)*(sf_[1].pts_[0]/(1-bc(0))-sf_[1].pts_[1]/(1-bc(0)))+((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/(1-bc(0)))+bc(1)*
00857 (pts_[ind[1]]+(-bc(1)-bc(0)+1)*(sf_[1].pts_[0]/(1-bc(0))-sf_[1].pts_[1]/(1-bc(0)))-((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))-(bc(1)*sf_[1].pts_[0])/(1-bc(0))+bc(0)*(sf_[0].pts_[1]/(bc(1)+bc(0))-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0))))+bc(1)*pts_[ind[1]]+bc(0)*
00858 ((-bc(1)-bc(0)+1)*((bc(0)*sf_[2].pts_[1])/POW2(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW2(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))-(bc(0)*sf_[2].pts_[1])/(1-bc(1))-((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1))+bc(1)*(sf_[0].pts_[1]/(bc(1)+bc(0))-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))+(bc(1)*sf_[0].pts_[1])/(bc(1)+bc(0))+(bc(0)*sf_[0].pts_[0])/(bc(1)+bc(0)))-bc(0)*((bc(0)*sf_[2].pts_[1])/(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1)))-bc(1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/(1-bc(0)))+
00859 (-bc(1)-bc(0)+1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/(1-bc(0)))+bc(0)*((bc(1)*sf_[0].pts_[1])/(bc(1)+bc(0))+(bc(0)*sf_[0].pts_[0])/(bc(1)+bc(0)));
00860 }
00861 #else
00862 const float a=bc(0), b=bc(1);
00863
00864 if(std::abs(a-1)<0.001f) {
00865
00866
00867
00868 M.col(0) = ( -(-b-a+1)*pts_[ind[2]]+(-b-a+1)*(-pts_[ind[2]]+a*(sf_[2].pts_[1]/(1-b)-sf_[2].pts_[0]/(1-b))+(a*sf_[2].pts_[1])/(1-b)+((-b-a+1)*sf_[2].pts_[0])/(1-b))+a*((-b-a+1)*(sf_[2].pts_[1]/(1-b)-sf_[2].pts_[0]/(1-b))-(a*sf_[2].pts_[1])/(1-b)-((-b-a+1)*sf_[2].pts_[0])/(1-b)+b*(-(b*sf_[0].pts_[1])/POW2(b+a)+sf_[0].pts_[0]/(b+a)-(a*sf_[0].pts_[0])/POW2(b+a))+pts_[ind[0]])+(-b-a+1)*((a*sf_[2].pts_[1])/(1-b)+((-b-a+1)*sf_[2].pts_[0])/(1-b))-a*((a*sf_[2].pts_[1])/(1-b)+((-b-a+1)*sf_[2].pts_[0])/(1-b))+b*(-(sf_[1].pts_[1]+sf_[1].pts_[0])/2+a*(-(b*sf_[0].pts_[1])/POW2(b+a)+sf_[0].pts_[0]/(b+a)-(a*sf_[0].pts_[0])/POW2(b+a))+(b*sf_[0].pts_[1])/(b+a)+(a*sf_[0].pts_[0])/(b+a))-(b*(sf_[1].pts_[1]+sf_[1].pts_[0]))/2+b*((b*sf_[0].pts_[1])/(b+a)+(a*sf_[0].pts_[0])/(b+a))+a*pts_[ind[0]] ).head<3>();
00869 M.col(1) = ( -(-b-a+1)*pts_[ind[2]]+(-b-a+1)*(-pts_[ind[2]]+a*((a*sf_[2].pts_[1])/POW2(1-b)+((-b-a+1)*sf_[2].pts_[0])/POW2(1-b)-sf_[2].pts_[0]/(1-b))+(sf_[1].pts_[1]+sf_[1].pts_[0])/2)+b*(pts_[ind[1]]-(sf_[1].pts_[1]+sf_[1].pts_[0])/2+a*(sf_[0].pts_[1]/(b+a)-(b*sf_[0].pts_[1])/POW2(b+a)-(a*sf_[0].pts_[0])/POW2(b+a)))+b*pts_[ind[1]]+a*((-b-a+1)*((a*sf_[2].pts_[1])/POW2(1-b)+((-b-a+1)*sf_[2].pts_[0])/POW2(1-b)-sf_[2].pts_[0]/(1-b))-(a*sf_[2].pts_[1])/(1-b)-((-b-a+1)*sf_[2].pts_[0])/(1-b)+b*(sf_[0].pts_[1]/(b+a)-(b*sf_[0].pts_[1])/POW2(b+a)-(a*sf_[0].pts_[0])/POW2(b+a))+(b*sf_[0].pts_[1])/(b+a)+(a*sf_[0].pts_[0])/(b+a))-a*((a*sf_[2].pts_[1])/(1-b)+((-b-a+1)*sf_[2].pts_[0])/(1-b))-(b*(sf_[1].pts_[1]+sf_[1].pts_[0]))/2+((-b-a+1)*(sf_[1].pts_[1]+sf_[1].pts_[0]))/2+a*((b*sf_[0].pts_[1])/(b+a)+(a*sf_[0].pts_[0])/(b+a)) ).head<3>();
00870
00871
00872 }
00873 else if(std::abs(b-1)<0.001f) {
00874
00875
00876
00877 M.col(0) = ( -(-b-a+1)*pts_[ind[2]]+(-b-a+1)*(-pts_[ind[2]]+(sf_[2].pts_[1]+sf_[2].pts_[0])/2+b*(((-b-a+1)*sf_[1].pts_[1])/POW2(1-a)-sf_[1].pts_[1]/(1-a)+(b*sf_[1].pts_[0])/POW2(1-a)))+a*(-(sf_[2].pts_[1]+sf_[2].pts_[0])/2+b*(-(b*sf_[0].pts_[1])/POW2(b+a)+sf_[0].pts_[0]/(b+a)-(a*sf_[0].pts_[0])/POW2(b+a))+pts_[ind[0]])+((-b-a+1)*(sf_[2].pts_[1]+sf_[2].pts_[0]))/2-(a*(sf_[2].pts_[1]+sf_[2].pts_[0]))/2+b*((-b-a+1)*(((-b-a+1)*sf_[1].pts_[1])/POW2(1-a)-sf_[1].pts_[1]/(1-a)+(b*sf_[1].pts_[0])/POW2(1-a))-((-b-a+1)*sf_[1].pts_[1])/(1-a)-(b*sf_[1].pts_[0])/(1-a)+a*(-(b*sf_[0].pts_[1])/POW2(b+a)+sf_[0].pts_[0]/(b+a)-(a*sf_[0].pts_[0])/POW2(b+a))+(b*sf_[0].pts_[1])/(b+a)+(a*sf_[0].pts_[0])/(b+a))-b*(((-b-a+1)*sf_[1].pts_[1])/(1-a)+(b*sf_[1].pts_[0])/(1-a))+b*((b*sf_[0].pts_[1])/(b+a)+(a*sf_[0].pts_[0])/(b+a))+a*pts_[ind[0]] ).head<3>();
00878 M.col(1) = ( -(-b-a+1)*pts_[ind[2]]+(-b-a+1)*(-pts_[ind[2]]+b*(sf_[1].pts_[0]/(1-a)-sf_[1].pts_[1]/(1-a))+((-b-a+1)*sf_[1].pts_[1])/(1-a)+(b*sf_[1].pts_[0])/(1-a))+b*(pts_[ind[1]]+(-b-a+1)*(sf_[1].pts_[0]/(1-a)-sf_[1].pts_[1]/(1-a))-((-b-a+1)*sf_[1].pts_[1])/(1-a)-(b*sf_[1].pts_[0])/(1-a)+a*(sf_[0].pts_[1]/(b+a)-(b*sf_[0].pts_[1])/POW2(b+a)-(a*sf_[0].pts_[0])/POW2(b+a)))+b*pts_[ind[1]]+a*(-(sf_[2].pts_[1]+sf_[2].pts_[0])/2+b*(sf_[0].pts_[1]/(b+a)-(b*sf_[0].pts_[1])/POW2(b+a)-(a*sf_[0].pts_[0])/POW2(b+a))+(b*sf_[0].pts_[1])/(b+a)+(a*sf_[0].pts_[0])/(b+a))-(a*(sf_[2].pts_[1]+sf_[2].pts_[0]))/2-b*(((-b-a+1)*sf_[1].pts_[1])/(1-a)+(b*sf_[1].pts_[0])/(1-a))+(-b-a+1)*(((-b-a+1)*sf_[1].pts_[1])/(1-a)+(b*sf_[1].pts_[0])/(1-a))+a*((b*sf_[0].pts_[1])/(b+a)+(a*sf_[0].pts_[0])/(b+a)) ).head<3>();
00879
00880
00881 }
00882 else if( std::abs(a+b)<0.003f) {
00883
00884
00885
00886 M.col(0) = ( -(-b-a+1)*pts_[ind[2]]+(-b-a+1)*(-pts_[ind[2]]+a*(sf_[2].pts_[1]/(1-b)-sf_[2].pts_[0]/(1-b))+(a*sf_[2].pts_[1])/(1-b)+((-b-a+1)*sf_[2].pts_[0])/(1-b)+b*(((-b-a+1)*sf_[1].pts_[1])/POW2(1-a)-sf_[1].pts_[1]/(1-a)+(b*sf_[1].pts_[0])/POW2(1-a)))+a*((-b-a+1)*(sf_[2].pts_[1]/(1-b)-sf_[2].pts_[0]/(1-b))-(a*sf_[2].pts_[1])/(1-b)-((-b-a+1)*sf_[2].pts_[0])/(1-b)+pts_[ind[0]])+(-b-a+1)*((a*sf_[2].pts_[1])/(1-b)+((-b-a+1)*sf_[2].pts_[0])/(1-b))-a*((a*sf_[2].pts_[1])/(1-b)+((-b-a+1)*sf_[2].pts_[0])/(1-b))+b*((-b-a+1)*(((-b-a+1)*sf_[1].pts_[1])/POW2(1-a)-sf_[1].pts_[1]/(1-a)+(b*sf_[1].pts_[0])/POW2(1-a))-((-b-a+1)*sf_[1].pts_[1])/(1-a)-(b*sf_[1].pts_[0])/(1-a)+(sf_[0].pts_[1]+sf_[0].pts_[0])/2)-b*(((-b-a+1)*sf_[1].pts_[1])/(1-a)+(b*sf_[1].pts_[0])/(1-a))+(b*(sf_[0].pts_[1]+sf_[0].pts_[0]))/2+a*pts_[ind[0]] ).head<3>();
00887 M.col(1) = ( -(-b-a+1)*pts_[ind[2]]+(-b-a+1)*(-pts_[ind[2]]+a*((a*sf_[2].pts_[1])/POW2(1-b)+((-b-a+1)*sf_[2].pts_[0])/POW2(1-b)-sf_[2].pts_[0]/(1-b))+b*(sf_[1].pts_[0]/(1-a)-sf_[1].pts_[1]/(1-a))+((-b-a+1)*sf_[1].pts_[1])/(1-a)+(b*sf_[1].pts_[0])/(1-a))+b*(pts_[ind[1]]+(-b-a+1)*(sf_[1].pts_[0]/(1-a)-sf_[1].pts_[1]/(1-a))-((-b-a+1)*sf_[1].pts_[1])/(1-a)-(b*sf_[1].pts_[0])/(1-a))+b*pts_[ind[1]]+a*((-b-a+1)*((a*sf_[2].pts_[1])/POW2(1-b)+((-b-a+1)*sf_[2].pts_[0])/POW2(1-b)-sf_[2].pts_[0]/(1-b))-(a*sf_[2].pts_[1])/(1-b)-((-b-a+1)*sf_[2].pts_[0])/(1-b)+(sf_[0].pts_[1]+sf_[0].pts_[0])/2)-a*((a*sf_[2].pts_[1])/(1-b)+((-b-a+1)*sf_[2].pts_[0])/(1-b))-b*(((-b-a+1)*sf_[1].pts_[1])/(1-a)+(b*sf_[1].pts_[0])/(1-a))+(-b-a+1)*(((-b-a+1)*sf_[1].pts_[1])/(1-a)+(b*sf_[1].pts_[0])/(1-a))+(a*(sf_[0].pts_[1]+sf_[0].pts_[0]))/2 ).head<3>();
00888
00889
00890 }
00891 else {
00892 #if 0
00893 M.col(0) = ( -(-b-a+1)*pts_[ind[2]]+(-b-a+1)*(-pts_[ind[2]]+a*(sf_[2].pts_[1]/(1-b)-sf_[2].pts_[0]/(1-b))+(a*sf_[2].pts_[1])/(1-b)+((-b-a+1)*sf_[2].pts_[0])/(1-b)+b*(((-b-a+1)*sf_[1].pts_[1])/POW2(1-a)-sf_[1].pts_[1]/(1-a)+(b*sf_[1].pts_[0])/POW2(1-a)))+a*
00894 ((-b-a+1)*(sf_[2].pts_[1]/(1-b)-sf_[2].pts_[0]/(1-b))-(a*sf_[2].pts_[1])/(1-b)-((-b-a+1)*sf_[2].pts_[0])/(1-b)+b*(-(b*sf_[0].pts_[1])/POW2(b+a)+sf_[0].pts_[0]/(b+a)-(a*sf_[0].pts_[0])/POW2(b+a))+pts_[ind[0]])+(-b-a+1)*((a*sf_[2].pts_[1])/(1-b)+((-b-a+1)*sf_[2].pts_[0])/(1-b))-a*((a*sf_[2].pts_[1])/(1-b)+((-b-a+1)*sf_[2].pts_[0])/(1-b))+b*
00895 ((-b-a+1)*(((-b-a+1)*sf_[1].pts_[1])/POW2(1-a)-sf_[1].pts_[1]/(1-a)+(b*sf_[1].pts_[0])/POW2(1-a))-((-b-a+1)*sf_[1].pts_[1])/(1-a)-(b*sf_[1].pts_[0])/(1-a)+a*(-(b*sf_[0].pts_[1])/POW2(b+a)+sf_[0].pts_[0]/(b+a)-(a*sf_[0].pts_[0])/POW2(b+a))+(b*sf_[0].pts_[1])/(b+a)+(a*sf_[0].pts_[0])/(b+a))-b*(((-b-a+1)*sf_[1].pts_[1])/(1-a)+(b*sf_[1].pts_[0])/(1-a))+b*((b*sf_[0].pts_[1])/(b+a)+(a*sf_[0].pts_[0])/(b+a))+a*pts_[ind[0]] ).head<3>();
00896 M.col(1) = ( -(-b-a+1)*pts_[ind[2]]+(-b-a+1)*(-pts_[ind[2]]+a*((a*sf_[2].pts_[1])/POW2(1-b)+((-b-a+1)*sf_[2].pts_[0])/POW2(1-b)-sf_[2].pts_[0]/(1-b))+b*(sf_[1].pts_[0]/(1-a)-sf_[1].pts_[1]/(1-a))+((-b-a+1)*sf_[1].pts_[1])/(1-a)+(b*sf_[1].pts_[0])/(1-a))+b*
00897 (pts_[ind[1]]+(-b-a+1)*(sf_[1].pts_[0]/(1-a)-sf_[1].pts_[1]/(1-a))-((-b-a+1)*sf_[1].pts_[1])/(1-a)-(b*sf_[1].pts_[0])/(1-a)+a*(sf_[0].pts_[1]/(b+a)-(b*sf_[0].pts_[1])/POW2(b+a)-(a*sf_[0].pts_[0])/POW2(b+a)))+b*pts_[ind[1]]+a*
00898 ((-b-a+1)*((a*sf_[2].pts_[1])/POW2(1-b)+((-b-a+1)*sf_[2].pts_[0])/POW2(1-b)-sf_[2].pts_[0]/(1-b))-(a*sf_[2].pts_[1])/(1-b)-((-b-a+1)*sf_[2].pts_[0])/(1-b)+b*(sf_[0].pts_[1]/(b+a)-(b*sf_[0].pts_[1])/POW2(b+a)-(a*sf_[0].pts_[0])/POW2(b+a))+(b*sf_[0].pts_[1])/(b+a)+(a*sf_[0].pts_[0])/(b+a))-a*((a*sf_[2].pts_[1])/(1-b)+((-b-a+1)*sf_[2].pts_[0])/(1-b))-b*(((-b-a+1)*sf_[1].pts_[1])/(1-a)+(b*sf_[1].pts_[0])/(1-a))+
00899 (-b-a+1)*(((-b-a+1)*sf_[1].pts_[1])/(1-a)+(b*sf_[1].pts_[0])/(1-a))+a*((b*sf_[0].pts_[1])/(b+a)+(a*sf_[0].pts_[0])/(b+a)) ).head<3>();
00900 #else
00901
00902 const float a2=a*a, b2=b*b;
00903 const float a3=a2*a, b3=b2*b;
00904
00905 M.col(0) = M.col(1) = (2*b*pts_[ind[2]]+2*a*pts_[ind[2]]-2*pts_[ind[2]] ).head<3>();
00906
00907 M.col(0) += (
00908 ((4*a*b+6*a2-4*a)*sf_[2].pts_[1]+(-2*b2+(4-8*a)*b-6*a2+8*a-2)*sf_[2].pts_[0])/(b-1)
00909 +(2*b2*sf_[0].pts_[1]+4*a*b*sf_[0].pts_[0])/(b+a)
00910 -(2*a*b2*sf_[0].pts_[1]+2*a2*b*sf_[0].pts_[0])/(b2+2*a*b+a2)
00911 -((4*b2+(4*a-4)*b)*sf_[1].pts_[1]-2*b2*sf_[1].pts_[0])/(a-1)
00912 +((2*b3+(4*a-4)*b2+(2*a2-4*a+2)*b)*sf_[1].pts_[1]+((2-2*a)*b2-2*b3)*sf_[1].pts_[0])/(a2-2*a+1)
00913 +2*a*pts_[ind[0]]
00914 ).head<3>();
00915 M.col(1) += (
00916 (2*a2*sf_[2].pts_[1]+(-4*a*b-4*a2+4*a)*sf_[2].pts_[0])/(b-1)
00917 +(4*a*b*sf_[0].pts_[1]+2*a2*sf_[0].pts_[0])/(b+a)
00918 -(2*a*b2*sf_[0].pts_[1]+2*a2*b*sf_[0].pts_[0])/(b2+2*a*b+a2)
00919 -((6*b2+(8*a-8)*b+2*a2-4*a+2)*sf_[1].pts_[1]+((4-4*a)*b-6*b2)*sf_[1].pts_[0])/(a-1)
00920 -((2*a2*b+2*a3-2*a2)*sf_[2].pts_[1]+(-2*a*b2+(4*a-4*a2)*b-2*a3+4*a2-2*a)*sf_[2].pts_[0])/(b2-2*b+1)
00921 +2*b*pts_[ind[1]]
00922 ).head<3>();
00923 #endif
00924 }
00925 #endif
00926
00927 if(!pcl_isfinite(M.sum())) {
00928 std::cout<<"INF2 v\n"<<M<<"\n";
00929 std::cout<<"bc\n"<<bc<<"\n";
00930 std::cout<<"T\n"<<_T_<<"\n";
00931 size_t ind[3] = { indAB(0,ORDER), indAB(ORDER,ORDER), indAB(0,0) };
00932
00933 for(int i=0; i<3; i++) {
00934 std::cout<<"cp\n"<<pts_[ind[i]]<<"\n";
00935 std::cout<<"uv\n"<<uv_[i]<<"\n";
00936 }
00937 }
00938
00939 return M;
00940 }
00941
00942 inline Eigen::Matrix<float,3,2> normal2BC(const Eigen::Vector2f &bc) {
00943
00944
00945
00946
00947
00948
00949
00950 static const size_t ind[3] = { indAB(0,ORDER), indAB(ORDER,ORDER), indAB(0,0) };
00951
00952 Eigen::Matrix<float,3,2> M;
00953 if(std::abs(bc(0)-1)<0.001f) {
00954 M.col(0) = (2*pts_[ind[2]]+(-bc(1)-bc(0)+1)*((2*sf_[2].pts_[1])/(1-bc(1))-(2*sf_[2].pts_[0])/(1-bc(1)))+2*(-bc(1)-bc(0)+1)*(sf_[2].pts_[1]/(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))-2*bc(0)*(sf_[2].pts_[1]/(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))+bc(0)*(-(2*sf_[2].pts_[1])/(1-bc(1))+(2*sf_[2].pts_[0])/(1-bc(1))+bc(1)*((2*bc(1)*sf_[0].pts_[1])/POW3(bc(1)+bc(0))-(2*sf_[0].pts_[0])/POW2(bc(1)+bc(0))+(2*bc(0)*sf_[0].pts_[0])/POW3(bc(1)+bc(0))))-(4*bc(0)*sf_[2].pts_[1])/(1-bc(1))-(4*(-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1))+bc(1)*(bc(0)*((2*bc(1)*sf_[0].pts_[1])/POW3(bc(1)+bc(0))-(2*sf_[0].pts_[0])/POW2(bc(1)+bc(0))+(2*bc(0)*sf_[0].pts_[0])/POW3(bc(1)+bc(0)))-(2*bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+(2*sf_[0].pts_[0])/(bc(1)+bc(0))-(2*bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))+2*bc(1)*(-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+sf_[0].pts_[0]/(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))+2*pts_[ind[0]] ).head<3>();
00955 M.col(1) = (2*pts_[ind[2]]+2*pts_[ind[1]]+bc(0)*((-bc(1)-bc(0)+1)*((2*bc(0)*sf_[2].pts_[1])/POW3(1-bc(1))+(2*(-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW3(1-bc(1))-(2*sf_[2].pts_[0])/POW2(1-bc(1)))-(2*bc(0)*sf_[2].pts_[1])/POW2(1-bc(1))-(2*(-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW2(1-bc(1))+(2*sf_[2].pts_[0])/(1-bc(1))+bc(1)*(-(2*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+(2*bc(1)*sf_[0].pts_[1])/POW3(bc(1)+bc(0))+(2*bc(0)*sf_[0].pts_[0])/POW3(bc(1)+bc(0)))+(2*sf_[0].pts_[1])/(bc(1)+bc(0))-(2*bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))-(2*bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))-2*bc(0)*((bc(0)*sf_[2].pts_[1])/POW2(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW2(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))+bc(0)*(-bc(1)-bc(0)+1)*((2*bc(0)*sf_[2].pts_[1])/POW3(1-bc(1))+(2*(-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW3(1-bc(1))-(2*sf_[2].pts_[0])/POW2(1-bc(1)))-2*sf_[1].pts_[1]-2*sf_[1].pts_[0]+2*bc(0)*(sf_[0].pts_[1]/(bc(1)+bc(0))-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))+bc(0)*bc(1)*(-(2*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+(2*bc(1)*sf_[0].pts_[1])/POW3(bc(1)+bc(0))+(2*bc(0)*sf_[0].pts_[0])/POW3(bc(1)+bc(0))) ).head<3>();
00956
00957
00958 }
00959 else if(std::abs(bc(1)-1)<0.001f) {
00960 M.col(0) = (2*pts_[ind[2]]-2*sf_[2].pts_[1]-2*sf_[2].pts_[0]+bc(1)*((-bc(1)-bc(0)+1)*((2*(-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW3(1-bc(0))-(2*sf_[1].pts_[1])/POW2(1-bc(0))+(2*bc(1)*sf_[1].pts_[0])/POW3(1-bc(0)))-(2*(-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW2(1-bc(0))+(2*sf_[1].pts_[1])/(1-bc(0))-(2*bc(1)*sf_[1].pts_[0])/POW2(1-bc(0))+bc(0)*((2*bc(1)*sf_[0].pts_[1])/POW3(bc(1)+bc(0))-(2*sf_[0].pts_[0])/POW2(bc(1)+bc(0))+(2*bc(0)*sf_[0].pts_[0])/POW3(bc(1)+bc(0)))-(2*bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+(2*sf_[0].pts_[0])/(bc(1)+bc(0))-(2*bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))-2*bc(1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW2(1-bc(0))-sf_[1].pts_[1]/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/POW2(1-bc(0)))+(-bc(1)-bc(0)+1)*bc(1)*((2*(-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW3(1-bc(0))-(2*sf_[1].pts_[1])/POW2(1-bc(0))+(2*bc(1)*sf_[1].pts_[0])/POW3(1-bc(0)))+2*bc(1)*(-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+sf_[0].pts_[0]/(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))+bc(0)*bc(1)*((2*bc(1)*sf_[0].pts_[1])/POW3(bc(1)+bc(0))-(2*sf_[0].pts_[0])/POW2(bc(1)+bc(0))+(2*bc(0)*sf_[0].pts_[0])/POW3(bc(1)+bc(0)))+2*pts_[ind[0]]).head<3>();
00961 M.col(1) = (2*pts_[ind[2]]+2*pts_[ind[1]]+bc(1)*((2*sf_[1].pts_[1])/(1-bc(0))-(2*sf_[1].pts_[0])/(1-bc(0))+bc(0)*(-(2*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+(2*bc(1)*sf_[0].pts_[1])/POW3(bc(1)+bc(0))+(2*bc(0)*sf_[0].pts_[0])/POW3(bc(1)+bc(0))))-2*bc(1)*(sf_[1].pts_[0]/(1-bc(0))-sf_[1].pts_[1]/(1-bc(0)))+2*(-bc(1)-bc(0)+1)*(sf_[1].pts_[0]/(1-bc(0))-sf_[1].pts_[1]/(1-bc(0)))+(-bc(1)-bc(0)+1)*((2*sf_[1].pts_[0])/(1-bc(0))-(2*sf_[1].pts_[1])/(1-bc(0)))-(4*(-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))-(4*bc(1)*sf_[1].pts_[0])/(1-bc(0))+bc(0)*(bc(1)*(-(2*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+(2*bc(1)*sf_[0].pts_[1])/POW3(bc(1)+bc(0))+(2*bc(0)*sf_[0].pts_[0])/POW3(bc(1)+bc(0)))+(2*sf_[0].pts_[1])/(bc(1)+bc(0))-(2*bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))-(2*bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))+2*bc(0)*(sf_[0].pts_[1]/(bc(1)+bc(0))-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))).head<3>();
00962
00963
00964 }
00965 else if( std::abs(bc(0)+bc(1))<0.001f) {
00966 M.col(0) = (2*pts_[ind[2]]+(-bc(1)-bc(0)+1)*((2*sf_[2].pts_[1])/(1-bc(1))-(2*sf_[2].pts_[0])/(1-bc(1))+bc(1)*((2*(-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW3(1-bc(0))-(2*sf_[1].pts_[1])/POW2(1-bc(0))+(2*bc(1)*sf_[1].pts_[0])/POW3(1-bc(0))))+2*(-bc(1)-bc(0)+1)*(sf_[2].pts_[1]/(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))-2*bc(0)*(sf_[2].pts_[1]/(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))+bc(0)*((2*sf_[2].pts_[0])/(1-bc(1))-(2*sf_[2].pts_[1])/(1-bc(1)))-(4*bc(0)*sf_[2].pts_[1])/(1-bc(1))-(4*(-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1))+bc(1)*((-bc(1)-bc(0)+1)*((2*(-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW3(1-bc(0))-(2*sf_[1].pts_[1])/POW2(1-bc(0))+(2*bc(1)*sf_[1].pts_[0])/POW3(1-bc(0)))-(2*(-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW2(1-bc(0))+(2*sf_[1].pts_[1])/(1-bc(0))-(2*bc(1)*sf_[1].pts_[0])/POW2(1-bc(0)))-2*bc(1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW2(1-bc(0))-sf_[1].pts_[1]/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/POW2(1-bc(0)))+2*pts_[ind[0]]).head<3>();
00967 M.col(1) = (2*pts_[ind[2]]+2*pts_[ind[1]]+bc(0)*((-bc(1)-bc(0)+1)*((2*bc(0)*sf_[2].pts_[1])/POW3(1-bc(1))+(2*(-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW3(1-bc(1))-(2*sf_[2].pts_[0])/POW2(1-bc(1)))-(2*bc(0)*sf_[2].pts_[1])/POW2(1-bc(1))-(2*(-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW2(1-bc(1))+(2*sf_[2].pts_[0])/(1-bc(1)))+(-bc(1)-bc(0)+1)*(bc(0)*((2*bc(0)*sf_[2].pts_[1])/POW3(1-bc(1))+(2*(-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW3(1-bc(1))-(2*sf_[2].pts_[0])/POW2(1-bc(1)))-(2*sf_[1].pts_[1])/(1-bc(0))+(2*sf_[1].pts_[0])/(1-bc(0)))-2*bc(0)*((bc(0)*sf_[2].pts_[1])/POW2(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW2(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))+bc(1)*((2*sf_[1].pts_[1])/(1-bc(0))-(2*sf_[1].pts_[0])/(1-bc(0)))-2*bc(1)*(sf_[1].pts_[0]/(1-bc(0))-sf_[1].pts_[1]/(1-bc(0)))+2*(-bc(1)-bc(0)+1)*(sf_[1].pts_[0]/(1-bc(0))-sf_[1].pts_[1]/(1-bc(0)))-(4*(-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))-(4*bc(1)*sf_[1].pts_[0])/(1-bc(0))).head<3>();
00968
00969
00970 }
00971 else {
00972 M.col(0) = (2*pts_[ind[2]]+(-bc(1)-bc(0)+1)*((2*sf_[2].pts_[1])/(1-bc(1))-(2*sf_[2].pts_[0])/(1-bc(1))+bc(1)*((2*(-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW3(1-bc(0))-(2*sf_[1].pts_[1])/POW2(1-bc(0))+(2*bc(1)*sf_[1].pts_[0])/POW3(1-bc(0))))+2*(-bc(1)-bc(0)+1)*(sf_[2].pts_[1]/(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))-2*bc(0)*(sf_[2].pts_[1]/(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))+bc(0)*(-(2*sf_[2].pts_[1])/(1-bc(1))+(2*sf_[2].pts_[0])/(1-bc(1))+bc(1)*((2*bc(1)*sf_[0].pts_[1])/POW3(bc(1)+bc(0))-(2*sf_[0].pts_[0])/POW2(bc(1)+bc(0))+(2*bc(0)*sf_[0].pts_[0])/POW3(bc(1)+bc(0))))-(4*bc(0)*sf_[2].pts_[1])/(1-bc(1))-
00973 (4*(-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1))+bc(1)*((-bc(1)-bc(0)+1)*((2*(-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW3(1-bc(0))-(2*sf_[1].pts_[1])/POW2(1-bc(0))+(2*bc(1)*sf_[1].pts_[0])/POW3(1-bc(0)))-(2*(-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW2(1-bc(0))+(2*sf_[1].pts_[1])/(1-bc(0))-(2*bc(1)*sf_[1].pts_[0])/POW2(1-bc(0))+bc(0)*((2*bc(1)*sf_[0].pts_[1])/POW3(bc(1)+bc(0))-(2*sf_[0].pts_[0])/POW2(bc(1)+bc(0))+(2*bc(0)*sf_[0].pts_[0])/POW3(bc(1)+bc(0)))-(2*bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+(2*sf_[0].pts_[0])/(bc(1)+bc(0))-(2*bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))-2*bc(1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW2(1-bc(0))-sf_[1].pts_[1]/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/POW2(1-bc(0)))+2*bc(1)*
00974 (-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+sf_[0].pts_[0]/(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))+2*pts_[ind[0]] ).head<3>();
00975
00976 M.col(1) =
00977 (2*pts_[ind[2]]+2*pts_[ind[1]]+bc(0)*((-bc(1)-bc(0)+1)*((2*bc(0)*sf_[2].pts_[1])/POW3(1-bc(1))+(2*(-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW3(1-bc(1))-(2*sf_[2].pts_[0])/POW2(1-bc(1)))-(2*bc(0)*sf_[2].pts_[1])/POW2(1-bc(1))-(2*(-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW2(1-bc(1))+(2*sf_[2].pts_[0])/(1-bc(1))+bc(1)*(-(2*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+(2*bc(1)*sf_[0].pts_[1])/POW3(bc(1)+bc(0))+(2*bc(0)*sf_[0].pts_[0])/POW3(bc(1)+bc(0)))+(2*sf_[0].pts_[1])/(bc(1)+bc(0))-(2*bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))-(2*bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))+(-bc(1)-bc(0)+1)*
00978 (bc(0)*((2*bc(0)*sf_[2].pts_[1])/POW3(1-bc(1))+(2*(-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW3(1-bc(1))-(2*sf_[2].pts_[0])/POW2(1-bc(1)))-(2*sf_[1].pts_[1])/(1-bc(0))+(2*sf_[1].pts_[0])/(1-bc(0)))-2*bc(0)*((bc(0)*sf_[2].pts_[1])/POW2(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW2(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))+bc(1)*((2*sf_[1].pts_[1])/(1-bc(0))-(2*sf_[1].pts_[0])/(1-bc(0))+bc(0)*(-(2*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+(2*bc(1)*sf_[0].pts_[1])/POW3(bc(1)+bc(0))+(2*bc(0)*sf_[0].pts_[0])/POW3(bc(1)+bc(0))))-2*bc(1)*(sf_[1].pts_[0]/(1-bc(0))-sf_[1].pts_[1]/(1-bc(0)))+2*(-bc(1)-bc(0)+1)*(sf_[1].pts_[0]/(1-bc(0))-sf_[1].pts_[1]/(1-bc(0)))-
00979 (4*(-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))-(4*bc(1)*sf_[1].pts_[0])/(1-bc(0))+2*bc(0)*(sf_[0].pts_[1]/(bc(1)+bc(0))-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0))) ).head<3>();
00980 }
00981
00982 if(!pcl_isfinite(M.sum())) {
00983 std::cout<<"INF3 v\n"<<M<<"\n";
00984 std::cout<<"bc\n"<<bc<<"\n";
00985 std::cout<<"T\n"<<_T_<<"\n";
00986 size_t ind[3] = { indAB(0,ORDER), indAB(ORDER,ORDER), indAB(0,0) };
00987
00988 for(int i=0; i<3; i++) {
00989 std::cout<<"cp\n"<<pts_[ind[i]]<<"\n";
00990 std::cout<<"uv\n"<<uv_[i]<<"\n";
00991 }
00992 }
00993
00994 return M;
00995 }
00996
00997 inline bool inside(const Eigen::Vector2f &uv) const {
00998 Eigen::Vector2f br;
00999
01000 br = _T_*(uv-uv_[2]);
01001
01002 return ( std::abs(br(0))+std::abs(br(1))+std::abs(1-br(0)-br(1))<=1 );
01003
01004 }
01005
01006 inline bool complete_inside(const Eigen::Vector2f &uv) const {
01007 Eigen::Vector2f br;
01008
01009 br = _T_*(uv-uv_[2]);
01010
01011 return ( std::abs(br(0))+std::abs(br(1))+std::abs(1-br(0)-br(1))<1 );
01012
01013 }
01014
01015 static float sqDistLinePt(const Eigen::Vector2f &uv, const Eigen::Vector2f &r1, const Eigen::Vector2f &r2) {
01016 float f = (uv-r1).dot(r2-r1) / (r2-r1).squaredNorm();
01017 if(f>1) f=1;
01018 else if(f<0) f=0;
01019 return (uv - f*(r2-r1) - r1).squaredNorm();
01020 }
01021
01022 bool polating(const Eigen::Vector3f &pt, const Eigen::Vector2f &uv, bool &inside, Eigen::Vector2f &r1, Eigen::Vector2f &r2) {
01023 static const size_t ind[3] = { indAB(0,ORDER), indAB(ORDER,ORDER), indAB(0,0) };
01024 float dist[3] = { (pt-pts_[ind[0]].head<3>()).squaredNorm(), (pt-pts_[ind[1]].head<3>()).squaredNorm(), (pt-pts_[ind[2]].head<3>()).squaredNorm() };
01025
01026 Eigen::Vector2f br;
01027
01028 br = _T_*(uv-uv_[2]);
01029
01030
01031
01032 if( std::abs(br(0))+std::abs(br(1))+std::abs(1-br(0)-br(1))<=1 ) {
01033 inside=true;
01034 r1=uv;
01035 return true;
01036 for(int i=0; i<3; i++) dist[i]=std::sqrt(dist[i]);
01037 br(0) = dist[0]/(dist[0]+dist[1]+dist[2]);
01038 br(1) = dist[1]/(dist[0]+dist[1]+dist[2]);
01039
01040 r1 = _T_.inverse()*br + uv_[2];
01041 return true;
01042 }
01043
01044 inside=false;
01045
01046 int m=0;
01047 if(sqDistLinePt(uv,uv_[(1+1)%3],uv_[(1+2)%3])<sqDistLinePt(uv,uv_[(m+1)%3],uv_[(m+2)%3])) m=1;
01048 if(sqDistLinePt(uv,uv_[(2+1)%3],uv_[(2+2)%3])<sqDistLinePt(uv,uv_[(m+1)%3],uv_[(m+2)%3])) m=2;
01049 const int a = (m+1)%3;
01050 const int b = (m+2)%3;
01051 const float f = (uv_[a]-uv_[b]).squaredNorm()/(pts_[ind[a]]-pts_[ind[b]]).squaredNorm();
01052
01053
01054
01055
01056
01057 Eigen::Vector2f p1, p2;
01058
01059 if(pcl_isfinite(f)) {
01060 dist[a]*=f;
01061 dist[b]*=f;
01062
01063 if(std::abs((2*uv_[b](0)-2*uv_[a](0)))>std::abs((2*uv_[b](1)-2*uv_[a](1)))) {
01064 const float n = -(2*uv_[b](1)-2*uv_[a](1)) / (2*uv_[b](0)-2*uv_[a](0));
01065 const float o = uv_[a](0)+(dist[b]-dist[a]+uv_[a].squaredNorm()-uv_[b].squaredNorm())/(2*uv_[b](0)-2*uv_[a](0));
01066
01067 p1(1)=-(std::sqrt((n*n+1)*dist[a]-o*o+2*uv_[a](1)*n*o-uv_[a](1)*uv_[a](1)*n*n)-(n*o+uv_[a](1)))/(n*n+1);
01068 p2(1)= (std::sqrt((n*n+1)*dist[a]-o*o+2*uv_[a](1)*n*o-uv_[a](1)*uv_[a](1)*n*n)+(n*o+uv_[a](1)))/(n*n+1);
01069 p1(0) = n*p1(1) - o+uv_[a](0);
01070 p2(0) = n*p2(1) - o+uv_[a](0);
01071
01072
01073
01074 }
01075 else {
01076 const float n = -(2*uv_[b](0)-2*uv_[a](0)) / (2*uv_[b](1)-2*uv_[a](1));
01077 const float o = uv_[a](1)+(dist[b]-dist[a]+uv_[a].squaredNorm()-uv_[b].squaredNorm())/(2*uv_[b](1)-2*uv_[a](1));
01078
01079 p1(0)=-(std::sqrt((n*n+1)*dist[a]-o*o+2*uv_[a](0)*n*o-uv_[a](0)*uv_[a](0)*n*n)-(n*o+uv_[a](0)))/(n*n+1);
01080 p2(0)= (std::sqrt((n*n+1)*dist[a]-o*o+2*uv_[a](0)*n*o-uv_[a](0)*uv_[a](0)*n*n)+(n*o+uv_[a](0)))/(n*n+1);
01081 p1(1) = n*p1(0) - o+uv_[a](1);
01082 p2(1) = n*p2(0) - o+uv_[a](1);
01083
01084
01085
01086 }
01087 }
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101 if(!pcl_isfinite(f)|| (!pcl_isfinite(p1.sum()) && !pcl_isfinite(p2.sum())) ) {
01102 dist[a] = std::sqrt(dist[a]);
01103 dist[b] = std::sqrt(dist[b]);
01104
01105
01106
01107 r1 = (uv_[a]*dist[a] + uv_[b]*dist[b])/(dist[a]+dist[b]);
01108 inside=true;
01109 return true;
01110 }
01111
01112
01113
01114
01115 r1 = p1;
01116 r2 = p2;
01117 return false;
01118 }
01119
01120 void print() const {
01121 static const size_t ind[3] = { indAB(0,ORDER), indAB(ORDER,ORDER), indAB(0,0) };
01122 for(int i=0; i<3; i++) {
01123 std::cout<<"pt\n"<<pts_[ind[i]]<<"\n";
01124 std::cout<<"n\n"<<n_[ind[i]]<<"\n";
01125 std::cout<<"n2\n"<<n2_[ind[i]]<<"\n";
01126 }
01127 for(int i=0; i<3; i++)
01128 sf_[i].print();
01129 std::cout<<std::endl;
01130 }
01131
01132 };
01133 }
01134
01135 #endif