ModBaseT.hh 9.87 KB
Newer Older
1
2
3
/*===========================================================================*\
 *                                                                           *
 *                               OpenMesh                                    *
Jan Möbius's avatar
Jan Möbius committed
4
 *      Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen      *
5
6
 *                           www.openmesh.org                                *
 *                                                                           *
7
 *---------------------------------------------------------------------------*
8
9
 *  This file is part of OpenMesh.                                           *
 *                                                                           *
10
 *  OpenMesh is free software: you can redistribute it and/or modify         *
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 *  it under the terms of the GNU Lesser General Public License as           *
 *  published by the Free Software Foundation, either version 3 of           *
 *  the License, or (at your option) any later version with the              *
 *  following exceptions:                                                    *
 *                                                                           *
 *  If other files instantiate templates or use macros                       *
 *  or inline functions from this file, or you compile this file and         *
 *  link it with other files to produce an executable, this file does        *
 *  not by itself cause the resulting executable to be covered by the        *
 *  GNU Lesser General Public License. This exception does not however       *
 *  invalidate any other reasons why the executable file might be            *
 *  covered by the GNU Lesser General Public License.                        *
 *                                                                           *
 *  OpenMesh is distributed in the hope that it will be useful,              *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
 *  GNU Lesser General Public License for more details.                      *
 *                                                                           *
 *  You should have received a copy of the GNU LesserGeneral Public          *
 *  License along with OpenMesh.  If not,                                    *
 *  see <http://www.gnu.org/licenses/>.                                      *
 *                                                                           *
33
\*===========================================================================*/
34
35

/*===========================================================================*\
36
 *                                                                           *
37
38
39
40
 *   $Revision$                                                         *
 *   $Date$                   *
 *                                                                           *
\*===========================================================================*/
Jan Möbius's avatar
Jan Möbius committed
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

/** \file ModBaseT.hh
    Base class for all decimation modules.
 */

//=============================================================================
//
//  CLASS ModBaseT
//
//=============================================================================

#ifndef OPENMESH_DECIMATER_MODBASET_HH
#define OPENMESH_DECIMATER_MODBASET_HH


//== INCLUDES =================================================================

#include <OpenMesh/Core/Utils/Noncopyable.hh>
#include <OpenMesh/Tools/Decimater/CollapseInfoT.hh>
#include <string>


//== NAMESPACE ================================================================

namespace OpenMesh  {
namespace Decimater {


//== FORWARD DECLARATIONS =====================================================

71
template <typename Mesh> class BaseDecimaterT;
Jan Möbius's avatar
Jan Möbius committed
72
73
74
75
76
77
78


//== CLASS DEFINITION =========================================================

/** Handle for mesh decimation modules
    \internal
 */
79

Jan Möbius's avatar
Jan Möbius committed
80
81
82
83
84
85
86
87
88
89
90
template <typename Module>
class ModHandleT : private Utils::Noncopyable
{
public:

  typedef ModHandleT<Module> Self;
  typedef Module module_type;

public:

  /// Default constructor
91
  ModHandleT() : mod_(NULL) {}
Jan Möbius's avatar
Jan Möbius committed
92
93
94

  /// Destructor
  ~ModHandleT() { /* don't delete mod_, since handle is not owner! */ }
95

Jan Möbius's avatar
Jan Möbius committed
96
97
98
99
100
101
102
  /// Check handle status
  /// \return \c true, if handle is valid, else \c false.
  bool is_valid() const { return mod_ != NULL; }

private:

#if defined(OM_CC_MSVC)
103
  friend class BaseDecimaterT;
Jan Möbius's avatar
Jan Möbius committed
104
#else
105
  template <typename Mesh> friend class BaseDecimaterT;
Jan Möbius's avatar
Jan Möbius committed
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#endif

  void     clear()           { mod_ = NULL; }
  void     init(Module* _m)  { mod_ = _m;   }
  Module*  module()          { return mod_; }


private:

