OpenMesh

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

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ModNormalDeviationT.hh
Go to the documentation of this file.
1 /*===========================================================================*\
2 * *
3 * OpenMesh *
4 * Copyright (C) 2001-2012 by Computer Graphics Group, RWTH Aachen *
5 * www.openmesh.org *
6 * *
7 *---------------------------------------------------------------------------*
8 * This file is part of OpenMesh. *
9 * *
10 * OpenMesh is free software: you can redistribute it and/or modify *
11 * it under the terms of the GNU Lesser General Public License as *
12 * published by the Free Software Foundation, either version 3 of *
13 * the License, or (at your option) any later version with the *
14 * following exceptions: *
15 * *
16 * If other files instantiate templates or use macros *
17 * or inline functions from this file, or you compile this file and *
18 * link it with other files to produce an executable, this file does *
19 * not by itself cause the resulting executable to be covered by the *
20 * GNU Lesser General Public License. This exception does not however *
21 * invalidate any other reasons why the executable file might be *
22 * covered by the GNU Lesser General Public License. *
23 * *
24 * OpenMesh is distributed in the hope that it will be useful, *
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
27 * GNU Lesser General Public License for more details. *
28 * *
29 * You should have received a copy of the GNU LesserGeneral Public *
30 * License along with OpenMesh. If not, *
31 * see <http://www.gnu.org/licenses/>. *
32 * *
33 \*===========================================================================*/
34
35 /*===========================================================================*\
36 * *
37 * $Revision: 737 $ *
38 * $Date: 2012-10-08 09:33:20 +0200 (Mo, 08 Okt 2012) $ *
39 * *
40 \*===========================================================================*/
41
45 //=============================================================================
46 //
47 // CLASS ModNormalDeviationT
48 //
49 //=============================================================================
50
51
52 #ifndef OPENMESH_DECIMATER_MODNORMALDEVIATIONT_HH
53 #define OPENMESH_DECIMATER_MODNORMALDEVIATIONT_HH
54
55
56 //== INCLUDES =================================================================
57
58 #include <OpenMesh/Tools/Decimater/ModBaseT.hh>
59 #include <OpenMesh/Core/Utils/Property.hh>
60 #include <OpenMesh/Core/Geometry/NormalConeT.hh>
61
62
63 //== NAMESPACES ===============================================================
64
65 namespace OpenMesh {
66 namespace Decimater {
67
68
69 //== CLASS DEFINITION =========================================================
70
71
86 template <class MeshT>
87 class ModNormalDeviationT : public ModBaseT< MeshT >
88 {
89 public:
90
91 DECIMATING_MODULE( ModNormalDeviationT, MeshT, NormalDeviation );
92
93 typedef typename Mesh::Scalar Scalar;
94 typedef typename Mesh::Point Point;
95 typedef typename Mesh::Normal Normal;
96 typedef typename Mesh::VertexHandle VertexHandle;
97 typedef typename Mesh::FaceHandle FaceHandle;
98 typedef typename Mesh::EdgeHandle EdgeHandle;
99 typedef NormalConeT<Scalar> NormalCone;
100
101
102
103 public:
104
106 ModNormalDeviationT(MeshT& _mesh, float _max_dev = 180.0)
107 : Base(_mesh, true), mesh_(Base::mesh())
108 {
109 set_normal_deviation(_max_dev);
110 mesh_.add_property(normal_cones_);
111 }
112
113
115 ~ModNormalDeviationT() {
116 mesh_.add_property(normal_cones_);
117 }
118
119
121 Scalar normal_deviation() const {
122 return normal_deviation_ / M_PI * 180.0;
123 }
124
126 void set_normal_deviation(Scalar _s) {
127 normal_deviation_ = _s / 180.0 * M_PI;
128 }
129
130
132 void initialize() {
133 if (!normal_cones_.is_valid())
134 mesh_.add_property(normal_cones_);
135
136 typename Mesh::FaceIter f_it = mesh_.faces_begin(),
137 f_end = mesh_.faces_end();
138
139 for (; f_it != f_end; ++f_it)
140 mesh_.property(normal_cones_, f_it) = NormalCone(mesh_.normal(f_it));
141 }
142
157 float collapse_priority(const CollapseInfo& _ci) {
158 // simulate collapse
159 mesh_.set_point(_ci.v0, _ci.p1);
160
161
162 typename Mesh::Scalar max_angle(0.0);
163 typename Mesh::ConstVertexFaceIter vf_it(mesh_, _ci.v0);
164 typename Mesh::FaceHandle fh, fhl, fhr;
165
166 if (_ci.v0vl.is_valid()) fhl = mesh_.face_handle(_ci.v0vl);
167 if (_ci.vrv0.is_valid()) fhr = mesh_.face_handle(_ci.vrv0);
168
169 for (; vf_it; ++vf_it) {
170 fh = vf_it.handle();
171 if (fh != _ci.fl && fh != _ci.fr) {
172 NormalCone nc = mesh_.property(normal_cones_, fh);
173
174 nc.merge(NormalCone(mesh_.calc_face_normal(fh)));
175 if (fh == fhl) nc.merge(mesh_.property(normal_cones_, _ci.fl));
176 if (fh == fhr) nc.merge(mesh_.property(normal_cones_, _ci.fr));
177
178 if (nc.angle() > max_angle) {
179 max_angle = nc.angle();
180 if (max_angle > 0.5 * normal_deviation_)
181 break;
182 }
183 }
184 }
185
186
187 // undo simulation changes
188 mesh_.set_point(_ci.v0, _ci.p0);
189
190
191 return (max_angle < 0.5 * normal_deviation_ ? max_angle : float( Base::ILLEGAL_COLLAPSE ));
192 }
193
195 void set_error_tolerance_factor(double _factor) {
196 if (_factor >= 0.0 && _factor <= 1.0) {
197 // the smaller the factor, the smaller normal_deviation_ gets
198 // thus creating a stricter constraint
199 // division by error_tolerance_factor_ is for normalization
200 Scalar normal_deviation = (normal_deviation_ * 180.0/M_PI) * _factor / this->error_tolerance_factor_;
201 set_normal_deviation(normal_deviation);
202 this->error_tolerance_factor_ = _factor;
203 }
204 }
205
206
207 void postprocess_collapse(const CollapseInfo& _ci) {
208 // account for changed normals
209 typename Mesh::VertexFaceIter vf_it(mesh_, _ci.v1);
210 for (; vf_it; ++vf_it)
211 mesh_.property(normal_cones_, vf_it).
212 merge(NormalCone(mesh_.normal(vf_it)));
213
214
215 // normal cones of deleted triangles
216 typename Mesh::FaceHandle fh;
217
218 if (_ci.vlv1.is_valid()) {
219 fh = mesh_.face_handle(mesh_.opposite_halfedge_handle(_ci.vlv1));
220 if (fh.is_valid())
221 mesh_.property(normal_cones_, fh).
222 merge(mesh_.property(normal_cones_, _ci.fl));
223 }
224
225 if (_ci.v1vr.is_valid()) {
226 fh = mesh_.face_handle(mesh_.opposite_halfedge_handle(_ci.v1vr));
227 if (fh.is_valid())
228 mesh_.property(normal_cones_, fh).
229 merge(mesh_.property(normal_cones_, _ci.fr));
230 }
231 }
232
233
234
235 private:
236
237 Mesh& mesh_;
238 Scalar normal_deviation_;
239 OpenMesh::FPropHandleT<NormalCone> normal_cones_;
240 };
241
242
243 //=============================================================================
244 } // END_NS_DECIMATER
245 } // END_NS_OPENMESH
246 //=============================================================================
247 #endif // OPENMESH_DECIMATER_MODNORMALDEVIATIONT_HH defined
248 //=============================================================================
249