ModAspectRatioT_impl.hh 7.92 KB
Newer Older
Jan Möbius's avatar
Jan Möbius committed
1
/* ========================================================================= *
Isaak Lim's avatar
Isaak Lim committed
2 3
 *                                                                           *
 *                               OpenMesh                                    *
Jan Möbius's avatar
Jan Möbius committed
4
 *           Copyright (c) 2001-2015, RWTH-Aachen University                 *
Jan Möbius's avatar
Typo  
Jan Möbius committed
5
 *           Department of Computer Graphics and Multimedia                  *
Jan Möbius's avatar
Jan Möbius committed
6 7
 *                          All rights reserved.                             *
 *                            www.openmesh.org                               *
Isaak Lim's avatar
Isaak Lim committed
8 9
 *                                                                           *
 *---------------------------------------------------------------------------*
Jan Möbius's avatar
Jan Möbius committed
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
 * This file is part of OpenMesh.                                            *
 *---------------------------------------------------------------------------*
 *                                                                           *
 * Redistribution and use in source and binary forms, with or without        *
 * modification, are permitted provided that the following conditions        *
 * are met:                                                                  *
 *                                                                           *
 * 1. Redistributions of source code must retain the above copyright notice, *
 *    this list of conditions and the following disclaimer.                  *
 *                                                                           *
 * 2. Redistributions in binary form must reproduce the above copyright      *
 *    notice, this list of conditions and the following disclaimer in the    *
 *    documentation and/or other materials provided with the distribution.   *
 *                                                                           *
 * 3. Neither the name of the copyright holder nor the names of its          *
 *    contributors may be used to endorse or promote products derived from   *
 *    this software without specific prior written permission.               *
 *                                                                           *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       *
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A           *
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  *
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,       *
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR        *
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    *
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      *
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        *
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              *
Jan Möbius's avatar
Jan Möbius committed
39 40
 *                                                                           *
 * ========================================================================= */
Isaak Lim's avatar
Isaak Lim committed
41 42


43
/** \file ModAspectRatioT_impl.hh
Isaak Lim's avatar
Isaak Lim committed
44 45 46 47 48 49 50
 */

//=============================================================================
//
//  CLASS ModAspectRatioT - IMPLEMENTATION
//
//=============================================================================
51
#define OPENMESH_DECIMATER_MODASPECTRATIOT_C
Isaak Lim's avatar
Isaak Lim committed
52 53 54 55 56 57 58

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

#include "ModAspectRatioT.hh"

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

