OpenMesh
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ModRoundnessT.hh
Go to the documentation of this file.
1 /*===========================================================================*\
2  * *
3  * OpenMesh *
4  * Copyright (C) 2001-2011 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: 460 $ *
38  * $Date: 2011-11-16 10:45:08 +0100 (Mi, 16 Nov 2011) $ *
39  * *
40 \*===========================================================================*/
41 
46 //=============================================================================
47 //
48 // CLASS ModRoundnessT
49 //
50 //=============================================================================
51 
52 #ifndef OPENMESH_DECIMATER_MODROUNDNESST_HH
53 #define OPENMESH_DECIMATER_MODROUNDNESST_HH
54 
55 
56 //== INCLUDES =================================================================
57 
59 #include <math.h>
60 
61 #if defined(OM_CC_MSVC)
62 # define OM_ENABLE_WARNINGS 4244
63 # pragma warning(disable : OM_ENABLE_WARNINGS )
64 #endif
65 
66 //== NAMESPACE ================================================================
67 
68 namespace OpenMesh { // BEGIN_NS_OPENMESH
69 namespace Decimater { // BEGIN_NS_DECIMATER
70 
71 
72 //== CLASS DEFINITION =========================================================
73 
74 
83 template <class DecimaterType>
84 class ModRoundnessT : public ModBaseT<DecimaterType>
85 {
86  public:
87  DECIMATING_MODULE( ModRoundnessT, DecimaterType, Roundness );
88 
89  public:
90 
91  // typedefs
92  typedef typename Mesh::Point Point;
93  typedef typename vector_traits<Point>::value_type value_type;
94 
95  public:
96 
98  ModRoundnessT( DecimaterType &_dec ) :
99  Base(_dec, false),
100  min_r_(-1.0)
101  { }
102 
105 
106  public: // inherited
107 
118  float collapse_priority(const CollapseInfo& _ci)
119  {
120  // using namespace OpenMesh;
121 
122  typename Mesh::ConstVertexOHalfedgeIter voh_it(Base::mesh(), _ci.v0);
123  double r;
124  double priority = 0.0; //==LEGAL_COLLAPSE
125  typename Mesh::FaceHandle fhC, fhB;
126  Vec3f B,C;
127 
128  if ( min_r_ < 0.0 ) // continues mode
129  {
130  C = vector_cast<Vec3f>(Base::mesh().point( Base::mesh().to_vertex_handle(voh_it)));
131  fhC = Base::mesh().face_handle( voh_it.handle() );
132 
133  for (++voh_it; voh_it; ++voh_it)
134  {
135  B = C;
136  fhB = fhC;
137  C = vector_cast<Vec3f>(Base::mesh().point(Base::mesh().to_vertex_handle(voh_it)));
138  fhC = Base::mesh().face_handle( voh_it.handle() );
139 
140  if ( fhB == _ci.fl || fhB == _ci.fr )
141  continue;
142 
143  // simulate collapse using position of v1
144  r = roundness( vector_cast<Vec3f>(_ci.p1), B, C );
145 
146  // return the maximum non-roundness
147  priority = std::max( priority, (1.0-r) );
148 
149  }
150  }
151  else // binary mode
152  {
153  C = vector_cast<Vec3f>(Base::mesh().point( Base::mesh().to_vertex_handle(voh_it)));
154  fhC = Base::mesh().face_handle( voh_it.handle() );
155 
156  for (++voh_it; voh_it && (priority==Base::LEGAL_COLLAPSE); ++voh_it)
157  {
158  B = C;
159  fhB = fhC;
160  C = vector_cast<Vec3f>(Base::mesh().point(Base::mesh().to_vertex_handle(voh_it)));
161  fhC = Base::mesh().face_handle( voh_it.handle() );
162 
163  if ( fhB == _ci.fl || fhB == _ci.fr )
164  continue;
165 
166  priority = ( (r=roundness( vector_cast<Vec3f>(_ci.p1), B, C )) < min_r_)
167  ? Base::ILLEGAL_COLLAPSE : Base::LEGAL_COLLAPSE;
168  }
169  }
170 
171  return (float) priority;
172  }
173 
174 
175 
176 public: // specific methods
177 
178  void set_min_angle( float _angle, bool /* _binary=true */ )
179  {
180  assert( _angle > 0 && _angle < 60 );
181 
182  _angle = float(M_PI * _angle /180.0);
183 
184  Vec3f A,B,C;
185 
186  A = Vec3f( 0, 0, 0);
187  B = Vec3f( 2*cos(_angle), 0, 0);
188  C = Vec3f( cos(_angle), sin(_angle), 0);
189 
190  double r1 = roundness(A,B,C);
191 
192  _angle = float(0.5 * ( M_PI - _angle ));
193 
194  A = Vec3f( 0, 0, 0);
195  B = Vec3f( 2*cos(_angle), 0, 0);
196  C = Vec3f( cos(_angle), sin(_angle), 0);
197 
198  double r2 = roundness(A,B,C);
199 
200  set_min_roundness( value_type(std::min(r1,r2)), true );
201  }
202 
210  void set_min_roundness( value_type _min_roundness, bool _binary=true )
211  {
212  assert( 0.0 <= _min_roundness && _min_roundness <= 1.0 );
213  min_r_ = _min_roundness;
214  Base::set_binary(_binary);
215  }
216 
219  {
220  min_r_ = -1.0;
221  Base::set_binary(false);
222  }
223 
224  // Compute a normalized roundness of a triangle ABC
225  //
226  // Having
227  // A,B,C corner points of triangle
228  // a,b,c the vectors BC,CA,AB
229  // Area area of triangle
230  //
231  // then define
232  //
233  // radius of circumference
234  // R := -----------------------
235  // length of shortest edge
236  //
237  // ||a|| * ||b|| * ||c||
238  // ---------------------
239  // 4 * Area ||a|| * ||b|| * ||c||
240  // = ----------------------- = -----------------------------------
241  // min( ||a||,||b||,||c||) 4 * Area * min( ||a||,||b||,||c|| )
242  //
243  // ||a|| * ||b|| * ||c||
244  // = -------------------------------------------------------
245  // 4 * 1/2 * ||cross(B-A,C-A)|| * min( ||a||,||b||,||c|| )
246  //
247  // a'a * b'b * c'c
248  // R� = ----------------------------------------------------------
249  // 4 * cross(B-A,C-A)'cross(B-A,C-A) * min( a'a, b'b, c'c )
250  //
251  // a'a * b'b * c'c
252  // R = 1/2 * sqrt(---------------------------)
253  // AA * min( a'a, b'b, c'c )
254  //
255  // At angle 60� R has it's minimum for all edge lengths = sqrt(1/3)
256  //
257  // Define normalized roundness
258  //
259  // nR := sqrt(1/3) / R
260  //
261  // AA * min( a'a, b'b, c'c )
262  // = sqrt(4/3) * sqrt(---------------------------)
263  // a'a * b'b * c'c
264  //
265  double roundness( const Vec3f& A, const Vec3f& B, const Vec3f &C )
266  {
267  const value_type epsilon = value_type(1e-15);
268 
269  static const value_type sqrt43 = value_type(sqrt(4.0/3.0)); // 60�,a=b=c, **)
270 
271  Vec3f vecAC = C-A;
272  Vec3f vecAB = B-A;
273 
274  // compute squared values to avoid sqrt-computations
275  value_type aa = (B-C).sqrnorm();
276  value_type bb = vecAC.sqrnorm();
277  value_type cc = vecAB.sqrnorm();
278  value_type AA = cross(vecAC,vecAB).sqrnorm(); // without factor 1/4 **)
279 
280  if ( AA < epsilon )
281  return 0.0;
282 
283  double nom = AA * std::min( std::min(aa,bb),cc );
284  double denom = aa * bb * cc;
285  double nR = sqrt43 * sqrt(nom/denom);
286 
287  return nR;
288  }
289 
290  private:
291 
292  value_type min_r_;
293 };
294 
295 
296 //=============================================================================
297 } // END_NS_DECIMATER
298 } // END_NS_OPENMESH
299 //=============================================================================
300 #if defined(OM_CC_MSVC) && defined(OM_ENABLE_WARNINGS)
301 # pragma warning(default : OM_ENABLE_WARNINGS)
302 # undef OM_ENABLE_WARNINGS
303 #endif
304 //=============================================================================
305 #endif // OPENMESH_DECIMATER_MODROUNDNESST_HH defined
306 //=============================================================================
307 

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