ModNormalFlippingT.hh 6.99 KB
Newer Older
1
2
3
/*===========================================================================*\
 *                                                                           *
 *                               OpenMesh                                    *
Jan Möbius's avatar
Jan Möbius committed
4
 *      Copyright (C) 2001-2012 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

/** \file ModNormalFlippingT.hh
43

Jan Möbius's avatar
Jan Möbius committed
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
 */

//=============================================================================
//
//  CLASS ModNormalFlipping
//
//=============================================================================


#ifndef OPENMESH_DECIMATER_MODNORMALFLIPPING_HH
#define OPENMESH_DECIMATER_MODNORMALFLIPPING_HH


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

#include <OpenMesh/Tools/Decimater/ModBaseT.hh>

//== NAMESPACES ===============================================================

namespace OpenMesh { // BEGIN_NS_OPENMESH
namespace Decimater { // BEGIN_NS_DECIMATER


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

/** Decimating module to avoid flipping of faces.
70
 *
Jan Möbius's avatar
Jan Möbius committed
71
72
 *  This module can be used only as a binary module. The criterion
 *  of allowing/disallowing the collapse is the angular deviation between
73
 *  the face normal of the original faces and normals of the faces after the
Jan Möbius's avatar
Jan Möbius committed
74
75
 *  collapse. The collapse will pass the test, if the deviation is below
 *  a given threshold.
76
 */
77
78
template <typename MeshT>
class ModNormalFlippingT : public ModBaseT< MeshT >
79
{
Jan Möbius's avatar
Jan Möbius committed
80
81
public:

82
  DECIMATING_MODULE( ModNormalFlippingT, MeshT, NormalFlipping );
Jan Möbius's avatar
Jan Möbius committed
83
84

public:
85

Jan Möbius's avatar
Jan Möbius committed
86
  /// Constructor
87
  ModNormalFlippingT( MeshT &_mesh) : Base(_mesh, true)
Jan Möbius's avatar
Jan Möbius committed
88
89
90
91
  {
    set_max_normal_deviation( 90.0f );
  }

92
93

  ~ModNormalFlippingT()
Jan Möbius's avatar
Jan Möbius committed
94
  { }
95

Jan Möbius's avatar
Jan Möbius committed
96
97

public:
98

Jan Möbius's avatar
Jan Möbius committed
99
100
101
102
  /** Compute collapse priority due to angular deviation of face normals
   *  before and after a collapse.
   *
   *  -# Compute for each adjacent face of \c _ci.v0 the face
103
   *  normal if the collpase would be executed.
Jan Möbius's avatar
Jan Möbius committed
104
   *
105
106
   *  -# Prevent the collapse, if the cosine of the angle between the
   *     original and the new normal is below a given threshold.
107
   *
Jan Möbius's avatar
Jan Möbius committed
108
109
110
111
112
113
114
115
116
   *  \param _ci The collapse description
   *  \return LEGAL_COLLAPSE or ILLEGAL_COLLAPSE
   *
   *  \see set_max_normal_deviation()
   */
  float collapse_priority(const CollapseInfo& _ci)
  {
    // simulate collapse
    Base::mesh().set_point(_ci.v0, _ci.p1);
117

Jan Möbius's avatar
Jan Möbius committed
118
119
120
121
    // check for flipping normals
    typename Mesh::ConstVertexFaceIter vf_it(Base::mesh(), _ci.v0);
    typename Mesh::FaceHandle          fh;
    typename Mesh::Scalar              c(1.0);
122
123

    for (; vf_it; ++vf_it)
Jan Möbius's avatar
Jan Möbius committed
124
    {
Jan Möbius's avatar
Jan Möbius committed
125
      fh = *vf_it;
Jan Möbius's avatar
Jan Möbius committed
126
127
128
129
130
131
      if (fh != _ci.fl && fh != _ci.fr)
      {
        typename Mesh::Normal n1 = Base::mesh().normal(fh);
        typename Mesh::Normal n2 = Base::mesh().calc_face_normal(fh);

        c = dot(n1, n2);
132

Jan Möbius's avatar
Jan Möbius committed
133
134
135
136
        if (c < min_cos_)
          break;
      }
    }
137

Jan Möbius's avatar
Jan Möbius committed
138
139
140
141
142
143
    // undo simulation changes
    Base::mesh().set_point(_ci.v0, _ci.p0);

    return float( (c < min_cos_) ? Base::ILLEGAL_COLLAPSE : Base::LEGAL_COLLAPSE );
  }

144
145
146
147
148
149
  /// set the percentage of maximum normal deviation
  void set_error_tolerance_factor(double _factor) {
    if (_factor >= 0.0 && _factor <= 1.0) {
      // the smaller the factor, the smaller max_deviation_ gets
      // thus creating a stricter constraint
      // division by error_tolerance_factor_ is for normalization
150
      double max_normal_deviation = (max_deviation_ * 180.0/M_PI) * _factor / this->error_tolerance_factor_;
151
152
153
154
      set_max_normal_deviation(max_normal_deviation);
      this->error_tolerance_factor_ = _factor;
    }
  }
Jan Möbius's avatar
Jan Möbius committed
155
156
157


public:
158

Jan Möbius's avatar
Jan Möbius committed
159
  /// get normal deviation
160
  double max_normal_deviation() const { return max_deviation_ / M_PI * 180.0; }
161

Jan Möbius's avatar
Jan Möbius committed
162
  /** Set normal deviation
163
   *
Jan Möbius's avatar
Jan Möbius committed
164
165
166
   *  Set the maximum angular deviation of the orignal normal and the new
   *  normal in degrees.
   */
167
168
  void set_max_normal_deviation(double _d) {
    max_deviation_ = _d / 180.0 * M_PI;
Jan Möbius's avatar
Jan Möbius committed
169
170
    min_cos_       = cos(max_deviation_);
  }
171

Jan Möbius's avatar
Jan Möbius committed
172
173
174
175
private:

  // hide this method
  void set_binary(bool _b) {}
176

Jan Möbius's avatar
Jan Möbius committed
177
178
179
180
181
182
183
184
185
186
187
188
189
190
private:

  // maximum normal deviation
  double max_deviation_, min_cos_;
};


//=============================================================================
} // END_NS_DECIMATER
} // END_NS_OPENMESH
//=============================================================================
#endif // OPENACG_MODNORMALFLIPPING_HH defined
//=============================================================================