OpenMesh
 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 
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;
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 
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_;
240 };
241 
242 
243 //=============================================================================
244 } // END_NS_DECIMATER
245 } // END_NS_OPENMESH
246 //=============================================================================
247 #endif // OPENMESH_DECIMATER_MODNORMALDEVIATIONT_HH defined
248 //=============================================================================
249 

acg pic Project OpenMesh, ©  Computer Graphics Group, RWTH Aachen. Documentation generated using doxygen .