59
namespace OpenMesh {
Isaak Lim's avatar
Isaak Lim committed
60 61 62 63
namespace Decimater {

//== IMPLEMENTATION ==========================================================

64 65
template<class MeshT>
typename ModAspectRatioT<MeshT>::Scalar ModAspectRatioT<MeshT>::aspectRatio(
66
    const Point& _v0, const Point& _v1, const Point& _v2) {
Isaak Lim's avatar
Isaak Lim committed
67 68 69 70 71
  Point d0 = _v0 - _v1;
  Point d1 = _v1 - _v2;

  // finds the max squared edge length
  Scalar l2, maxl2 = d0.sqrnorm();
72
  if ((l2 = d1.sqrnorm()) > maxl2)
Isaak Lim's avatar
Isaak Lim committed
73 74 75
    maxl2 = l2;
  // keep searching for the max squared edge length
  d1 = _v2 - _v0;
76
  if ((l2 = d1.sqrnorm()) > maxl2)
Isaak Lim's avatar
Isaak Lim committed
77 78 79 80 81 82 83 84 85 86 87 88 89
    maxl2 = l2;

  // squared area of the parallelogram spanned by d0 and d1
  Scalar a2 = (d0 % d1).sqrnorm();

  // the area of the triangle would be
  // sqrt(a2)/2 or length * height / 2
  // aspect ratio = length / height
  //              = length * length / (2*area)
  //              = length * length / sqrt(a2)

  // returns the length of the longest edge
  //         divided by its corresponding height
90
  return sqrt((maxl2 * maxl2) / a2);
Isaak Lim's avatar
Isaak Lim committed
91 92 93 94
}

//-----------------------------------------------------------------------------

95 96
template<class MeshT>
void ModAspectRatioT<MeshT>::initialize() {
97 98
  typename Mesh::FaceIter f_it, f_end(mesh_.faces_end());
  typename Mesh::FVIter fv_it;
Isaak Lim's avatar
Isaak Lim committed
99

100
  for (f_it = mesh_.faces_begin(); f_it != f_end; ++f_it) {
Jan Möbius's avatar
Jan Möbius committed
101 102 103 104
    fv_it = mesh_.fv_iter(*f_it);
    typename Mesh::Point& p0 = mesh_.point(*fv_it);
    typename Mesh::Point& p1 = mesh_.point(*(++fv_it));
    typename Mesh::Point& p2 = mesh_.point(*(++fv_it));
Isaak Lim's avatar
Isaak Lim committed
105

Jan Möbius's avatar
Jan Möbius committed
106
    mesh_.property(aspect_, *f_it) = static_cast<typename Mesh::Scalar>(1.0) / aspectRatio(p0, p1, p2);
Isaak Lim's avatar
Isaak Lim committed
107 108 109 110 111
  }
}

//-----------------------------------------------------------------------------

112 113
template<class MeshT>
void ModAspectRatioT<MeshT>::preprocess_collapse(const CollapseInfo& _ci) {
114 115
  typename Mesh::FaceHandle fh;
  typename Mesh::FVIter fv_it;
Isaak Lim's avatar
Isaak Lim committed
116

Jan Möbius's avatar
Jan Möbius committed
117
  for (typename Mesh::VFIter vf_it = mesh_.vf_iter(_ci.v0); vf_it.is_valid(); ++vf_it) {
Jan Möbius's avatar
Jan Möbius committed
118
    fh = *vf_it;
119
    if (fh != _ci.fl && fh != _ci.fr) {
Jan Möbius's avatar
Jan Möbius committed
120 121 122 123
      fv_it = mesh_.fv_iter(fh);
      typename Mesh::Point& p0 = mesh_.point(*fv_it);
      typename Mesh::Point& p1 = mesh_.point(*(++fv_it));
      typename Mesh::Point& p2 = mesh_.point(*(++fv_it));
Isaak Lim's avatar
Isaak Lim committed
124

Jan Möbius's avatar
Jan Möbius committed
125
      mesh_.property(aspect_, fh) = static_cast<typename Mesh::Scalar>(1.0) / aspectRatio(p0, p1, p2);
Isaak Lim's avatar
Isaak Lim committed
126 127 128 129 130 131
    }
  }
}

//-----------------------------------------------------------------------------

132 133
template<class MeshT>
float ModAspectRatioT<MeshT>::collapse_priority(const CollapseInfo& _ci) {
134 135 136 137
  typename Mesh::VertexHandle v2, v3;
  typename Mesh::FaceHandle fh;
  const typename Mesh::Point *p1(&_ci.p1), *p2, *p3;
  typename Mesh::Scalar r0, r1, r0_min(1.0), r1_min(1.0);
138
  typename Mesh::ConstVertexOHalfedgeIter voh_it(mesh_, _ci.v0);
Isaak Lim's avatar
Isaak Lim committed
139

140
  v3 = mesh_.to_vertex_handle(*voh_it);
141
  p3 = &mesh_.point(v3);
Isaak Lim's avatar
Isaak Lim committed
142

143
  while (voh_it.is_valid()) {
Isaak Lim's avatar
Isaak Lim committed
144 145 146
    v2 = v3;
    p2 = p3;

147 148
    ++voh_it;
    v3 = mesh_.to_vertex_handle(*voh_it);
Isaak Lim's avatar
Isaak Lim committed
149 150
    p3 = &mesh_.point(v3);

151
    fh = mesh_.face_handle(*voh_it);
Isaak Lim's avatar
Isaak Lim committed
152 153

    // if not boundary
154 155 156 157
    if (fh.is_valid()) {
      // aspect before
      if ((r0 = mesh_.property(aspect_, fh)) < r0_min)
        r0_min = r0;
Isaak Lim's avatar
Isaak Lim committed
158

159
      // aspect after
Isaak Lim's avatar
Isaak Lim committed
160
      if (!(v2 == _ci.v1 || v3 == _ci.v1))
Jan Möbius's avatar
Jan Möbius committed
161
        if ((r1 = static_cast<typename Mesh::Scalar>(1.0) / aspectRatio(*p1, *p2, *p3)) < r1_min)
162
          r1_min = r1;
Isaak Lim's avatar
Isaak Lim committed
163 164 165
    }
  }

166 167
  if (Base::is_binary()) {
    return
168 169
        ((r1_min > r0_min) || (r1_min > min_aspect_)) ? float(Base::LEGAL_COLLAPSE) :
            float(Base::ILLEGAL_COLLAPSE);
Isaak Lim's avatar
Isaak Lim committed
170

171
  } else {
Isaak Lim's avatar
Isaak Lim committed
172
    if (r1_min > r0_min)
173
      return 1.f - float(r1_min);
174 175
    else
      return
176
          (r1_min > min_aspect_) ? 2.f - float(r1_min) : float(Base::ILLEGAL_COLLAPSE);
Isaak Lim's avatar
Isaak Lim committed
177 178 179
  }
}

180 181 182 183 184 185 186 187
//-----------------------------------------------------------------------------

template<class MeshT>
void ModAspectRatioT<MeshT>::set_error_tolerance_factor(double _factor) {
  if (_factor >= 0.0 && _factor <= 1.0) {
    // the smaller the factor, the larger min_aspect_ gets
    // thus creating a stricter constraint
    // division by (2.0 - error_tolerance_factor_) is for normalization
188 189
    float min_aspect = min_aspect_ * (2.f - float(_factor)) / (2.f - float(this->error_tolerance_factor_));
    set_aspect_ratio(1.f/min_aspect);
190 191 192 193
    this->error_tolerance_factor_ = _factor;
  }
}

Isaak Lim's avatar
Isaak Lim committed
194 195 196 197
//=============================================================================
}
}
//=============================================================================