Developer Documentation
MixedDecimaterT_impl.hh
Go to the documentation of this file.
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.openmesh.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenMesh. *
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 
46 //=============================================================================
47 //
48 // CLASS MixedDecimaterT - IMPLEMENTATION
49 //
50 //=============================================================================
51 #define OPENMESH_MIXED_DECIMATER_DECIMATERT_CC
52 
53 //== INCLUDES =================================================================
54 
56 
57 #include <vector>
58 #if defined(OM_CC_MIPS)
59 # include <float.h>
60 #else
61 # include <cfloat>
62 #endif
63 
64 //== NAMESPACE ===============================================================
65 namespace OpenMesh {
66 namespace Decimater {
67 
68 //== IMPLEMENTATION ==========================================================
69 
70 template<class Mesh>
72  BaseDecimaterT<Mesh>(_mesh),McDecimaterT<Mesh>(_mesh), DecimaterT<Mesh>(_mesh) {
73 
74 }
75 
76 //-----------------------------------------------------------------------------
77 
78 template<class Mesh>
80 
81 }
82 
83 //-----------------------------------------------------------------------------
84 template<class Mesh>
85 size_t MixedDecimaterT<Mesh>::decimate(const size_t _n_collapses, const float _mc_factor) {
86 
87  if (_mc_factor > 1.0)
88  return 0;
89 
90  size_t n_collapses_mc = static_cast<size_t>(_mc_factor*_n_collapses);
91  size_t n_collapses_inc = static_cast<size_t>(_n_collapses - n_collapses_mc);
92 
93  size_t r_collapses = 0;
94  if (_mc_factor > 0.0)
95  r_collapses = McDecimaterT<Mesh>::decimate(n_collapses_mc);
96 
97  // returns, if the previous steps were aborted by the observer
98  if (this->observer() && this->observer()->abort())
99  return r_collapses;
100 
101  if (_mc_factor < 1.0)
102  r_collapses += DecimaterT<Mesh>::decimate(n_collapses_inc);
103 
104  return r_collapses;
105 
106 }
107 
108 template<class Mesh>
109 size_t MixedDecimaterT<Mesh>::decimate_to_faces(const size_t _n_vertices,const size_t _n_faces, const float _mc_factor ){
110 
111  if (_mc_factor > 1.0)
112  return 0;
113 
114  std::size_t r_collapses = 0;
115  if (_mc_factor > 0.0)
116  {
117  bool constraintsOnly = (_n_vertices == 0) && (_n_faces == 1);
118  if (!constraintsOnly) {
119  size_t mesh_faces = this->mesh().n_faces();
120  size_t mesh_vertices = this->mesh().n_vertices();
121  //reduce the mesh only for _mc_factor
122  size_t n_vertices_mc = static_cast<size_t>(mesh_vertices - _mc_factor * (mesh_vertices - _n_vertices));
123  size_t n_faces_mc = static_cast<size_t>(mesh_faces - _mc_factor * (mesh_faces - _n_faces));
124 
125  r_collapses = McDecimaterT<Mesh>::decimate_to_faces(n_vertices_mc, n_faces_mc);
126  } else {
127 
128  const size_t samples = this->samples();
129 
130  // MinimalSample count for the McDecimater
131  const size_t min = 2;
132 
133  // Maximal number of samples for the McDecimater
134  const size_t max = samples;
135 
136  // Number of incremental steps
137  const size_t steps = 7;
138 
139  for ( size_t i = 0; i < steps; ++i ) {
140 
141  // Compute number of samples to be used
142  size_t samples = int (double( min) + double(i)/(double(steps)-1.0) * (max-2) ) ;
143 
144  // We won't allow 1 here, as this is the last step in the incremental part
145  float decimaterLevel = (float(i + 1)) * _mc_factor / (float(steps) );
146 
147  this->set_samples(samples);
148  r_collapses += McDecimaterT<Mesh>::decimate_constraints_only(decimaterLevel);
149  }
150  }
151  }
152 
153  //Update the mesh::n_vertices function, otherwise the next Decimater function will delete too much
154  this->mesh().garbage_collection();
155 
156  // returns, if the previous steps were aborted by the observer
157  if (this->observer() && this->observer()->abort())
158  return r_collapses;
159 
160  //reduce the rest of the mesh
161  if (_mc_factor < 1.0) {
162  r_collapses += DecimaterT<Mesh>::decimate_to_faces(_n_vertices,_n_faces);
163  }
164 
165 
166  return r_collapses;
167 }
168 
169 //=============================================================================
170 }// END_NS_MC_DECIMATER
171 } // END_NS_OPENMESH
172 //=============================================================================
size_t decimate(size_t _n_collapses=0)
Perform a number of collapses on the mesh.
Observer * observer()
Get current observer of a decimater.
size_t decimate_to_faces(const size_t _n_vertices=0, const size_t _n_faces=0, const float _mc_factor=0.8)
size_t decimate_to_faces(size_t _n_vertices=0, size_t _n_faces=0)
size_t decimate_to_faces(size_t _n_vertices=0, size_t _n_faces=0)
Attempts to decimate the mesh until a desired vertex or face complexity is achieved.
Mesh & mesh()
access mesh. used in modules.
size_t decimate(size_t _n_collapses)
MixedDecimaterT(Mesh &_mesh)
Constructor.
size_t decimate(const size_t _n_collapses, const float _mc_factor)
size_t decimate_constraints_only(float _factor)