surface_tri_spline.hpp
Go to the documentation of this file.
00001 /*
00002  * surface_tri_spline.hpp
00003  *
00004  *  Created on: 01.10.2012
00005  *      Author: josh
00006  */
00007 
00008 #if 0
00009 bool SurfaceTriSpline::TRIANGLE::update2(const std::vector<Eigen::Vector3f> &pts, const std::vector<Eigen::Vector3f> &normals, const std::vector<Eigen::Vector2f> &uv_pts, const Surface *surf)
00010 {
00011   std::cout<<"pS_\n"<<pS_<<"\n";
00012   std::cout<<"nS_\n"<<nS_<<"\n";
00013 
00014   Eigen::Matrix<float,9,9> toSolve_M;
00015   Eigen::Matrix<float,9,1> toSolve_v;
00016 
00017   toSolve_M.fill(0);
00018   toSolve_v.fill(0);
00019 
00020   for(int i=0; i<3; i++)
00021   {
00022     for(int j=0; j<3; j++) toSolve_M.row(i*3+0)(3*i+j) = nI_[i](j);
00023     for(int j=0; j<3; j++) toSolve_M.row(i*3+0)(3*((i+1)%3)+j) = -nI_[i](j);
00024 
00025     for(int j=0; j<3; j++) toSolve_M.row(i*3+1)(3*i+j) = nI_[i](j);
00026     toSolve_v(i*3+1) = nI_[i].dot(I_[i]);
00027 
00028     for(int j=0; j<3; j++) toSolve_M.row(i*3+2)(3*i+j) = normals[i_[i]](j);
00029     toSolve_v(i*3+2) = normals[i_[i]].dot(pts[i_[i]]);
00030   }
00031 
00032   Eigen::Matrix<float,9,1> p = toSolve_M.colPivHouseholderQr().solve(toSolve_v); //toSolve_M.inverse()*toSolve_v;//
00033 
00034   for(int i=0; i<3; i++)
00035   {
00036     for(int j=0; j<3; j++)
00037       pb_[i](j) = p(i*3+j);
00038 
00039     std::cout<<"pb_\n"<<pb_[i]<<"\n";
00040   }
00041   std::cout<<"toSolve_M\n"<<toSolve_M<<"\n";
00042   std::cout<<"toSolve_v\n"<<toSolve_v<<"\n";
00043   std::cout<<"params\n"<<p<<"\n";
00044   std::cout<<"result\n"<<toSolve_M*p-toSolve_v<<"\n";
00045 
00046 #if 0
00047   Eigen::Vector3f line_eq[6];
00048 
00049   for(int i=0; i<3; i++)
00050   {
00051     //intersection of 2 planes --> line
00052     Eigen::Vector3f np = normals[i_[i]].cross( nI_[i] );
00053     const float dot = normals[i_[i]].dot( nI_[i] );
00054     const float h2 = nI_[i].dot( I_[i]-pts[i_[i]] );
00055     const float dot2 = (1-dot*dot);
00056     Eigen::Vector3f vp;
00057     if(dot2) {
00058       vp =
00059           ( (-h2*dot)*normals[i_[i]] + (h2)*nI_[i] )/dot2 + pts[i_[i]];
00060 
00061       if(np.squaredNorm()<0.00001f) {
00062         np = (I_[i]-pts[i_[i]]).cross( (nI_[i]+normals[i_[i]])*0.5f );
00063         vp = (I_[i]+pts[i_[i]])*0.5f;
00064       }
00065     }
00066     else {
00067       np = (I_[i]-pts[i_[i]]).cross( (nI_[i]+normals[i_[i]])*0.5f );
00068       vp = (I_[i]+pts[i_[i]])*0.5f;
00069     }
00070 
00071     //line: p = r*np + vp
00072 
00073     std::cout<<"np\n"<<np<<"\n";
00074     std::cout<<"vp\n"<<vp<<"\n";
00075 
00076     line_eq[i*2+0] = np;
00077     line_eq[i*2+1] = vp;
00078 
00079 
00080     float r = (pts[(i+2)%3]-vp).dot(normals[i_[(i+2)%3]]) / (normals[i_[(i+2)%3]].dot(np));
00081     if(pcl_isfinite(r))
00082       pb_[i] = np*r+vp;
00083     else
00084       pb_[i] = (I_[i] + pts[i_[i]])*0.5f;
00085 
00086     std::cout<<"r "<<r<<"\n";
00087     std::cout<<"pb_\n"<<pb_[i]<<"\n";
00088   }
00089 
00090 #if 0
00091 
00092   Eigen::Matrix3f toSolve_M;
00093   Eigen::Vector3f toSolve_v;
00094 
00095   for(int i=0; i<3; i++)
00096   {
00097     pb_[i] = (I_[i] + pts[i_[i]])*0.5f;
00098 
00099     toSolve_M.row(i)(i) = line_eq[2*i + 0 ].dot(nI_[(i+2)%3]);
00100     toSolve_M.row(i)((1+i)%3) = 0;
00101     toSolve_M.row(i)((2+i)%3) = 0;
00102 
00103     toSolve_v(i) = (pts[i_[i]]-line_eq[2*i + 1 ]).dot(nI_[i_[(i+2)%3]]);
00104   }
00105 
00106   Eigen::Vector3f p = toSolve_M.inverse()*toSolve_v;//toSolve_M.colPivHouseholderQr().solve(toSolve_v); //
00107 
00108   for(int i=0; i<3; i++)
00109   {
00110     if(pcl_isfinite(p(i)))
00111       pb_[i] = line_eq[2*i+0]*p(i)+line_eq[2*i+1];
00112 
00113     std::cout<<"pb_\n"<<pb_[i]<<"\n";
00114   }
00115   std::cout<<"toSolve_M\n"<<toSolve_M<<"\n";
00116   std::cout<<"toSolve_v\n"<<toSolve_v<<"\n";
00117   std::cout<<"params\n"<<p<<"\n";
00118 #endif
00119 #endif
00120   return true;
00121 }
00122 
00123 bool SurfaceTriSpline::TRIANGLE::update1(const std::vector<Eigen::Vector3f> &pts, const std::vector<Eigen::Vector3f> &normals, const std::vector<Eigen::Vector2f> &uv_pts, const Surface *surf)
00124 {
00125   //update barycentric coordinates transformation
00126   _T_.col(0) = uv_pts[i_[0]]-uv_pts[i_[2]];
00127   _T_.col(1) = uv_pts[i_[1]]-uv_pts[i_[2]];
00128   _T_ = _T_.inverse().eval();
00129 
00130   //update barycentric coordinates transformation
00131   Eigen::Vector2f uv_center = (uv_pts[i_[0]]+uv_pts[i_[1]]+uv_pts[i_[2]])/3;
00132   for(int i=0; i<3; i++) {
00133     _Tb_[i].col(0) = uv_center-uv_pts[i_[i]];
00134     _Tb_[i].col(1) = uv_pts[i_[(i+1)%3]]-uv_pts[i_[i]];
00135     _Tb_[i] = _Tb_[i].inverse().eval();
00136   }
00137 
00138   //normal of tensor
00139   add_cross_ = ( pts[i_[1]]-pts[i_[0]] ).cross( pts[i_[2]]-pts[i_[0]] );
00140   add_cross_.normalize();
00141 
00142   float t=0;
00143   for(int i=0; i<3; i++)
00144     t+=add_cross_.dot(normals[i_[i]]);
00145   if(t<0) add_cross_*=-1;
00146 
00147   if(!surf||1) {
00148     Eigen::Vector3f v;
00149     Eigen::Vector2f v2,r;
00150     Eigen::Matrix2f M;
00151     v2(0)=1;v2(1)=0;
00152     //float l;
00153     Eigen::Vector3f line_eq[6];
00154 
00155     for(int i=0; i<3; i++)
00156     {
00157 #if 1
00158       //intersection of 2 planes --> line
00159       Eigen::Vector3f np = normals[i_[i]].cross( normals[i_[(1+i)%3]] );
00160       const float dot = normals[i_[i]].dot( normals[i_[(1+i)%3]] );
00161       const float h2 = normals[i_[(1+i)%3]].dot( pts[i_[(1+i)%3]]-pts[i_[i]] );
00162       const float dot2 = (1-dot*dot);
00163       if(dot2) {
00164         Eigen::Vector3f vp =
00165             ( (-h2*dot)*normals[i_[i]] + (h2)*normals[i_[(1+i)%3]] )/dot2 + pts[i_[i]];
00166 
00167         if(np.squaredNorm()<0.00001f) {
00168           np = (pts[i_[(1+i)%3]]-pts[i_[i]]).cross( (normals[i_[(1+i)%3]]+normals[i_[i]])*0.5f );
00169           vp = (pts[i_[(1+i)%3]]+pts[i_[i]])*0.5f;
00170         }
00171 
00172         //line: p = r*np + vp
00173 
00174         std::cout<<"np\n"<<np<<"\n";
00175         std::cout<<"vp\n"<<vp<<"\n";
00176 
00177         line_eq[i*2+0] = np;
00178         line_eq[i*2+1] = vp;
00179       }
00180       else {
00181         ROS_ASSERT(0);
00182       }
00183 #elif 1
00184       Eigen::Vector3f v = (pts[i_[(1+i)%3]]-pts[i_[i]]);
00185       const float x = ( normals[i_[(1+i)%3]].dot( v ) )/( (normals[i_[(1+i)%3]]-normals[i_[i]]).dot( v ) );
00186       if(!pcl_isfinite(x))
00187         I_[i] = (pts[i_[(1+i)%3]] + pts[i_[i]])*0.5f;
00188       else {
00189         Eigen::Vector3f nx, vx;
00190         nx = (1-x)*normals[i_[(1+i)%3]] + x*normals[i_[i]];
00191         vx = (1-x)*pts[i_[(1+i)%3]] + x*pts[i_[i]];
00192         nx.normalize();
00193 
00194         //intersection of plane with line
00195         const float y = (pts[i_[i]]-vx).dot(normals[i_[i]]) / (normals[i_[i]].dot(nx));
00196 
00197         I_[i] = y*nx + vx;
00198 
00199         std::cout<<"x "<<x<<"\n";
00200         std::cout<<"y "<<y<<"\n";
00201         std::cout<<"nx\n"<<nx<<"\n";
00202         std::cout<<"vx\n"<<vx<<"\n";
00203       }
00204 
00205       std::cout<<"p\n"<<pts[i_[(1+i)%3]]<<"\n"<<pts[i_[i]]<<"\n";
00206       std::cout<<"n\n"<<normals[i_[(1+i)%3]]<<"\n"<<normals[i_[i]]<<"\n";
00207       std::cout<<"I\n"<<I_[i]<<"\n";
00208 #elif 1
00209       //intersection of 2 planes --> line
00210       Eigen::Vector3f np = normals[i_[i]].cross( normals[i_[(1+i)%3]] );
00211       const float dot = normals[i_[i]].dot( normals[i_[(1+i)%3]] );
00212       const float h2 = normals[i_[(1+i)%3]].dot( pts[i_[(1+i)%3]]-pts[i_[i]] );
00213       const float dot2 = (1-dot*dot);
00214       if(dot2) {
00215         Eigen::Vector3f vp =
00216             ( (-h2*dot)*normals[i_[i]] + (h2)*normals[i_[(1+i)%3]] )/dot2;
00217         //line: p = r*np + vp
00218 
00219         Eigen::MatrixXf A(3,2);
00220         A.col(0) = np;
00221         //A.col(1) = pts[i_[(1+i)%3]]-pts[i_[i]];
00222         //      Eigen::Vector2f r = A.jacobiSvd(Eigen::ComputeThinU | Eigen::ComputeThinV).solve(-vp);
00223         //      I_[i] = np*r(0) + vp + pts[i_[i]];
00224         //      I_[i] = np*r(0) + vp + pts[i_[i]];
00225         A.col(1) = add_cross_;
00226         Eigen::Vector2f r = A.jacobiSvd(Eigen::ComputeThinU | Eigen::ComputeThinV).solve(-vp + (pts[i_[(1+i)%3]]+pts[i_[i]])*0.5f-pts[i_[i]]);
00227         I_[i] = add_cross_*r(1) + (pts[i_[(1+i)%3]]+pts[i_[i]])*0.5f;
00228 
00229 
00230         std::cout<<"A\n"<<A<<"\n";
00231         std::cout<<"vp\n"<<vp<<"\n";
00232         std::cout<<"r\n"<<r<<"\n";
00233       }
00234       else {
00235         I_[i] = (pts[i_[(1+i)%3]] + pts[i_[i]])*0.5f;
00236       }
00237       std::cout<<"p\n"<<pts[i_[(1+i)%3]]<<"\n"<<pts[i_[i]]<<"\n";
00238       std::cout<<"n\n"<<normals[i_[(1+i)%3]]<<"\n"<<normals[i_[i]]<<"\n";
00239       std::cout<<"I\n"<<I_[i]<<"\n";
00240 #else
00241       /*v=pts[i_[(1+i)%3]]-pts[i_[i]];
00242     l=v.norm();
00243     v/=l;
00244 
00245     v2(0)=l;
00246 
00247     M.row(1)(0) = v.dot(normals[i_[i]]);
00248     M.row(1)(1) = v.dot(normals[i_[(1+i)%3]]);
00249 
00250     M.row(0)(0) = std::sqrt( 1 - M.row(1)(0)*M.row(1)(0) );
00251     M.row(0)(1) = std::sqrt( 1 - M.row(1)(1)*M.row(1)(1) );
00252 
00253     r = M.inverse()*v2;
00254 
00255     if(!pcl_isfinite(r(0)))
00256       I_[i] = 0.5f*(pts[i_[(1+i)%3]]+pts[i_[i]]);
00257         //return false;
00258     else
00259 
00260     I_[i] = -M.row(1)(0)*r(0) * add_cross_ + (r(0)*pts[i_[(1+i)%3]] + r(1)*pts[i_[i]])/r.sum();
00261 
00262     std::cout<<"p\n"<<pts[i_[(1+i)%3]]<<"\n"<<pts[i_[i]]<<"\n";
00263     std::cout<<"n\n"<<normals[i_[(1+i)%3]]<<"\n"<<normals[i_[i]]<<"\n";
00264     std::cout<<"I\n"<<I_[i]<<"\n";
00265 
00266     std::cout<<"v\n"<<v<<"\n";
00267     std::cout<<"l\n"<<l<<"\n";
00268     std::cout<<"M\n"<<M<<"\n";
00269     std::cout<<"r\n"<<r<<"\n";*/
00270 
00271       Eigen::Matrix<float,3,2> A;
00272       A.col(0) = add_cross_.cross(pts[i_[(1+i)%3]]-pts[i_[i]]).cross(normals[i_[i]]);
00273       A.col(1) = -add_cross_.cross(pts[i_[i]]-pts[i_[(1+i)%3]]).cross(normals[i_[(1+i)%3]]);
00274       r = A.colPivHouseholderQr().solve(pts[i_[(1+i)%3]]-pts[i_[i]]).head<2>();
00275 
00276       I_[i] = r(0)*A.col(0) + pts[i_[i]];
00277 
00278       std::cout<<"p\n"<<pts[i_[(1+i)%3]]<<"\n"<<pts[i_[i]]<<"\n";
00279       std::cout<<"n\n"<<normals[i_[(1+i)%3]]<<"\n"<<normals[i_[i]]<<"\n";
00280       std::cout<<"I\n"<<I_[i]<<"\n";
00281       std::cout<<"I2\n"<<-r(1)*A.col(1) + pts[i_[(1+i)%3]]<<"\n";
00282       std::cout<<"cross\n"<<add_cross_<<"\n";
00283 
00284       std::cout<<"r\n"<<r<<"\n";
00285       std::cout<<"A\n"<<A<<"\n";
00286 
00287       std::cout<<"d\n"<<(pts[i_[(1+i)%3]]-pts[i_[i]])<<"\n";
00288       std::cout<<"d1\n"<<A.col(0).dot(normals[i_[i]])<<"\n";
00289       std::cout<<"d2\n"<<A.col(1).dot(normals[i_[(1+i)%3]])<<"\n";
00290 #endif
00291     }
00292 
00293 
00294     Eigen::Matrix<float,6,3> toSolve_M;
00295     Eigen::Matrix<float,6,1> toSolve_v;
00296 
00297     bool set[3];
00298     for(int i=0; i<3; i++)
00299     {
00300       set[i]=false;
00301       Eigen::Vector3f v = (pts[i_[(1+i)%3]]-pts[i_[i]]);
00302       float x = ( normals[i_[(1+i)%3]].dot( v ) )/( (normals[i_[(1+i)%3]]-normals[i_[i]]).dot( v ) );
00303       if(!pcl_isfinite(x)) {
00304         I_[i] = (pts[i_[(1+i)%3]] + pts[i_[i]])*0.5f;
00305         x=0.5f;
00306       }
00307       else
00308         set[i]=true;
00309       Eigen::Vector3f nx;
00310       nx = (1-x)*normals[i_[(1+i)%3]] + x*normals[i_[i]];
00311       nI_[i] = nx;
00312       nI_[i].normalize();
00313 
00314       std::cout<<"nx\n"<<nx<<"\n";
00315 
00316       toSolve_M.row(i)(i) = 0;
00317       toSolve_M.row(i)((1+i)%3) = line_eq[2*((1+i)%3) + 0 ].dot(nx);
00318       toSolve_M.row(i)((2+i)%3) = -line_eq[2*((2+i)%3) + 0 ].dot(nx);
00319 
00320       toSolve_M.row(i+3)(i) = -line_eq[2*i + 0 ].dot(nx);
00321       toSolve_M.row(i+3)((1+i)%3) = line_eq[2*((1+i)%3) + 0 ].dot(nx);
00322       toSolve_M.row(i+3)((2+i)%3) = 0;
00323 
00324       toSolve_v(i) = line_eq[2*((1+i)%3) + 1 ].dot(nx)-line_eq[2*((2+i)%3) + 1 ].dot(nx);
00325 
00326       toSolve_v(i+3) = line_eq[2*((1+i)%3) + 1 ].dot(nx)-line_eq[2*i + 1 ].dot(nx);
00327     }
00328 
00329     Eigen::Vector3f p = toSolve_M.colPivHouseholderQr().solve(toSolve_v); //toSolve_M.inverse()*toSolve_v;//
00330 
00331     for(int i=0; i<3; i++)
00332     {
00333       if(set[i])
00334         I_[i] = line_eq[2*i+0]*p(i)+line_eq[2*i+1];
00335 
00336       std::cout<<"p\n"<<pts[i_[(1+i)%3]]<<"\n"<<pts[i_[i]]<<"\n";
00337       std::cout<<"n\n"<<normals[i_[(1+i)%3]]<<"\n"<<normals[i_[i]]<<"\n";
00338       std::cout<<"I\n"<<I_[i]<<"\n";
00339     }
00340     std::cout<<"toSolve_M\n"<<toSolve_M<<"\n";
00341     std::cout<<"toSolve_v\n"<<toSolve_v<<"\n";
00342     std::cout<<"params\n"<<p<<"\n";
00343   }
00344   else {
00345 
00346     for(int i=0; i<3; i++)
00347     {
00348       Eigen::Vector3f p = surf->project2world((uv_pts[i_[(1+i)%3]]+uv_pts[i_[i]])*0.5f);
00349       I_[i] = 2*(p-0.25f*(pts[i_[(1+i)%3]]+pts[i_[i]]));
00350 
00351       std::cout<<"I\n"<<I_[i]<<"\n";
00352     }
00353   }
00354 
00355   //calculate apex
00356   {
00357     Eigen::Vector3f br;
00358     br.fill( 1.f/3 );
00359 
00360     Eigen::Vector3f p1 = triNurbsBasis(br, pts[i_[0]], I_[0], I_[2]);
00361     Eigen::Vector3f p2 = triNurbsBasis(br, I_[0], pts[i_[1]], I_[1]);
00362     Eigen::Vector3f p3 = triNurbsBasis(br, I_[2], I_[1], pts[i_[2]]);
00363 
00364     pS_ = triNurbsBasis(br, p1,p2,p3);
00365     nS_ = (p2-p1).cross(p3-p1);
00366     nS_.normalize();
00367   }
00368 
00369   return update2(pts,normals,uv_pts, surf);
00370 
00371 #if 0
00372 
00373   //check if data are valid
00374   float v1,v2;
00375   v1 = ( pts[i_[1]]-pts[i_[0]] ).dot( normals[i_[0]] );
00376   v2 = ( pts[i_[1]]-pts[i_[0]] ).dot( normals[i_[1]] );
00377   if(v1*v2<0) return false;
00378   v1 = ( pts[i_[2]]-pts[i_[0]] ).dot( normals[i_[0]] );
00379   v2 = ( pts[i_[2]]-pts[i_[0]] ).dot( normals[i_[2]] );
00380   if(v1*v2<0) return false;
00381   v1 = ( pts[i_[1]]-pts[i_[2]] ).dot( normals[i_[2]] );
00382   v2 = ( pts[i_[1]]-pts[i_[2]] ).dot( normals[i_[1]] );
00383   if(v1*v2<0) return false;
00384 
00385   //origin: pts[i_[0]]
00386 
00387   //intersection of 2 planes --> line
00388   Eigen::Vector3f np = normals[i_[0]].cross( normals[i_[1]] );
00389   const float dot = normals[i_[0]].dot( normals[i_[1]] );
00390   const float h2 = normals[i_[1]].dot( pts[i_[1]]-pts[i_[0]] );
00391   const float dot2 = (1-dot*dot);
00392   if(dot2) {
00393     Eigen::Vector3f vp =
00394         ( (-h2*dot)*normals[i_[0]] + (h2)*normals[i_[1]] )/dot2;
00395     //line: p = r*np + vp
00396 
00397     //intersection of last plane with line
00398     float r = (pts[i_[2]]-pts[i_[0]]-vp).dot(normals[i_[2]]) / (normals[i_[2]].dot(np));
00399 
00400     add_cp_ = r*np + vp;
00401 
00402     ROS_ASSERT(pcl_isfinite(np.sum()));
00403     ROS_ASSERT(pcl_isfinite(vp.sum()));
00404     ROS_ASSERT(pcl_isfinite(r));
00405   }
00406   else {
00407     add_cp_ = (pts[i_[0]]+pts[i_[1]]+pts[i_[2]])/3-pts[i_[0]];
00408   }
00409   add_cp_tp_(3) = add_cp_.dot(add_cross_);
00410   add_cp_+= pts[i_[0]];
00411   add_cp_tp_(0) = (pts[i_[0]]-pts[i_[2]]).dot(add_cp_-pts[i_[2]]) / (pts[i_[0]]-pts[i_[2]]).squaredNorm();       //next point to line
00412   add_cp_tp_(1) = (pts[i_[1]]-pts[i_[2]]).dot(add_cp_-pts[i_[2]]) / (pts[i_[1]]-pts[i_[2]]).squaredNorm();
00413   add_cp_tp_(2) = (pts[i_[0]]-pts[i_[1]]).dot(add_cp_-pts[i_[1]]) / (pts[i_[0]]-pts[i_[1]]).squaredNorm();
00414 
00415   ROS_ASSERT(pcl_isfinite(add_cp_.sum()));
00416   ROS_ASSERT(pcl_isfinite(_T_.sum()));
00417   ROS_ASSERT(pcl_isfinite(add_cp_tp_.sum()));
00418 
00419   return pcl_isfinite(add_cp_.sum())&&pcl_isfinite(_T_.sum())&&pcl_isfinite(add_cp_tp_.sum());
00420 #endif
00421 }
00422 
00423 void SurfaceTriSpline::TRIANGLE::getWeight(const Eigen::Vector3f &pt, Eigen::Matrix3f &w) const
00424 {
00425   for(int i=0; i<3; i++) {
00426     w(i,0) =   (1-pt(i))*(1-pt(i));
00427     w(i,1) = 2*(pt(i)  )*(1-pt(i));
00428     w(i,2) =   (pt(i)  )*(pt(i)  );
00429   }
00430 }
00431 
00432 void SurfaceTriSpline::TRIANGLE::getWeightD1(const Eigen::Vector3f &pt, Eigen::Matrix3f &w) const
00433 {
00434   ROS_ASSERT(0);//TODO
00435   for(int i=0; i<3; i++) {
00436     w(i,0) =   (pt(i)-1)*(pt(i)-1);
00437     w(i,1) = 2*(pt(i)  )*(pt(i)-1);
00438     w(i,2) =   (pt(i)  )*(pt(i)  );
00439   }
00440 }
00441 
00442 Eigen::Vector3f SurfaceTriSpline::TRIANGLE::triNurbsBasis(const Eigen::Vector3f &bc, const Eigen::Vector3f &p1, const Eigen::Vector3f &p2, const Eigen::Vector3f &p3) const
00443 {
00444   return bc(0)*p1 + bc(1)*p2 + bc(2)*p3;
00445 }
00446 
00447 
00448 Eigen::Vector3f SurfaceTriSpline::TRIANGLE::project2world(const Eigen::Vector2f &pt, const std::vector<Eigen::Vector3f> &pts, const std::vector<Eigen::Vector2f> &uv_pts) const
00449 {
00450   for(int i=0; i<3; i++) {
00451     //1. bayrcentric coordinates 2D -> 3D
00452     Eigen::Vector3f br;
00453     br.head<2>() = _Tb_[i]*(pt-uv_pts[i_[i]]);
00454     br(2) = 1-br(0)-br(1);
00455 
00456     if(!( br(0)>=0 && br(0)<=1 && br(1)>=0 && br(1)<=1 && br(2)>=0 && br(2)<=1) ) continue;
00457 
00458     //  std::cout<<_T_<<"\n";
00459     //  std::cout<<(pt-uv_pts[i_[2]])<<"\n\n";
00460     //  std::cout<<br<<"\n";
00461     //  std::cout<<br(0)*uv_pts[i_[0]]+br(1)*uv_pts[i_[1]]+br(2)*uv_pts[i_[2]]<<"\n\n";
00462 
00463     Eigen::Vector3f p1 = triNurbsBasis(br, pts[i_[i]], I_[i], pb_[i]);
00464     Eigen::Vector3f p2 = triNurbsBasis(br, I_[i], pts[i_[(i+1)%3]], pb_[(i+1)%3]);
00465     Eigen::Vector3f p3 = triNurbsBasis(br, pb_[i],  pb_[(i+1)%3], pS_);
00466 
00467     return triNurbsBasis(br, p1,p2,p3);
00468   }
00469 
00470   //ROS_ASSERT(0);
00471   return Eigen::Vector3f::Zero();
00472 
00473   //  Eigen::Vector3f r = triNurbsBasis(br, p1,p2,p3);
00474   //
00475   //  return -(r-triNurbsBasis(br, pts[i_[0]], pts[i_[1]], pts[i_[2]])).dot(add_cross_)*add_cross_ + triNurbsBasis(br, pts[i_[0]], pts[i_[1]], pts[i_[2]]);
00476 
00477   /*
00478   //inside: br(0)>=0 && br(0)<1 && br(1)>=0 && br(1)<1 && br(2)>=0 && br(2)<1
00479    */
00480 }
00481 
00482 Eigen::Vector3f SurfaceTriSpline::TRIANGLE::normalAt(const Eigen::Vector2f &pt, const std::vector<Eigen::Vector3f> &pts, const std::vector<Eigen::Vector2f> &uv_pts) const
00483 {
00484   //1. bayrcentric coordinates 2D -> 3D
00485   Eigen::Vector3f br;
00486   br.head<2>() = _T_*(pt-uv_pts[i_[2]]);
00487   br(2) = 1-br(0)-br(1);
00488 
00489   //  std::cout<<_T_<<"\n";
00490   //  std::cout<<(pt-uv_pts[i_[2]])<<"\n\n";
00491   //  std::cout<<br<<"\n";
00492   //  std::cout<<br(0)*uv_pts[i_[0]]+br(1)*uv_pts[i_[1]]+br(2)*uv_pts[i_[2]]<<"\n\n";
00493 
00494   Eigen::Vector3f p1 = triNurbsBasis(br, pts[i_[0]], I_[0], I_[2]);
00495   Eigen::Vector3f p2 = triNurbsBasis(br, I_[0], pts[i_[1]], I_[1]);
00496   Eigen::Vector3f p3 = triNurbsBasis(br, I_[2], I_[1], pts[i_[2]]);
00497 
00498   Eigen::Vector3f n = (p2-p1).cross(p3-p1);
00499   n.normalize();
00500   return n;
00501 }
00502 
00503 bool SurfaceTriSpline::TRIANGLE::isIn(const Eigen::Vector2f &pt, const std::vector<Eigen::Vector2f> &uv_pts) const
00504 {
00505   //1. bayrcentric coordinates 2D -> 3D
00506   Eigen::Vector3f br;
00507   br.head<2>() = _T_*(pt-uv_pts[i_[2]]);
00508   br(2) = 1-br(0)-br(1);
00509 
00510   return br(0)>=0 && br(0)<=1 && br(1)>=0 && br(1)<=1 && br(2)>=0 && br(2)<=1;
00511 }
00512 #endif
00513 
00514 void SurfaceTriSpline::init(const boost::array<float, 6> &params, const float min_x, const float max_x, const float min_y, const float max_y, const float weight)
00515 {
00516   ROS_ASSERT(0);
00517 }
00518 
00519 void SurfaceTriSpline::init(const PolynomialSurface *params, const std::vector<Eigen::Vector3f> &pts, const float weight) {
00520 
00521   for(size_t i=0; i<pts.size(); i++) {
00522     ParametricSurface::Topology::POINT p;
00523 
00524     p.uv = pts[i].head<2>();
00525     p.pt = params->project2world(p.uv);
00526     p.n = params->normalAt(p.uv);
00527     p.n2 = params->normalAt2(p.uv);
00528     p.weight_ = weight;
00529     top_.insertPointWithoutUpdate(p);
00530   }
00531 
00532   top_.update();
00533   top_.finish();
00534 }
00535 
00536 void SurfaceTriSpline::init(const PolynomialSurface *params, const float min_x, const float max_x, const float min_y, const float max_y, const float weight)
00537 {
00538   Eigen::Vector2f uv[5];
00539   uv[0](0)=uv[3](0) = min_x;
00540   uv[1](0)=uv[2](0) = max_x;
00541   uv[0](1)=uv[1](1) = min_y;
00542   uv[2](1)=uv[3](1) = max_y;
00543   uv[4](0) = (min_x+max_x)*0.5f;
00544   uv[4](1) = (min_y+max_y)*0.5f;
00545 
00546 #if 1
00547   ParametricSurface::Topology::POINT p;
00548 
00549   p.uv(0) = min_x;
00550   p.uv(1) = min_y;
00551   p.pt = params->project2world(p.uv);
00552   p.n = params->normalAt(p.uv);
00553   p.n2 = params->normalAt2(p.uv);
00554   top_.insertPointWithoutUpdate(p);
00555 
00556   p.uv(0) = max_x;
00557   p.uv(1) = min_y;
00558   p.pt = params->project2world(p.uv);
00559   p.n = params->normalAt(p.uv);
00560   p.n2 = params->normalAt2(p.uv);
00561   top_.insertPointWithoutUpdate(p);
00562 
00563   p.uv(0) = max_x;
00564   p.uv(1) = max_y;
00565   p.pt = params->project2world(p.uv);
00566   p.n = params->normalAt(p.uv);
00567   p.n2 = params->normalAt2(p.uv);
00568   top_.insertPointWithoutUpdate(p);
00569 
00570   p.uv(0) = min_x;
00571   p.uv(1) = max_y;
00572   p.pt = params->project2world(p.uv);
00573   p.n = params->normalAt(p.uv);
00574   p.n2 = params->normalAt2(p.uv);
00575   top_.insertPointWithoutUpdate(p);
00576 
00577   p.uv(0) = (min_x+max_x)*0.5f;
00578   p.uv(1) = (min_y+max_y)*0.5f;
00579   p.pt = params->project2world(p.uv);
00580   p.n = params->normalAt(p.uv);
00581   p.n2 = params->normalAt2(p.uv);
00582   top_.insertPoint(p);
00583 
00584   //top_.finish();
00585 
00586 #else
00587   for(int i=0; i<5; i++)
00588     addPoint(
00589         params->project2world(uv[i]),-params->normalAt(uv[i]),uv[i]
00590     );
00591 
00592   addTriangle(0,1,2, params);
00593   //addTriangle(0,3,2, params);
00594 
00595   //  addTriangle(0,1,4);
00596   //  addTriangle(1,4,2);
00597   //  addTriangle(2,3,4);
00598   //  addTriangle(0,3,4);
00599 #endif
00600 }
00601 
00602 #if 0
00603 void SurfaceTriSpline::addPoint(
00604     const Eigen::Vector3f &p1, const Eigen::Vector3f &n1, const Eigen::Vector2f &uv1
00605 )
00606 {
00607   pts_.push_back(p1);
00608   uv_pts_.push_back(uv1);
00609   normals_.push_back(n1);
00610 }
00611 
00612 void SurfaceTriSpline::addTriangle(const size_t i1, const size_t i2, const size_t i3, const Surface *surf) {
00613   ROS_ASSERT(i1<pts_.size());
00614   ROS_ASSERT(i2<pts_.size());
00615   ROS_ASSERT(i3<pts_.size());
00616 
00617   triangles_.push_back( TRIANGLE(i1,i2,i3) );
00618   ROS_ASSERT( triangles_.back().update1(pts_,normals_,uv_pts_, surf) );
00619 }
00620 #endif
00621 
00623 void SurfaceTriSpline::transform(const Eigen::Matrix3f &rot, const Eigen::Vector3f &tr)
00624 {
00625 #if 1
00626   top_.transform(rot,tr);
00627 #else
00628   for(size_t i=0; i<pts_.size(); i++) {
00629     pts_[i] = rot*pts_[i]+tr;
00630     normals_[i] = rot*normals_[i];
00631   }
00632   for(size_t i=0; i<triangles_.size(); i++)
00633     triangles_[i].transform(rot,tr);
00634 #endif
00635 }
00636 
00637 Eigen::Vector3f SurfaceTriSpline::project2world(const Eigen::Vector2f &pt) const
00638 {
00639 #if 1
00640   return top_.project2world(pt);
00641 #else
00642   size_t next=0;
00643   float dis = std::numeric_limits<float>::max();
00644 
00645   for(size_t i=0; i<triangles_.size(); i++)
00646   {
00647     if(triangles_[i].isIn(pt,uv_pts_)) {
00648       return triangles_[i].project2world(pt,pts_,uv_pts_);
00649     }
00650 
00651     const float d = (uv_pts_[triangles_[i].i_[0]]-pt).squaredNorm();
00652     if(d<dis) {
00653       dis = d;
00654       next = i;
00655     }
00656 
00657   }
00658 
00659   return triangles_[next].project2world(pt,pts_,uv_pts_);
00660 
00661   ROS_ASSERT(0);
00662 #endif
00663 }
00664 
00665 Eigen::Vector3f SurfaceTriSpline::normalAt(const Eigen::Vector2f &pt) const
00666 {
00667 #if 1
00668   return top_.normalAt(pt);
00669 #else
00670   size_t next=0;
00671   float dis = std::numeric_limits<float>::max();
00672 
00673   for(size_t i=0; i<triangles_.size(); i++)
00674   {
00675     if(triangles_[i].isIn(pt,uv_pts_)) {
00676       return triangles_[i].normalAt(pt,pts_,uv_pts_);
00677     }
00678 
00679     const float d = (uv_pts_[triangles_[i].i_[0]]-pt).squaredNorm();
00680     if(d<dis) {
00681       dis = d;
00682       next = i;
00683     }
00684 
00685   }
00686 
00687   return triangles_[next].normalAt(pt,pts_,uv_pts_);
00688 
00689   ROS_ASSERT(0);
00690 #endif
00691 }
00692 
00693 Eigen::Vector2f SurfaceTriSpline::nextPoint(const Eigen::Vector3f &v) const {
00694   ___CTR___++;
00695   return top_.nextPoint(v);
00696 }
00697 
00698 float SurfaceTriSpline::merge(const Surface &o, const float this_w, const float o_w, const SWINDOW &wind_t, const SWINDOW &wind_o) {
00699   return (top_ += ((SurfaceTriSpline*)(&o))->top_);
00700 }
00701 
00702 /*
00703  * merging rules:
00704  *
00705  * generate merge pts + normals of all input data (including mid pts ???)
00706  * build topology with valid connections (TODO)
00707  * check
00708  */


cob_3d_mapping_slam
Author(s): Joshua Hampp
autogenerated on Wed Aug 26 2015 11:04:51