  Module* mod_;

};




//== CLASS DEFINITION =========================================================



/// Macro that sets up the name() function
/// \internal
#define DECIMATER_MODNAME(_mod_name) \
 virtual const std::string& name() const { \
  static std::string _s_modname_(#_mod_name); return _s_modname_; \
}


/** Convenience macro, to be used in derived modules
135
 *  The macro defines the types
Jan Möbius's avatar
Jan Möbius committed
136
137
138
139
140
 *  - \c Handle, type of the module's handle.
 *  - \c Base,   type of ModBaseT<>.
 *  - \c Mesh,   type of the associated mesh passed by the decimater type.
 *  - \c CollapseInfo,  to your convenience
 *  and uses DECIMATER_MODNAME() to define the name of the module.
141
 *
Jan Möbius's avatar
Jan Möbius committed
142
 *  \param Classname  The name of the derived class.
Matthias Möller's avatar
Matthias Möller committed
143
 *  \param MeshT      Pass here the mesh type, which is the
Jan Möbius's avatar
Jan Möbius committed
144
145
146
 *                    template parameter passed to ModBaseT.
 *  \param Name       Give the module a name.
 */
147
148
#define DECIMATING_MODULE(Classname, MeshT, Name)	\
  typedef Classname < MeshT >    Self;		\
Jan Möbius's avatar
Jan Möbius committed
149
  typedef OpenMesh::Decimater::ModHandleT< Self >     Handle; \
150
  typedef OpenMesh::Decimater::ModBaseT< MeshT > Base;   \
Jan Möbius's avatar
Jan Möbius committed
151
152
153
154
155
156
157
158
159
160
161
162
  typedef typename Base::Mesh         Mesh;		\
  typedef typename Base::CollapseInfo CollapseInfo;	\
  DECIMATER_MODNAME( Name )



//== CLASS DEFINITION =========================================================


/** Base class for all decimation modules.

    Each module has to implement this interface.
163
    To build your own module you have to
Jan Möbius's avatar
Jan Möbius committed
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
    -# derive from this class.
    -# create the basic settings with DECIMATING_MODULE().
    -# override collapse_priority(), if necessary.
    -# override initialize(), if necessary.
    -# override postprocess_collapse(), if necessary.

    A module has two major working modes:
    -# binary mode
    -# non-binary mode

    In the binary mode collapse_priority() checks a constraint and
    returns LEGAL_COLLAPSE or ILLEGAL_COLLAPSE.

    In the non-binary mode the module computes a float error value in
    the range [0, inf) and returns it. In the case a constraint has
    been set, e.g. the error must be lower than a upper bound, and the
    constraint is violated, collapse_priority() must return
    ILLEGAL_COLLAPSE.

    \see collapse_priority()

    \todo "Tutorial on building a custom decimation module."

*/
188
189

template <typename MeshT>
Jan Möbius's avatar
Jan Möbius committed
190
191
192
class ModBaseT
{
public:
193
194
  typedef MeshT Mesh;
  typedef CollapseInfoT<MeshT>                 CollapseInfo;
Jan Möbius's avatar
Jan Möbius committed
195
196
197
198
199
200
201

  enum {
    ILLEGAL_COLLAPSE = -1, ///< indicates an illegal collapse
    LEGAL_COLLAPSE   = 0   ///< indicates a legal collapse
  };

protected:
202

Jan Möbius's avatar
Jan Möbius committed
203
204
  /// Default constructor
  /// \see \ref decimater_docu
205
  ModBaseT(MeshT& _mesh, bool _is_binary)
206
    : error_tolerance_factor_(1.0), mesh_(_mesh), is_binary_(_is_binary) {}
Jan Möbius's avatar
Jan Möbius committed
207
208
209
210

public:

  /// Virtual desctructor
211
  virtual ~ModBaseT() { }
Jan Möbius's avatar
Jan Möbius committed
212
213
214

  /// Set module's name (using DECIMATER_MODNAME macro)
  DECIMATER_MODNAME(ModBase);
215

Jan Möbius's avatar
Jan Möbius committed
216
217
218
219
220
221
222
223
224

  /// Returns true if criteria returns a binary value.
  bool is_binary(void) const { return is_binary_; }

  /// Set whether module is binary or not.
  void set_binary(bool _b)   { is_binary_ = _b; }


public: // common interface
225

Jan Möbius's avatar
Jan Möbius committed
226
227
228
   /// Initialize module-internal stuff
   virtual void initialize() { }

229
   /** Return collapse priority.
Jan Möbius's avatar
Jan Möbius committed
230
231
232
233
234
235
236
237
238
239
    *
    *  In the binary mode collapse_priority() checks a constraint and
    *  returns LEGAL_COLLAPSE or ILLEGAL_COLLAPSE.
    *
    *  In the non-binary mode the module computes a float error value in
    *  the range [0, inf) and returns it. In the case a constraint has
    *  been set, e.g. the error must be lower than a upper bound, and the
    *  constraint is violated, collapse_priority() must return
    *  ILLEGAL_COLLAPSE.
    *
240
    *  \return Collapse priority in the range [0,inf),
Jan Möbius's avatar
Jan Möbius committed
241
242
    *          \c LEGAL_COLLAPSE or \c ILLEGAL_COLLAPSE.
    */
243
   virtual float collapse_priority(const CollapseInfoT<MeshT>& /* _ci */)
Jan Möbius's avatar
Jan Möbius committed
244
245
   { return LEGAL_COLLAPSE; }

246
247
248
   /** Before _from_vh has been collapsed into _to_vh, this method
       will be called.
    */
249
   virtual void preprocess_collapse(const CollapseInfoT<MeshT>& /* _ci */)
250
251
   {}

Jan Möbius's avatar
Jan Möbius committed
252
   /** After _from_vh has been collapsed into _to_vh, this method
253
       will be called.
Jan Möbius's avatar
Jan Möbius committed
254
    */
255
   virtual void postprocess_collapse(const CollapseInfoT<MeshT>& /* _ci */)
Jan Möbius's avatar
Jan Möbius committed
256
257
   {}

258
259
260
261
262
263
264
265
266
267
268
269
   /**
    * This provides a function that allows the setting of a percentage
    * of the original contraint.
    *
    * Note that the module might need to be re-initialized again after
    * setting the percentage
    * @param factor_ has to be in the closed interval between 0.0 and 1.0
    */
   virtual void set_error_tolerance_factor(double _factor) {
     if (_factor >= 0.0 && _factor <= 1.0)
       error_tolerance_factor_ = _factor;
   }
Jan Möbius's avatar
Jan Möbius committed
270
271
272
273
274


protected:

  /// Access the mesh associated with the decimater.
275
  MeshT& mesh() { return mesh_; }
Jan Möbius's avatar
Jan Möbius committed
276

277
278
279
  // current percentage of the original constraint
  double error_tolerance_factor_;

Jan Möbius's avatar
Jan Möbius committed
280
281
282
283
284
285
private:

  // hide copy constructor & assignemnt
  ModBaseT(const ModBaseT& _cpy);
  ModBaseT& operator=(const ModBaseT& );

286
  MeshT& mesh_;
Jan Möbius's avatar
Jan Möbius committed
287
288
289
290
291
292
293
294
295
296
297
298

  bool is_binary_;
};


//=============================================================================
} // namespace Decimater
} // namespace OpenMesh
//=============================================================================
#endif // OPENMESH_DECIMATER_MODBASE_HH defined
//=============================================================================