/*===========================================================================*\
* *
* OpenMesh *
* Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
* *
* OpenMesh is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version with the *
* following exceptions: *
* *
* If other files instantiate templates or use macros *
* or inline functions from this file, or you compile this file and *
* link it with other files to produce an executable, this file does *
* not by itself cause the resulting executable to be covered by the *
* GNU Lesser General Public License. This exception does not however *
* invalidate any other reasons why the executable file might be *
* covered by the GNU Lesser General Public License. *
* *
* OpenMesh 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 Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU LesserGeneral Public *
* License along with OpenMesh. If not, *
* see . *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
/** \file NonManifoldVertexFixingT.cc
*/
//=============================================================================
//
// CLASS MeshFixing - IMPLEMENTATION
//
//=============================================================================
#define NONMANIFOLDVERTEXFIXING_CC
//== INCLUDES =================================================================
#include "NonManifoldVertexFixingT.hh"
//== NAMESPACE ===============================================================
//== IMPLEMENTATION ==========================================================
template
NonManifoldVertexFixingT::NonManifoldVertexFixingT(MeshT& _mesh ) :
mesh_(_mesh)
{
}
template
void NonManifoldVertexFixingT::fix()
{
OpenMesh::FPropHandleT< size_t > component;
if ( !mesh_.get_property_handle(component,"component") )
mesh_.add_property(component, "component");
for (typename MeshT::VertexIter v_iter = mesh_.vertices_begin(); v_iter != mesh_.vertices_end(); ++v_iter)
{
// unmark all faces
for (typename MeshT::VertexFaceIter vf_iter = mesh_.vf_begin(v_iter); vf_iter; ++vf_iter)
mesh_.property(component,vf_iter.handle()) = 0;
size_t componentCount = 1;
//search and isolate new components
//shared vertices will be duplicated
for (typename MeshT::VertexFaceIter vf_iter = mesh_.vf_begin(v_iter); vf_iter; ++vf_iter)
{
//get the first face in the component
std::vector checkNeighbour;
if(mesh_.property(component,vf_iter.handle()) == 0)
{
mesh_.property(component,vf_iter.handle()) = componentCount;
checkNeighbour.push_back(vf_iter.handle());
}
// if a reference face was found, a new component exists
// and a new vertex is required (except for the first component)
typename MeshT::VertexHandle v_new;
if (componentCount > 1 && !checkNeighbour.empty())
{
typename MeshT::Point p = mesh_.point(v_iter.handle());
v_new = mesh_.add_vertex(p);
}
// check all adjacent faces of our reference
while(!checkNeighbour.empty())
{
typename MeshT::FaceHandle face = checkNeighbour.back();
checkNeighbour.pop_back();
std::vector f_vertices;
// get all neighbor faces of face
for (typename MeshT::FaceVertexIter fv_iter = mesh_.fv_begin(face); fv_iter; ++fv_iter)
{
f_vertices.push_back(fv_iter.handle());
if (fv_iter.handle() != v_iter)
{
//find the next neighbor face over edge v_iter and fv_iter
typename MeshT::FaceHandle nf;
for (typename MeshT::VertexFaceIter nf_iter = mesh_.vf_begin(v_iter); nf_iter && !nf.is_valid(); ++nf_iter)
{
if (nf_iter.handle() != face)
for (typename MeshT::FaceVertexIter nfv_iter = mesh_.fv_begin(nf_iter); nfv_iter && !nf.is_valid(); ++nfv_iter)
if (nfv_iter.handle() == fv_iter.handle())
nf = nf_iter.handle();
}
//if such a face was found, it is in the same component as the reference face
if (nf.is_valid() && !mesh_.property(component,nf))
{
mesh_.property(component,nf) = componentCount;
checkNeighbour.push_back(nf);
}
}
}
//if one face wasn't found in the component = 1 run, then it is a new component, due to split
if (componentCount > 1 && v_new.is_valid())
{
std::replace(f_vertices.begin(),f_vertices.end(),v_iter.handle(),v_new);
mesh_.delete_face(face,false);
mesh_.add_face(f_vertices);
}
}
// all faces which belong to v_iter and inside same component found
// the next face will be in a new component
++componentCount;
}
}
mesh_.remove_property(component);
mesh_.garbage_collection();
}