/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004-2016 \/)\/ * * Visual Computing Lab /\/| * * ISTI - Italian National Research Council | * * \ * * All rights reserved. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * * for more details. * * * ****************************************************************************/ #ifndef OUTLINE_SUPPORT_H #define OUTLINE_SUPPORT_H #include #include #include #include namespace vcg { namespace tri { // Naming // Outline2 just a vector of point2 // Outline3 just a vector of point2 // Outline3Vec a vector of Outline2 // Outline2Vec a vector of Outline2 // Mesh a common mesh of triangles // EdgeMesh a polyline mesh. template < class ScalarType> class OutlineUtil { public: /** * Returns the area of the polygon defined by the parameter points * @param a vector of points * @return the area of the polygon */ static ScalarType Outline2Area(const std::vector< Point2 > &outline2) { float area=0; for (size_t i=0,j=outline2.size()-1; i > &outline2) { float dd=0; int sz = outline2.size(); //sums all the distances between point i and point i+1 (modulus sz) for(int j=0; j Outline2BBox(const std::vector > &outline2) { Box2 bb; for(size_t i=0;i Outline2VecBBox(const std::vector > > &outline2Vec) { Box2 bb; for(size_t j=0;j > &outline2) { std::reverse(outline2.begin(),outline2.end()); } static void BuildRandomOutlineVec(int outlineNum, std::vector< std::vector< Point2f > > &outline2Vec, int seed=0) { vcg::math::MarsenneTwisterRNG rnd; if(seed==0) seed=time(0); rnd.initialize(seed); for(int i=0;i poly; for(int j=0;j<10;j++) poly.push_back(Point2f(0.5+0.5*rnd.generate01(),2.0f*M_PI*rnd.generate01())); std::sort(poly.begin(),poly.end()); float ratio = rnd.generateRange(0.2,0.9); float rot = rnd.generateRange(-M_PI,M_PI); float scale = pow(rnd.generateRange(0.3,0.9),1); for(size_t j=0;j > &outline2Vec) { float maxArea =0; int maxInd=-1; for(size_t i=0;i maxArea) { maxArea=curArea; maxInd=i; } } assert(maxInd>=0); return maxInd; } template static bool ConvertOutline3VecToOutline2Vec(std::vector< std::vector< PointType> > &outline3Vec, std::vector< std::vector< Point2f> > &outline2Vec ) { outline2Vec.resize(outline3Vec.size()); for(size_t i=0;i static int ConvertMeshBoundaryToOutline3Vec(MeshType &m, std::vector< std::vector > &outline3Vec) { typedef typename MeshType::FaceType FaceType; std::vector outline; tri::Allocator::CompactVertexVector(m); tri::Allocator::CompactFaceVector(m); tri::UpdateFlags::FaceClearV(m); tri::UpdateFlags::VertexClearV(m); tri::UpdateTopology::FaceFace(m); int totalVn=0; for(size_t i=0;i p(startB,j); face::Pos startPos = p; assert(p.IsBorder()); do { assert(p.IsManifold()); p.F()->SetV(); outline.push_back(p.V()->P()); p.NextB(); totalVn++; } while(p != startPos); outline3Vec.push_back(outline); outline.clear(); } } return totalVn; } template static void ConvertMeshBoundaryToEdgeMesh(MeshType &m, MeshType &em) { typedef typename MeshType::VertexIterator VertexIterator; typedef typename MeshType::EdgeIterator EdgeIterator; typedef typename MeshType::VertexPointer VertexPointer; em.Clear(); std::vector< std::vector > outlines; int nv = ConvertMeshBoundaryToOutlines(m,outlines); if (nv<2) return; VertexIterator vi=vcg::tri::Allocator::AddVertices(em,nv); EdgeIterator ei=vcg::tri::Allocator::AddEdges(em,nv); // printf("Building an edge mesh of %i v and %i e and %lu outlines\n",em.vn,em.en,outlines.size()); for (size_t i=0;iP()=outlines[i][j]; // printf("(%5.2f %5.2f %5.2f)",vi->cP()[0],vi->cP()[1],vi->cP()[2]); ei->V(0)=&*vi; if((j+1)V(1)=&*(vi+1); else ei->V(1)=firstVp; } // printf("\n"); } } template static bool ConvertOutline3VecToEdgeMesh(std::vector< std::vector< Point3f> > &outlineVec, MeshType &m) { typedef typename MeshType::VertexPointer VertexPointer; typedef typename MeshType::EdgePointer EdgePointer; m.Clear(); std::vector< std::vector > Indexes(outlineVec.size()); for(size_t i=0;i::AddVertices(m,1); Point3f pp=Point3f(outlineVec[i][j][0],outlineVec[i][j][1],outlineVec[i][j][2]); vp->P()= pp; } } for(size_t i=0;i::AddEdges(m,1); ep->V(0)=&m.vert[Indexes[i][j]]; ep->V(1)=&m.vert[Indexes[i][(j+1)%polyLen]]; } tri::UpdateBounding::Box(m); return true; } template static bool ConvertOutline3VecToEdgeMesh(std::vector< Point3f> &outline, MeshType &m) { std::vector< std::vector< Point3f> > outlineVec; outlineVec.push_back(outline); return Convert3DOutlinesToEdgeMesh(outlineVec,m); } }; } // end namespace tri } // end namespace vcg #endif // OUTLINE_SUPPORT_H