NonManifoldVertexFixingT.cc 6.83 KB
Newer Older
1
2
3
4
5
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

/*===========================================================================*\
 *                                                                           *
 *                               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 <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();

}