From 7037098822bc2addc03dc324089c78bf86d81d30 Mon Sep 17 00:00:00 2001 From: cignoni Date: Thu, 27 Jan 2011 15:49:21 +0000 Subject: [PATCH] Added to BitQuad Support a Generic quad triangulation function and used in OFF importer. It takes in input 4 vertex pointrs and rotate them so that a simple fan triangulation is Ok. It uses geometric criteria for avoiding bad shaped triangles, and folds and it use an internal set of already created diagonal to avoid the creation of non manifold situations. --- vcg/complex/trimesh/bitquad_support.h | 47 +++++++++++++++++++++++++++ wrap/io_trimesh/import_off.h | 38 ++++++++-------------- 2 files changed, 61 insertions(+), 24 deletions(-) diff --git a/vcg/complex/trimesh/bitquad_support.h b/vcg/complex/trimesh/bitquad_support.h index 531a1093..e6c49d11 100644 --- a/vcg/complex/trimesh/bitquad_support.h +++ b/vcg/complex/trimesh/bitquad_support.h @@ -1,8 +1,10 @@ #ifndef VCG_BITQUAD_SUPPORT #define VCG_BITQUAD_SUPPORT #include +#include #include #include +#include #include /** BIT-QUAD creation support: @@ -91,6 +93,7 @@ typedef typename MeshType::FaceType* FaceTypeP; typedef typename MeshType::VertexType VertexType; typedef typename MeshType::FaceIterator FaceIterator; typedef typename MeshType::VertexIterator VertexIterator; +typedef typename MeshType::VertexPointer VertexPointer; class Pos{ FaceType *f; @@ -1126,7 +1129,51 @@ static ScalarType Cos(const CoordType &a, const CoordType &b, const CoordType &c if (d==0) return 0.0; return (e0*e1)/d; } +public: +/** + Generic quad triangulation function. + It take in input 4 vertex pointrs and rotate them so that a simple fan triangulation is Ok. + It uses geometric criteria for avoiding bad shaped triangles, and folds + and it use an internal set of already created diagonal to avoid the creation of non manifold situations. + At the begin you shoud call this function with an empty vector to reset the set of existing diagonals. + */ +static void QuadTriangulate(std::vector &q) +{ + typedef typename std::set > diagSetType; + static diagSetType diagSet; // the set of already created diagonals + if(q.size()!=4) + { + diagSet.clear(); + return; + } + const CoordType &P0=q[0]->cP(); + const CoordType &P1=q[1]->cP(); + const CoordType &P2=q[2]->cP(); + const CoordType &P3=q[3]->cP(); + CoordType N00 = Normal(P0,P1,P2); + CoordType N01 = Normal(P0,P2,P3); + CoordType N10 = Normal(P1,P2,P3); + CoordType N11 = Normal(P1,P3,P0); + + ScalarType Angle0Rad=Angle(N00,N01); + ScalarType Angle1Rad=Angle(N10,N11); + + // QualityRadii is inradius/circumradius; bad when close to zero. + // swap diagonal if the worst triangle improve. + bool qualityImprove = std::min(QualityRadii(P0,P1,P2),QualityRadii(P0,P2,P3)) < std::min(QualityRadii(P1,P2,P3),QualityRadii(P1,P3,P0)); + bool swapCauseFlip = (Angle1Rad > M_PI/2.0) && (Angle0Rad res; + if(q[0] #include #include +#include #include #include @@ -371,6 +372,12 @@ namespace vcg Allocator::AddFaces(mesh, nFaces); unsigned int f0=0; + + + // Initial call to the QuadTriangulate with an empty vector to just reset the static set of existing diagonals + std::vector qtmp; + BitQuad::QuadTriangulate(qtmp); + for (unsigned int f=0; f < nFaces; f++) { f0 = f; @@ -419,30 +426,13 @@ namespace vcg k++; } if(vert_per_face==4) - { // To well triangulate the quad: - // if the quad is flat and convex we use the shortest diag , - // else we should use the diag that makes the smallest - - const CoordType &P0=mesh.vert[vertIndices[0]].cP(); - const CoordType &P1=mesh.vert[vertIndices[1]].cP(); - const CoordType &P2=mesh.vert[vertIndices[2]].cP(); - const CoordType &P3=mesh.vert[vertIndices[3]].cP(); - - CoordType N00 = Normal(P0,P1,P2); - CoordType N01 = Normal(P0,P2,P3); - CoordType N10 = Normal(P1,P2,P3); - CoordType N11 = Normal(P1,P3,P0); - - ScalarType Angle0Rad=Angle(N00,N01); - ScalarType Angle1Rad=Angle(N10,N11); - - // QualityRadii is inradius/circumradius; bad when close to zero. - // swap diagonal if the worst triangle improve. - bool qualityImprove = std::min(QualityRadii(P0,P1,P2),QualityRadii(P0,P2,P3)) < std::min(QualityRadii(P1,P2,P3),QualityRadii(P1,P3,P0)); - bool swapCauseFlip = (Angle1Rad > M_PI/2.0) && (Angle0Rad q(4); + for(int qqi=0;qqi<4;++qqi) + q[qqi]=& mesh.vert[vertIndices[qqi]]; + BitQuad::QuadTriangulate(q); + for(int qqi=0;qqi<4;++qqi) + vertIndices[qqi] = q[qqi]- & mesh.vert[0]; } // standard fan triangulation (we hope the polygon is convex...) for (int j=0; j<=vert_per_face-3; j++)