Developer Documentation
NonManifoldVertexFixingT.cc
Go to the documentation of this file.
1 
2 /*===========================================================================*\
3  * *
4  * OpenMesh *
5  * Copyright (c) 2001-2015, RWTH-Aachen University *
6  * Department of Computer Graphics and Multimedia *
7  * All rights reserved. *
8  * www.openflipper.org *
9  * *
10  *---------------------------------------------------------------------------*
11  * This file is part of OpenFlipper. *
12  *---------------------------------------------------------------------------*
13  * *
14  * Redistribution and use in source and binary forms, with or without *
15  * modification, are permitted provided that the following conditions *
16  * are met: *
17  * *
18  * 1. Redistributions of source code must retain the above copyright notice, *
19  * this list of conditions and the following disclaimer. *
20  * *
21  * 2. Redistributions in binary form must reproduce the above copyright *
22  * notice, this list of conditions and the following disclaimer in the *
23  * documentation and/or other materials provided with the distribution. *
24  * *
25  * 3. Neither the name of the copyright holder nor the names of its *
26  * contributors may be used to endorse or promote products derived from *
27  * this software without specific prior written permission. *
28  * *
29  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
30  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
31  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
32  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
33  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
34  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
35  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
36  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
37  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
38  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
39  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
40  * *
41  \*===========================================================================*/
42 
43 /*===========================================================================*\
44  * *
45  * $Revision$ *
46  * $Date$ *
47  * *
48  \*===========================================================================*/
49 
53 //=============================================================================
54 //
55 // CLASS MeshFixing - IMPLEMENTATION
56 //
57 //=============================================================================
58 
59 #define NONMANIFOLDVERTEXFIXING_CC
60 
61 //== INCLUDES =================================================================
62 
63 #include "NonManifoldVertexFixingT.hh"
64 
65 //== NAMESPACE ===============================================================
66 
67 
68 //== IMPLEMENTATION ==========================================================
69 
70 
71 template<class MeshT>
73 mesh_(_mesh)
74 {
75 }
76 
77 
78 template<class MeshT>
80 {
81 
83  if ( !mesh_.get_property_handle(component,"component") )
84  mesh_.add_property(component, "component");
85 
86  for (typename MeshT::VertexIter v_iter = mesh_.vertices_begin(); v_iter != mesh_.vertices_end(); ++v_iter)
87  {
88  // unmark all faces
89  for (typename MeshT::VertexFaceIter vf_iter = mesh_.vf_begin(*v_iter); vf_iter.is_valid(); ++vf_iter)
90  mesh_.property(component,*vf_iter) = 0;
91 
92  size_t componentCount = 1;
93 
94 
95  //search and isolate new components
96  //shared vertices will be duplicated
97  for (typename MeshT::VertexFaceIter vf_iter = mesh_.vf_begin(*v_iter); vf_iter.is_valid(); ++vf_iter)
98  {
99  //get the first face in the component
100  std::vector<typename MeshT::FaceHandle> checkNeighbour;
101  if(mesh_.property(component,*vf_iter) == 0)
102  {
103  mesh_.property(component,*vf_iter) = componentCount;
104  checkNeighbour.push_back(*vf_iter);
105  }
106 
107  // if a reference face was found, a new component exists
108  // and a new vertex is required (except for the first component)
109  typename MeshT::VertexHandle v_new;
110  if (componentCount > 1 && !checkNeighbour.empty())
111  {
112  typename MeshT::Point p = mesh_.point(*v_iter);
113  v_new = mesh_.add_vertex(p);
114  }
115 
116  // check all adjacent faces of our reference
117  while(!checkNeighbour.empty())
118  {
119  typename MeshT::FaceHandle face = checkNeighbour.back();
120  checkNeighbour.pop_back();
121 
122  std::vector<typename MeshT::VertexHandle> f_vertices;
123  // get all neighbor faces of face
124  for (typename MeshT::FaceVertexIter fv_iter = mesh_.fv_begin(face); fv_iter.is_valid(); ++fv_iter)
125  {
126  f_vertices.push_back(*fv_iter);
127  if (*fv_iter != *v_iter)
128  {
129  //find the next neighbor face over edge v_iter and fv_iter
130  typename MeshT::FaceHandle nf;
131  for (typename MeshT::VertexFaceIter nf_iter = mesh_.vf_begin(*v_iter); nf_iter.is_valid() && !nf.is_valid(); ++nf_iter)
132  {
133  if (*nf_iter != face)
134  for (typename MeshT::FaceVertexIter nfv_iter = mesh_.fv_begin(*nf_iter); nfv_iter.is_valid() && !nf.is_valid(); ++nfv_iter)
135  if (*nfv_iter == *fv_iter)
136  nf = *nf_iter;
137  }
138 
139  //if such a face was found, it is in the same component as the reference face
140  if (nf.is_valid() && !mesh_.property(component,nf))
141  {
142  mesh_.property(component,nf) = componentCount;
143  checkNeighbour.push_back(nf);
144  }
145  }
146  }
147 
148  //if one face wasn't found in the component = 1 run, then it is a new component, due to split
149  if (componentCount > 1 && v_new.is_valid())
150  {
151  std::replace(f_vertices.begin(),f_vertices.end(),*v_iter,v_new);
152 
153  mesh_.delete_face(face,false);
154  mesh_.add_face(f_vertices);
155 
156  }
157  }
158 
159  // all faces which belong to v_iter and inside same component found
160  // the next face will be in a new component
161  ++componentCount;
162  }
163  }
164 
165  mesh_.remove_property(component);
166  mesh_.garbage_collection();
167 
168 }
Removed non-manifold vertices from a mesh by duplicating them.
VertexHandle add_vertex(const Point &_p)
Alias for new_vertex(const Point&).
Definition: PolyMeshT.hh:236