mesh_conversion.hpp
Go to the documentation of this file.
00001 
00063 #ifndef COB_MESH_CONVERSION_HPP
00064 #define COB_MESH_CONVERSION_HPP
00065 
00066 namespace cob_3d_meshing
00067 {
00068   template<typename SensorT>
00069   template<typename PointT, typename MeshT>
00070   void MeshConversion<SensorT>::fromPointCloud(
00071     const typename pcl::PointCloud<PointT>::ConstPtr& pc, MeshT& mesh)
00072   {
00073     typedef typename MeshT::VertexHandle VertexHandle;
00074 
00075     int rows = pc->height - 1; // last row
00076     int cols = pc->width - 1; // last column
00077     int row_offset;
00078     // [h]orizontal, [v]ertical, [l]eft, [r]ight edge check
00079     std::vector<std::vector<bool> > h(rows+1, std::vector<bool>(cols,true));
00080     std::vector<std::vector<bool> > v(rows, std::vector<bool>(cols+1,true));
00081     std::vector<std::vector<bool> > l(rows, std::vector<bool>(cols,true));
00082     std::vector<std::vector<bool> > r(rows, std::vector<bool>(cols,true));
00083     std::vector<std::vector<VertexHandle> >
00084       vh(rows+1, std::vector<VertexHandle>(cols+1)); // vertex handles
00085 
00086     /*
00087      * +--+--+   p00  h00  p01  h01  p02
00088      * |  |  |   v00 lr00  v01 lr01  v02
00089      * +--+--+   p10  h10  p11  h11  p12
00090      * |  |  |   v10 lr10  v11 lr11  v12
00091      * +--+--+   p20  h20  p21  h21  p22
00092      */
00093 
00094     // corners
00095     h.front().front() = v.front().front() = r.front().front() = false;
00096     h.front().back()  = v.front().back()  = l.front().back()  = false;
00097     h.back().front() = v.back().front() = l.back().front() = false;
00098     h.back().back()  = v.back().back()  = r.back().back()  = false;
00099 
00100     // first and last row
00101     for(int x = 1; x<cols; ++x)
00102     {
00103       h.front()[x-1] = false;
00104       h.front()[x  ] = false;
00105       v.front()[x  ] = false;
00106       l.front()[x-1] = false;
00107       r.front()[x  ] = false;
00108       h.back ()[x-1] = false;
00109       h.back ()[x  ] = false;
00110       v.back ()[x  ] = false;
00111       r.back ()[x-1] = false;
00112       l.back ()[x  ] = false;
00113     }
00114 
00115     for(int y = 1; y<rows; ++y)
00116     {
00117       // left column and right column
00118       h[y  ].front() = false;
00119       v[y-1].front() = false;
00120       v[y  ].front() = false;
00121       l[y-1].front() = false;
00122       r[y  ].front() = false;
00123       h[y  ].back()  = false;
00124       v[y-1].back()  = false;
00125       v[y  ].back()  = false;
00126       r[y-1].back()  = false;
00127       l[y  ].back()  = false;
00128 
00129       row_offset = y*(cols+1);
00130       // iterate remaining
00131       for(int x=1; x<cols; ++x)
00132       {
00133         const PointT* p = &(*pc)[row_offset+x];
00134         if( p->z != p->z )
00135         {
00136           v[y-1][x  ] = false;
00137           v[y  ][x  ] = false;
00138           h[y  ][x-1] = false;
00139           h[y  ][x  ] = false;
00140           l[y-1][x  ] = false;
00141           l[y  ][x-1] = false;
00142           r[y-1][x-1] = false;
00143           r[y  ][x  ] = false;
00144         }
00145         else
00146         {
00147           vh[y][x] = mesh.addVertex(y*pc->width+x, *p);
00148         }
00149       }
00150     }
00151 
00152     // iterate h and v to check if edge is valid
00153     typename std::vector<PointT, Eigen::aligned_allocator_indirection<PointT> >
00154       ::const_iterator pii = pc->points.begin();
00155     typename std::vector<PointT, Eigen::aligned_allocator_indirection<PointT> >
00156       ::const_iterator pij = pii + 1; // right
00157     typename std::vector<PointT, Eigen::aligned_allocator_indirection<PointT> >
00158       ::const_iterator pji = pii + 1 + cols; // below
00159     typename std::vector<PointT, Eigen::aligned_allocator_indirection<PointT> >
00160       ::const_iterator pjj = pji + 1; // below right
00161 
00162     for(int y=0; y<rows; ++y)
00163     {
00164       for(int x=0; x<cols; ++x)
00165       {
00166         // check horizontal and vertical
00167         if (h[y][x])
00168           h[y][x] = isNeighbor(pii->getVector3fMap(), pij->getVector3fMap());
00169         if (v[y][x])
00170           v[y][x] = isNeighbor(pii->getVector3fMap(), pji->getVector3fMap());
00171 
00172         // check diagonal
00173         unsigned char status = (l[y][x] << 1) | r[y][x];
00174         switch(status)
00175         {
00176         case 0b00:
00177           break;
00178         case 0b01:
00179           r[y][x] = isNeighbor(pii->getVector3fMap(), pjj->getVector3fMap());
00180           break;
00181         case 0b10:
00182           l[y][x] = isNeighbor(pij->getVector3fMap(), pji->getVector3fMap());
00183           break;
00184         case 0b11:
00185           if( (pij->z - pji->z) > (pii->z - pjj->z) )
00186           {
00187             r[y][x] = false;
00188             l[y][x] = isNeighbor(pij->getVector3fMap(), pji->getVector3fMap());
00189           }
00190           else
00191           {
00192             l[y][x] = false;
00193             r[y][x] = isNeighbor(pii->getVector3fMap(), pjj->getVector3fMap());
00194           }
00195           break;
00196         }
00197         ++pii; ++pij; ++pji; ++pjj;
00198       }
00199       // skip the last column
00200       // note that in the very last iteration, pjj points beyond end()
00201       ++pii; ++pij; ++pji; ++pjj;
00202     }
00203 
00204     for(int y=0; y<rows; ++y)
00205     {
00206       for(int x=0; x<cols; ++x)
00207       {
00208         /* ii-ji-ij | ij-ji-jj | ii-jj-ij | ii-ji-jj
00209          *  +-+     |    +     |  +-+     |  +
00210          *  |/      |   /|     |   \|     |  |\
00211          *  +       |  +-+     |    +     |  +-+     */
00212         if(l[y][x])
00213         {
00214           if (h[y  ][x] && v[y][x  ])
00215             mesh.addFace(vh[y][x  ], vh[y+1][x], vh[y  ][x+1]);
00216           if (h[y+1][x] && v[y][x+1])
00217             mesh.addFace(vh[y][x+1], vh[y+1][x], vh[y+1][x+1]);
00218         }
00219         else if (r[y][x])
00220         {
00221           if (h[y][x] && v[y][x+1])
00222             mesh.addFace(vh[y][x], vh[y+1][x+1], vh[y][x+1]);
00223           if (v[y][x] && h[y+1][x])
00224             mesh.addFace(vh[y][x], vh[y+1][x], vh[y+1][x+1]);
00225         }
00226       }
00227     }
00228   }
00229 }
00230 
00231 #endif


cob_3d_meshing
Author(s): Georg Arbeiter
autogenerated on Wed Aug 26 2015 11:04:03