JacobiLaplaceSmootherT_impl.hh 7.44 KB
Newer Older
Jan Möbius's avatar
Jan Möbius committed
1
/* ========================================================================= *
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 8 9 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
 *                          All rights reserved.                             *
 *                            www.openmesh.org                               *
 *                                                                           *
 *---------------------------------------------------------------------------*
 * 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
 *                                                                           *
 * ========================================================================= */
41

42

Jan Möbius's avatar
Jan Möbius committed
43

44
/** \file JacobiLaplaceSmootherT_impl.hh
Jan Möbius's avatar
Jan Möbius committed
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 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
    
 */

//=============================================================================
//
//  CLASS JacobiLaplaceSmootherT - IMPLEMENTATION
//
//=============================================================================

#define OPENMESH_JACOBI_LAPLACE_SMOOTHERT_C

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

#include <OpenMesh/Tools/Smoother/JacobiLaplaceSmootherT.hh>


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


namespace OpenMesh {
namespace Smoother {


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


template <class Mesh>
void
JacobiLaplaceSmootherT<Mesh>::
smooth(unsigned int _n)
{
  if (Base::continuity() > Base::C0)
  {
    Base::mesh_.add_property(umbrellas_);
    if (Base::continuity() > Base::C1)
      Base::mesh_.add_property(squared_umbrellas_);
  }

  LaplaceSmootherT<Mesh>::smooth(_n);

  if (Base::continuity() > Base::C0)
  {
    Base::mesh_.remove_property(umbrellas_);
    if (Base::continuity() > Base::C1)
      Base::mesh_.remove_property(squared_umbrellas_);
  }
}


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


template <class Mesh>
void
JacobiLaplaceSmootherT<Mesh>::
compute_new_positions_C0()
{
102 103 104 105
  typename Mesh::VertexIter  							v_it, v_end(Base::mesh_.vertices_end());
  typename Mesh::ConstVertexOHalfedgeIter voh_it;
  typename Mesh::Normal      							u, p, zero(0,0,0);
  typename Mesh::Scalar      							w;
Jan Möbius's avatar
Jan Möbius committed
106 107 108

  for (v_it=Base::mesh_.vertices_begin(); v_it!=v_end; ++v_it)
  {
Jan Möbius's avatar
Jan Möbius committed
109
    if (this->is_active(*v_it))
Jan Möbius's avatar
Jan Möbius committed
110 111 112
    {
      // compute umbrella
      u = zero;
113 114 115
      for (voh_it = Base::mesh_.cvoh_iter(*v_it); voh_it.is_valid(); ++voh_it) {
        w = this->weight(Base::mesh_.edge_handle(*voh_it));
        u += vector_cast<typename Mesh::Normal>(Base::mesh_.point(Base::mesh_.to_vertex_handle(*voh_it))) * w;
Jan Möbius's avatar
Jan Möbius committed
116
      }
Jan Möbius's avatar
Jan Möbius committed
117
      u *= this->weight(*v_it);
Jan Möbius's avatar
Jan Möbius committed
118
      u -= vector_cast<typename Mesh::Normal>(Base::mesh_.point(*v_it));
Jan Möbius's avatar
Jan Möbius committed
119 120

      // damping
Jan Möbius's avatar
Jan Möbius committed
121
      u *= static_cast< typename Mesh::Scalar >(0.5);
Jan Möbius's avatar
Jan Möbius committed
122 123
    
      // store new position
Jan Möbius's avatar
Jan Möbius committed
124
      p  = vector_cast<typename Mesh::Normal>(Base::mesh_.point(*v_it));
Jan Möbius's avatar
Jan Möbius committed
125
      p += u;
Jan Möbius's avatar
Jan Möbius committed
126
      this->set_new_position(*v_it, p);
Jan Möbius's avatar
Jan Möbius committed
127 128 129 130 131 132 133 134 135 136 137 138 139
    }
  }
}


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


template <class Mesh>
void
JacobiLaplaceSmootherT<Mesh>::
compute_new_positions_C1()
{
140 141 142 143
  typename Mesh::VertexIter  							v_it, v_end(Base::mesh_.vertices_end());
  typename Mesh::ConstVertexOHalfedgeIter voh_it;
  typename Mesh::Normal      							u, uu, p, zero(0,0,0);
  typename Mesh::Scalar      							w, diag;
Jan Möbius's avatar
Jan Möbius committed
144 145 146 147 148 149


  // 1st pass: compute umbrellas
  for (v_it=Base::mesh_.vertices_begin(); v_it!=v_end; ++v_it)
  {
    u = zero;
150 151 152
    for (voh_it = Base::mesh_.cvoh_iter(*v_it); voh_it.is_valid(); ++voh_it) {
      w  = this->weight(Base::mesh_.edge_handle(*voh_it));
      u -= vector_cast<typename Mesh::Normal>(Base::mesh_.point(Base::mesh_.to_vertex_handle(*voh_it)))*w;
Jan Möbius's avatar
Jan Möbius committed
153
    }
Jan Möbius's avatar
Jan Möbius committed
154 155
    u *= this->weight(*v_it);
    u += vector_cast<typename Mesh::Normal>(Base::mesh_.point(*v_it));
Jan Möbius's avatar
Jan Möbius committed
156

Jan Möbius's avatar
Jan Möbius committed
157
    Base::mesh_.property(umbrellas_, *v_it) = u;
Jan Möbius's avatar
Jan Möbius committed
158 159 160 161 162 163
  }


  // 2nd pass: compute updates
  for (v_it=Base::mesh_.vertices_begin(); v_it!=v_end; ++v_it)
  {
Jan Möbius's avatar
Jan Möbius committed
164
    if (this->is_active(*v_it))
Jan Möbius's avatar
Jan Möbius committed
165 166 167
    {
      uu   = zero;
      diag = 0.0;   
168 169 170
      for (voh_it = Base::mesh_.cvoh_iter(*v_it); voh_it.is_valid(); ++voh_it) {
        w  = this->weight(Base::mesh_.edge_handle(*voh_it));
        uu   -= Base::mesh_.property(umbrellas_, Base::mesh_.to_vertex_handle(*voh_it));
Jan Möbius's avatar
Jan Möbius committed
171
        diag += (w * this->weight(Base::mesh_.to_vertex_handle(*voh_it)) + static_cast<typename Mesh::Scalar>(1.0) ) * w;
Jan Möbius's avatar
Jan Möbius committed
172
      }
Jan Möbius's avatar
Jan Möbius committed
173 174 175
      uu   *= this->weight(*v_it);
      diag *= this->weight(*v_it);
      uu   += Base::mesh_.property(umbrellas_, *v_it);
Jan Möbius's avatar
Jan Möbius committed
176
      if (diag) uu *= static_cast<typename Mesh::Scalar>(1.0) / diag;
Jan Möbius's avatar
Jan Möbius committed
177 178

      // damping
179
      uu *= static_cast<typename vector_traits<typename Mesh::Normal>::value_type>(0.25);
Jan Möbius's avatar
Jan Möbius committed
180 181
    
      // store new position
Jan Möbius's avatar
Jan Möbius committed
182
      p  = vector_cast<typename Mesh::Normal>(Base::mesh_.point(*v_it));
Jan Möbius's avatar
Jan Möbius committed
183
      p -= uu;
Jan Möbius's avatar
Jan Möbius committed
184
      this->set_new_position(*v_it, p);
Jan Möbius's avatar
Jan Möbius committed
185 186 187 188 189 190 191 192 193
    }
  }
}


//=============================================================================
} // namespace Smoother
} // namespace OpenMesh
//=============================================================================