outline_support.h
Go to the documentation of this file.
00001 #ifndef OUTLINE_SUPPORT_H
00002 #define OUTLINE_SUPPORT_H
00003 
00004 #include <vcg/math/random_generator.h>
00005 #include <vcg/complex/complex.h>
00006 #include <vcg/complex/algorithms/update/topology.h>
00007 #include <vcg/complex/algorithms/update/bounding.h>
00008 
00009 namespace vcg {
00010 namespace tri {
00011 
00012 // Naming
00013 //  Outline2 just a vector of point2
00014 //  Outline3 just a vector of point2
00015 //  Outline3Vec a vector of Outline2
00016 //  Outline2Vec a vector of Outline2
00017 //  Mesh a common mesh of triangles
00018 //  EdgeMesh a polyline mesh.
00019 
00020 template < class ScalarType>
00021 class OutlineUtil
00022 {
00023 public:
00024 
00025 
00031   static ScalarType Outline2Area(const std::vector< Point2<ScalarType> > &outline2)
00032   {
00033       float   area=0;
00034       for (size_t i=0,j=outline2.size()-1; i<outline2.size(); i++) {
00035           area+=(outline2[j][0]+outline2[i][0])*(outline2[j][1]-outline2[i][1]);
00036           j=i;
00037       }
00038       return -area*.5;
00039   }
00040 
00046   static ScalarType Outline2Perimeter(const std::vector< Point2<ScalarType>  > &outline2)
00047   {
00048       float dd=0; int sz = outline2.size();
00049 
00050       //sums all the distances between point i and point i+1 (modulus sz)
00051       for(int j=0; j<sz; ++j)
00052       {
00053           dd += Distance (Point2f(outline2[j][0],outline2[j][1]),Point2f(outline2[(j+1)%sz][0],outline2[(j+1)%sz][1]));
00054       }
00055       return dd;
00056   }
00057 
00064   static Box2<ScalarType> Outline2BBox(const std::vector<Point2<ScalarType> > &outline2)
00065   {
00066     Box2<ScalarType> bb;
00067     for(size_t i=0;i<outline2.size();++i)
00068       bb.Add(outline2[i]);
00069 
00070     return bb;
00071   }
00072 
00079   static Box2<ScalarType> Outline2VecBBox(const std::vector<std::vector<Point2<ScalarType> > > &outline2Vec)
00080   {
00081     Box2<ScalarType> bb;
00082     for(size_t j=0;j<outline2Vec.size();++j)
00083       for(size_t i=0;i<outline2Vec[j].size();++i)
00084         bb.Add(outline2Vec[j][i]);
00085 
00086     return bb;
00087   }
00088 
00089   static void ReverseOutline2(std::vector< Point2<ScalarType> > &outline2)
00090   {
00091     std::reverse(outline2.begin(),outline2.end());
00092   }
00093 
00094 
00095   static void BuildRandomOutlineVec(int outlineNum, std::vector< std::vector< Point2f > > &outline2Vec, int seed=0)
00096   {
00097     vcg::math::MarsenneTwisterRNG rnd;
00098     if(seed==0) seed=time(0);
00099     rnd.initialize(seed);
00100     for(int i=0;i<outlineNum;++i)
00101     {
00102       std::vector<Point2f> poly;
00103       for(int j=0;j<10;j++)
00104         poly.push_back(Point2f(0.5+0.5*rnd.generate01(),2.0f*M_PI*rnd.generate01()));
00105 
00106       std::sort(poly.begin(),poly.end());
00107 
00108       float ratio = rnd.generateRange(0.2,0.9);
00109       float rot = rnd.generateRange(-M_PI,M_PI);
00110       float scale = pow(rnd.generateRange(0.3,0.9),1);
00111 
00112       for(size_t j=0;j<poly.size();j++)
00113       {
00114         poly[j].Polar2Cartesian();
00115         poly[j][1]*=ratio;
00116         poly[j] *= scale;
00117         poly[j].Cartesian2Polar();
00118         poly[j][1]+=rot;
00119         poly[j].Polar2Cartesian();
00120       }
00121 
00122       Point2f randTras(rnd.generateRange(-5,5),rnd.generateRange(-5,5));
00123       for(size_t j=0;j<poly.size();j++)
00124         poly[j]+=randTras;
00125 
00126       outline2Vec.push_back(poly);
00127     }
00128   }
00129 
00130   static int LargestOutline2(const std::vector< std::vector< Point2f > > &outline2Vec)
00131   {
00132     float maxArea =0;
00133     int maxInd=-1;
00134     for(size_t i=0;i<outline2Vec.size();++i)
00135     {
00136       float curArea = fabs(Outline2Area(outline2Vec[i]));
00137       if(curArea > maxArea)
00138       {
00139         maxArea=curArea;
00140         maxInd=i;
00141       }
00142     }
00143     assert(maxInd>=0);
00144     return maxInd;
00145   }
00146 
00147   template<class PointType>
00148   static bool ConvertOutline3VecToOutline2Vec(std::vector< std::vector< PointType> > &outline3Vec, std::vector< std::vector< Point2f> > &outline2Vec )
00149   {
00150     outline2Vec.resize(outline3Vec.size());
00151     for(size_t i=0;i<outline3Vec.size();++i)
00152     {
00153       //    printf("ConvertToPoint2fOutlines: Outline %4lu (%2lu) :  ",i,outlineVec[i].size());
00154       outline2Vec[i].resize(outline3Vec[i].size());
00155       for(size_t j=0;j<outline3Vec[i].size();++j)
00156       {
00157         outline2Vec[i][j][0]=outline3Vec[i][j][0];
00158         outline2Vec[i][j][1]=outline3Vec[i][j][1];
00159         //      printf("(%5.2f %5.2f)",outlineVec2f[i][j][0],outlineVec2f[i][j][1]);
00160       }
00161       //    printf("\n");
00162     }
00163     return true;
00164   }
00165 
00166   template<class MeshType>
00167   static int ConvertMeshBoundaryToOutline3Vec(MeshType &m, std::vector< std::vector<Point3f> > &outline3Vec)
00168   {
00169     typedef typename MeshType::FaceType FaceType;
00170     std::vector<Point3f> outline;
00171 
00172     tri::Allocator<MeshType>::CompactVertexVector(m);
00173     tri::Allocator<MeshType>::CompactFaceVector(m);
00174     tri::UpdateFlags<MeshType>::FaceClearV(m);
00175     tri::UpdateFlags<MeshType>::VertexClearV(m);
00176     tri::UpdateTopology<MeshType>::FaceFace(m);
00177     int totalVn=0;
00178     for(size_t i=0;i<m.face.size();i++)
00179     {
00180       for (int j=0;j<3;j++)
00181         if (!m.face[i].IsV() && face::IsBorder(m.face[i],j))
00182         {
00183           FaceType* startB=&(m.face[i]);
00184           face::Pos<FaceType> p(startB,j);
00185           face::Pos<FaceType> startPos = p;
00186           assert(p.IsBorder());
00187           do
00188           {
00189             assert(p.IsManifold());
00190             p.F()->SetV();
00191             outline.push_back(p.V()->P());
00192             p.NextB();
00193             totalVn++;
00194           }
00195           while(p != startPos);
00196           outline3Vec.push_back(outline);
00197           outline.clear();
00198         }
00199     }
00200     return totalVn;
00201   }
00202 
00203   template<class MeshType>
00204   static void ConvertMeshBoundaryToEdgeMesh(MeshType &m, MeshType &em)
00205   {
00206     typedef typename MeshType::VertexIterator VertexIterator;
00207     typedef typename MeshType::EdgeIterator EdgeIterator;
00208     typedef typename MeshType::VertexPointer VertexPointer;
00209     em.Clear();
00210     std::vector< std::vector<Point3f> > outlines;
00211     int nv = ConvertMeshBoundaryToOutlines(m,outlines);
00212     if (nv<2) return;
00213     VertexIterator vi=vcg::tri::Allocator<MeshType>::AddVertices(em,nv);
00214     EdgeIterator ei=vcg::tri::Allocator<MeshType>::AddEdges(em,nv);
00215 
00216     //  printf("Building an edge mesh of %i v and %i e and %lu outlines\n",em.vn,em.en,outlines.size());
00217 
00218     for (size_t i=0;i<outlines.size();i++)
00219     {
00220       VertexPointer firstVp = &*vi;
00221       for(size_t j=0;j<outlines[i].size();++j,++vi,++ei)
00222       {
00223         (&*vi)->P()=outlines[i][j];
00224         //      printf("(%5.2f %5.2f %5.2f)",vi->cP()[0],vi->cP()[1],vi->cP()[2]);
00225         ei->V(0)=&*vi;
00226         if((j+1)<outlines[i].size()) ei->V(1)=&*(vi+1);
00227         else ei->V(1)=firstVp;
00228       }
00229       //    printf("\n");
00230     }
00231   }
00232 
00233   template<class MeshType>
00234   static bool ConvertOutline3VecToEdgeMesh(std::vector< std::vector< Point3f> > &outlineVec, MeshType &m)
00235   {
00236     typedef typename MeshType::VertexPointer VertexPointer;
00237     typedef typename MeshType::EdgePointer EdgePointer;
00238 
00239     m.Clear();
00240     std::vector< std::vector<int> > Indexes(outlineVec.size());
00241     for(size_t i=0;i<outlineVec.size();++i)
00242     {
00243       for(size_t j=0;j<outlineVec[i].size();++j)
00244       {
00245         Indexes[i].push_back(m.vert.size());
00246         VertexPointer vp=&*tri::Allocator<MeshType>::AddVertices(m,1);
00247         Point3f pp=Point3f(outlineVec[i][j][0],outlineVec[i][j][1],outlineVec[i][j][2]);
00248         vp->P()= pp;
00249       }
00250     }
00251 
00252     for(size_t i=0;i<outlineVec.size();++i)
00253       for(size_t j=0;j<outlineVec[i].size();++j)
00254       { int polyLen =outlineVec[i].size();
00255         EdgePointer ep=&*tri::Allocator<MeshType>::AddEdges(m,1);
00256         ep->V(0)=&m.vert[Indexes[i][j]];
00257         ep->V(1)=&m.vert[Indexes[i][(j+1)%polyLen]];
00258       }
00259     tri::UpdateBounding<MeshType>::Box(m);
00260     return true;
00261   }
00262 
00263   template<class MeshType>
00264   static bool ConvertOutline3VecToEdgeMesh(std::vector< Point3f> &outline, MeshType &m)
00265   {
00266     std::vector< std::vector< Point3f> > outlineVec;
00267     outlineVec.push_back(outline);
00268     return Convert3DOutlinesToEdgeMesh(outlineVec,m);
00269   }
00270 
00271 };
00272 
00273 } // end namespace tri
00274 } // end namespace vcg
00275 
00276 #endif // OUTLINE_SUPPORT_H


shape_reconstruction
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:33:34