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