NonManifoldVertexFixingT.cc 6.83 KB
Newer Older
1 2 3 4

/*===========================================================================*\
 *                                                                           *
 *                               OpenMesh                                    *
Jan Möbius's avatar
Jan Möbius committed
5
 *      Copyright (C) 2001-2014 by Computer Graphics Group, RWTH Aachen      *
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
 *                           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 <http://www.gnu.org/licenses/>.                                      *
 *                                                                           *
 \*===========================================================================*/

/*===========================================================================*\
 *                                                                           *
38 39
 *   $Revision$                                                         *
 *   $Date$                   *
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
 *                                                                           *
 \*===========================================================================*/

/** \file NonManifoldVertexFixingT.cc
 */

//=============================================================================
//
//  CLASS MeshFixing - IMPLEMENTATION
//
//=============================================================================

#define NONMANIFOLDVERTEXFIXING_CC

//== INCLUDES =================================================================

#include "NonManifoldVertexFixingT.hh"

//== NAMESPACE ===============================================================


//== IMPLEMENTATION ==========================================================


template<class MeshT>
NonManifoldVertexFixingT<MeshT>::NonManifoldVertexFixingT(MeshT& _mesh ) :
mesh_(_mesh)
{
}


template<class MeshT>
void NonManifoldVertexFixingT<MeshT>::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
Jan Möbius's avatar
Jan Möbius committed
82 83
    for (typename MeshT::VertexFaceIter vf_iter = mesh_.vf_begin(*v_iter); vf_iter.is_valid(); ++vf_iter)
      mesh_.property(component,*vf_iter) = 0;
84 85 86 87 88 89

    size_t componentCount = 1;


    //search and isolate new components
    //shared vertices will be duplicated
Jan Möbius's avatar
Jan Möbius committed
90
    for (typename MeshT::VertexFaceIter vf_iter = mesh_.vf_begin(*v_iter); vf_iter.is_valid(); ++vf_iter)
91 92 93
    {
      //get the first face in the component
      std::vector<typename MeshT::FaceHandle> checkNeighbour;
Jan Möbius's avatar
Jan Möbius committed
94
      if(mesh_.property(component,*vf_iter) == 0)
95
      {
Jan Möbius's avatar
Jan Möbius committed
96 97
        mesh_.property(component,*vf_iter) = componentCount;
        checkNeighbour.push_back(*vf_iter);
98 99 100 101 102 103 104
      }

      // 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())
      {
Jan Möbius's avatar
Jan Möbius committed
105
        typename MeshT::Point p = mesh_.point(*v_iter);
106 107 108 109 110 111 112 113 114 115 116
        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<typename MeshT::VertexHandle> f_vertices;
        // get all neighbor faces of face
Jan Möbius's avatar
Jan Möbius committed
117
        for (typename MeshT::FaceVertexIter fv_iter = mesh_.fv_begin(face); fv_iter.is_valid(); ++fv_iter)
118
        {
Jan Möbius's avatar
Jan Möbius committed
119 120
          f_vertices.push_back(*fv_iter);
          if (*fv_iter != *v_iter)
121 122 123
          {
            //find the next neighbor face over edge v_iter and fv_iter
            typename MeshT::FaceHandle nf;
Jan Möbius's avatar
Jan Möbius committed
124
            for (typename MeshT::VertexFaceIter nf_iter = mesh_.vf_begin(*v_iter); nf_iter.is_valid() && !nf.is_valid(); ++nf_iter)
125
            {
Jan Möbius's avatar
Jan Möbius committed
126 127 128 129
              if (*nf_iter != face)
                for (typename MeshT::FaceVertexIter nfv_iter = mesh_.fv_begin(*nf_iter); nfv_iter.is_valid() && !nf.is_valid(); ++nfv_iter)
                  if (*nfv_iter == *fv_iter)
                    nf = *nf_iter;
130 131 132 133 134 135 136 137 138 139 140 141 142 143
            }

            //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())
        {
Jan Möbius's avatar
Jan Möbius committed
144
          std::replace(f_vertices.begin(),f_vertices.end(),*v_iter,v_new);
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161

          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();

}