From 5233b20f12aa1985381978bc4cb4909b69d8e0a8 Mon Sep 17 00:00:00 2001 From: cignoni Date: Thu, 7 Apr 2011 22:28:28 +0000 Subject: [PATCH] Added a function Flip a mesh so that its normals are orented outside. Just for safety it uses a voting scheme. It assumes that * mesh has already has coherent normals. * mesh is watertight and single component. --- vcg/complex/algorithms/clean.h | 54 ++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/vcg/complex/algorithms/clean.h b/vcg/complex/algorithms/clean.h index ac392a6b..8e27c8ea 100644 --- a/vcg/complex/algorithms/clean.h +++ b/vcg/complex/algorithms/clean.h @@ -1150,6 +1150,60 @@ private: std::swap((*fi).WT(0),(*fi).WT(1)); } } + /// Flip a mesh so that its normals are orented outside. + /// Just for safety it uses a voting scheme. + /// It assumes that + /// mesh has already has coherent normals. + /// mesh is watertight and signle component. + static bool FlipNormalOutside(MeshType &m) + { + if(m.vert.empty()) return false; + + tri::UpdateNormals::PerVertexAngleWeighted(m); + tri::UpdateNormals::NormalizeVertex(m); + + std::vector< VertexPointer > minVertVec; + std::vector< VertexPointer > maxVertVec; + + // The set of directions to be choosen + std::vector< Point3x > dirVec; + dirVec.push_back(Point3x(1,0,0)); + dirVec.push_back(Point3x(0,1,0)); + dirVec.push_back(Point3x(0,0,1)); + dirVec.push_back(Point3x( 1, 1,1)); + dirVec.push_back(Point3x(-1, 1,1)); + dirVec.push_back(Point3x(-1,-1,1)); + dirVec.push_back(Point3x( 1,-1,1)); + for(size_t i=0;iP().dot(dirVec[i])) minVertVec[i] = &*vi; + if( (*vi).cP().dot(dirVec[i]) > maxVertVec[i]->P().dot(dirVec[i])) maxVertVec[i] = &*vi; + } + } + + int voteCount=0; + ScalarType angleThreshold = cos(math::ToRad(85.0)); + for(size_t i=0;iP()[0],minVertVec[i]->P()[1],minVertVec[i]->P()[2]); +// qDebug("Max vert along (%f %f %f) is %f %f %f",dirVec[i][0],dirVec[i][1],dirVec[i][2],maxVertVec[i]->P()[0],maxVertVec[i]->P()[1],maxVertVec[i]->P()[2]); + if(minVertVec[i]->N().dot(dirVec[i]) > angleThreshold ) voteCount++; + if(maxVertVec[i]->N().dot(dirVec[i]) < -angleThreshold ) voteCount++; + } +// qDebug("votecount = %i",voteCount); + if(voteCount < dirVec.size()/2) return false; + FlipMesh(m); + return true; + } + // Search and remove small single triangle folds // - a face has normal opposite to all other faces // - choose the edge that brings to the face f1 containing the vertex opposite to that edge.