Developer Documentation

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
MeshRepairPluginT.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
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 * $LastChangedBy$ *
46 * $Date$ *
47 * *
48 \*===========================================================================*/
49
50 #define MESHREPAIRPLUGINT_CC
51
52 #include "MeshRepairPlugin.hh"
53
54 //-----------------------------------------------------------------------------
55
56 template<typename MeshT>
57 void MeshRepairPlugin::flipOrientation(MeshT& _mesh)
58 {
59
60
61 std::vector< unsigned int > valence;
62 std::vector< typename MeshT::VertexHandle > vhandles;
63
64
65
66 bool selected = false;
67
68 // Check if a face is selected
69 for (typename MeshT::FaceIter f_it = _mesh.faces_begin(); f_it != _mesh.faces_end() ; ++f_it)
70 if ( _mesh.status(*f_it).selected() ) {
71 selected = true;
72 break;
73 }
74
75 // Two ways to go
76 // if something is selected, we have to duplicate some vertices in order to get a manifold mesh
77 if ( selected ) {
78
79 // Tag all vertices adjacent to selected faces
80 for (typename MeshT::VertexIter v_it = _mesh.vertices_begin(); v_it != _mesh.vertices_end(); ++v_it) {
81
82 bool tagged = false;
83
84 for (typename MeshT::VertexFaceIter vf_it = _mesh.vf_iter(*v_it); !tagged && vf_it.is_valid(); ++vf_it)
85 if (_mesh.status(*vf_it).selected())
86 tagged = true;
87
88 _mesh.status(*v_it).set_tagged(tagged);
89 }
90
91 // Remember the vertex mapping for the duplication
92 OpenMesh::VPropHandleT< typename MeshT::VHandle> vmap;
93 _mesh.add_property(vmap);
94
95 // duplicate vertices that are incident to tagged and un-tagged faces
96 for (typename MeshT::VertexIter v_it = _mesh.vertices_begin(); v_it != _mesh.vertices_end(); ++v_it) {
97
98 typename MeshT::VertexHandle vh = *v_it;
99
100 if (_mesh.status(*v_it).tagged() )
101 for (typename MeshT::VertexFaceIter vf_it = _mesh.vf_iter(*v_it); vf_it.is_valid(); ++vf_it)
102
103 if (!_mesh.status(*vf_it).tagged()) {
104
105 typename MeshT::Point tmpPoint = _mesh.point(*v_it);
106
107 // Duplicate the vertex
108 vh = _mesh.add_vertex( tmpPoint );
109
110 // The next vertex should be tagged
111 _mesh.status(vh).set_tagged(true);
112
113 // The original vertex is already duplicated, so we don't need to do it again!
114 _mesh.status(*v_it).set_tagged(false);
115 break;
116 }
117
118 _mesh.property(vmap, *v_it) = vh;
119 }
120
121 // Delete the old faces and collect their information
122 for (typename MeshT::FaceIter f_it = _mesh.faces_begin(); f_it != _mesh.faces_end(); ++f_it) {
123
124 if (_mesh.status(*f_it).selected()) {
125
126 // Collect vertex handles
127 typename MeshT::FaceVertexIter fv_it = _mesh.fv_iter(*f_it);
128
129 valence.push_back(_mesh.valence(*f_it));
130 while (fv_it.is_valid()) {
131 vhandles.push_back(*fv_it);
132 ++fv_it;
133 }
134
135 // delete the corresponding face
136 _mesh.delete_face(*f_it, false);
137 }
138
139 }
140
141 // Rebuild the faces in the opposite order
142 std::size_t pos = 0;
143 for (std::size_t i = 0; i < valence.size(); i++) {
144
145 std::vector<typename MeshT::VertexHandle> faceVertices;
146
147 pos += valence[i];
148
149 // add valence vertices in the inverse order
150 for (unsigned int j = 1; j <= valence[i]; ++j)
151 faceVertices.push_back(_mesh.property(vmap,vhandles[pos - j]) );
152
153 _mesh.add_face(faceVertices);
154 }
155
156 _mesh.remove_property(vmap);
157
158 } else {
159
160 std::vector < typename MeshT::Point > points;
161
162 // store vertices
163 points.reserve(_mesh.n_vertices() );
164 for (typename MeshT::VertexIter v_it = _mesh.vertices_begin(); v_it != _mesh.vertices_end(); ++v_it)
165 points.push_back(_mesh.point(*v_it));
166
167 // Better approximation of vector size for storing the handles
168 const unsigned int n_VerticesPerFace = _mesh.is_trimesh() ? 3 : 4;
169
170 // Remember vertex handles for each face and its valence
171 std::vector< typename MeshT::VertexHandle > vhandles;
172 vhandles.reserve( _mesh.n_faces() * n_VerticesPerFace);
173 for (typename MeshT::FaceIter f_it = _mesh.faces_begin(); f_it != _mesh.faces_end(); ++f_it) {
174
175 valence.push_back( _mesh.valence(*f_it) );
176
177 for (typename MeshT::FaceVertexIter fv_it = _mesh.fv_iter(*f_it); fv_it.is_valid(); ++fv_it)
178 vhandles.push_back(*fv_it);
179 }
180
181 // Remove all entities from the mesh
182 _mesh.clean();
183
184 // Restore vertices
185 for (unsigned int i = 0; i < points.size(); ++i)
186 _mesh.add_vertex(points[i]);
187
188
189 // Add back the faces
190 std::size_t pos = 0;
191 for (std::size_t i = 0; i < valence.size(); i++) {
192
193 std::vector<typename MeshT::VertexHandle> faceVertices;
194
195 pos += valence[i];
196
197 // add valence vertices in the inverse order
198 for (unsigned int j = 1; j <= valence[i]; ++j)
199 faceVertices.push_back(vhandles[pos - j]);
200
201 _mesh.add_face(faceVertices);
202 }
203
204 }
205
206
207 _mesh.garbage_collection();
208 _mesh.update_normals();
209 }
210
211 //-----------------------------------------------------------------------------
212
MeshRepairPlugin::flipOrientation
void flipOrientation(int _objectId)
Flips the normals of all selected faces by changing the vertex order.
Definition: FaceFunctions.cc:106
OpenMesh::VPropHandleT
Definition: Property.hh:487