2011-05-11 12:04:33 +02:00
|
|
|
#ifndef GLU_TESSELLATOR_CAP_H
|
|
|
|
#define GLU_TESSELLATOR_CAP_H
|
|
|
|
#include "glu_tesselator.h"
|
2011-05-24 11:42:10 +02:00
|
|
|
#include <vcg/simplex/edge/pos.h>
|
2012-01-18 17:48:06 +01:00
|
|
|
#include <vcg/complex/algorithms/clean.h>
|
|
|
|
#include <vcg/complex/algorithms/update/bounding.h>
|
2011-05-11 12:04:33 +02:00
|
|
|
|
|
|
|
namespace vcg {
|
|
|
|
namespace tri {
|
|
|
|
|
2011-05-24 11:42:10 +02:00
|
|
|
|
2011-05-11 12:04:33 +02:00
|
|
|
// This function take a mesh with one or more boundary stored as edges, and fill another mesh with a triangulation of that boundaries.
|
|
|
|
// it assumes that boundary are planar and exploits glutessellator for the triangulaiton
|
|
|
|
template <class MeshType>
|
2012-01-18 17:48:06 +01:00
|
|
|
void CapEdgeMesh(MeshType &em, MeshType &cm, bool revertFlag=false)
|
2011-05-11 12:04:33 +02:00
|
|
|
{
|
|
|
|
typedef typename MeshType::EdgeType EdgeType;
|
2014-06-19 13:42:23 +02:00
|
|
|
typedef typename MeshType::CoordType CoordType;
|
|
|
|
std::vector< std::vector<CoordType> > outlines;
|
|
|
|
std::vector<CoordType> outline;
|
2011-05-11 12:04:33 +02:00
|
|
|
UpdateFlags<MeshType>::EdgeClearV(em);
|
|
|
|
UpdateTopology<MeshType>::EdgeEdge(em);
|
|
|
|
int nv=0;
|
2011-05-31 10:40:02 +02:00
|
|
|
for(size_t i=0;i<em.edge.size();i++) if(!em.edge[i].IsD())
|
2011-05-11 12:04:33 +02:00
|
|
|
{
|
|
|
|
if (!em.edge[i].IsV())
|
|
|
|
{
|
2011-05-24 11:42:10 +02:00
|
|
|
edge::Pos<EdgeType> startE(&em.edge[i],0);
|
|
|
|
edge::Pos<EdgeType> curE=startE;
|
2011-05-11 12:04:33 +02:00
|
|
|
do
|
|
|
|
{
|
2011-05-24 11:42:10 +02:00
|
|
|
curE.E()->SetV();
|
|
|
|
outline.push_back(curE.V()->P());
|
|
|
|
curE.NextE();
|
2011-05-11 12:04:33 +02:00
|
|
|
nv++;
|
|
|
|
}
|
|
|
|
while(curE != startE);
|
2012-01-18 17:48:06 +01:00
|
|
|
if(revertFlag) std::reverse(outline.begin(),outline.end());
|
2011-05-11 12:04:33 +02:00
|
|
|
outlines.push_back(outline);
|
|
|
|
outline.clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (nv<2) return;
|
|
|
|
// printf("Found %i outlines for a total of %i vertices",outlines.size(),nv);
|
|
|
|
|
|
|
|
typename MeshType::VertexIterator vi=vcg::tri::Allocator<MeshType>::AddVertices(cm,nv);
|
|
|
|
for (size_t i=0;i<outlines.size();i++)
|
|
|
|
{
|
|
|
|
for(size_t j=0;j<outlines[i].size();++j,++vi)
|
|
|
|
(&*vi)->P()=outlines[i][j];
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<int> indices;
|
|
|
|
glu_tesselator::tesselate(outlines, indices);
|
2014-06-19 13:42:23 +02:00
|
|
|
std::vector<CoordType> points;
|
2011-05-11 12:04:33 +02:00
|
|
|
glu_tesselator::unroll(outlines, points);
|
2012-01-18 17:48:06 +01:00
|
|
|
//typename MeshType::FaceIterator fi=tri::Allocator<MeshType>::AddFaces(cm,nv-2);
|
|
|
|
typename MeshType::FaceIterator fi=tri::Allocator<MeshType>::AddFaces(cm,indices.size()/3);
|
2011-05-11 12:04:33 +02:00
|
|
|
for (size_t i=0; i<indices.size(); i+=3,++fi)
|
|
|
|
{
|
|
|
|
(*&fi)->V(0)=&cm.vert[ indices[i+0] ];
|
|
|
|
(*&fi)->V(1)=&cm.vert[ indices[i+1] ];
|
|
|
|
(*&fi)->V(2)=&cm.vert[ indices[i+2] ];
|
|
|
|
}
|
|
|
|
Clean<MeshType>::RemoveDuplicateVertex(cm);
|
|
|
|
UpdateBounding<MeshType>::Box(cm);
|
|
|
|
}
|
|
|
|
|
|
|
|
} // end namespace tri
|
|
|
|
} // end namespace vcg
|
|
|
|
|
|
|
|
#endif // GLU_TESSELLATOR_CAP_H
|