Developer Documentation
JacobiLaplaceSmootherT_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 
43 
48 //=============================================================================
49 //
50 // CLASS JacobiLaplaceSmootherT - IMPLEMENTATION
51 //
52 //=============================================================================
53 
54 #define OPENMESH_JACOBI_LAPLACE_SMOOTHERT_C
55 
56 //== INCLUDES =================================================================
57 
59 
60 
61 //== NAMESPACES ===============================================================
62 
63 
64 namespace OpenMesh {
65 namespace Smoother {
66 
67 
68 //== IMPLEMENTATION ==========================================================
69 
70 
71 template <class Mesh>
72 void
74 smooth(unsigned int _n)
75 {
76  if (Base::continuity() > Base::C0)
77  {
78  Base::mesh_.add_property(umbrellas_);
79  if (Base::continuity() > Base::C1)
80  Base::mesh_.add_property(squared_umbrellas_);
81  }
82 
84 
85  if (Base::continuity() > Base::C0)
86  {
87  Base::mesh_.remove_property(umbrellas_);
88  if (Base::continuity() > Base::C1)
89  Base::mesh_.remove_property(squared_umbrellas_);
90  }
91 }
92 
93 
94 //-----------------------------------------------------------------------------
95 
96 
97 template <class Mesh>
98 void
101 {
102  typename Mesh::VertexIter v_it, v_end(Base::mesh_.vertices_end());
103  typename Mesh::ConstVertexOHalfedgeIter voh_it;
104  typename Mesh::Normal u, p, zero(0,0,0);
105  typename Mesh::Scalar w;
106 
107  for (v_it=Base::mesh_.vertices_begin(); v_it!=v_end; ++v_it)
108  {
109  if (this->is_active(*v_it))
110  {
111  // compute umbrella
112  u = zero;
113  for (voh_it = Base::mesh_.cvoh_iter(*v_it); voh_it.is_valid(); ++voh_it) {
114  w = this->weight(Base::mesh_.edge_handle(*voh_it));
115  u += vector_cast<typename Mesh::Normal>(Base::mesh_.point(Base::mesh_.to_vertex_handle(*voh_it))) * w;
116  }
117  u *= this->weight(*v_it);
118  u -= vector_cast<typename Mesh::Normal>(Base::mesh_.point(*v_it));
119 
120  // damping
121  u *= static_cast< typename Mesh::Scalar >(0.5);
122 
123  // store new position
124  p = vector_cast<typename Mesh::Normal>(Base::mesh_.point(*v_it));
125  p += u;
126  this->set_new_position(*v_it, p);
127  }
128  }
129 }
130 
131 
132 //-----------------------------------------------------------------------------
133 
134 
135 template <class Mesh>
136 void
139 {
140  typename Mesh::VertexIter v_it, v_end(Base::mesh_.vertices_end());
141  typename Mesh::ConstVertexOHalfedgeIter voh_it;
142  typename Mesh::Normal u, uu, p, zero(0,0,0);
143  typename Mesh::Scalar w, diag;
144 
145 
146  // 1st pass: compute umbrellas
147  for (v_it=Base::mesh_.vertices_begin(); v_it!=v_end; ++v_it)
148  {
149  u = zero;
150  for (voh_it = Base::mesh_.cvoh_iter(*v_it); voh_it.is_valid(); ++voh_it) {
151  w = this->weight(Base::mesh_.edge_handle(*voh_it));
152  u -= vector_cast<typename Mesh::Normal>(Base::mesh_.point(Base::mesh_.to_vertex_handle(*voh_it)))*w;
153  }
154  u *= this->weight(*v_it);
155  u += vector_cast<typename Mesh::Normal>(Base::mesh_.point(*v_it));
156 
157  Base::mesh_.property(umbrellas_, *v_it) = u;
158  }
159 
160 
161  // 2nd pass: compute updates
162  for (v_it=Base::mesh_.vertices_begin(); v_it!=v_end; ++v_it)
163  {
164  if (this->is_active(*v_it))
165  {
166  uu = zero;
167  diag = 0.0;
168  for (voh_it = Base::mesh_.cvoh_iter(*v_it); voh_it.is_valid(); ++voh_it) {
169  w = this->weight(Base::mesh_.edge_handle(*voh_it));
170  uu -= Base::mesh_.property(umbrellas_, Base::mesh_.to_vertex_handle(*voh_it));
171  diag += (w * this->weight(Base::mesh_.to_vertex_handle(*voh_it)) + static_cast<typename Mesh::Scalar>(1.0) ) * w;
172  }
173  uu *= this->weight(*v_it);
174  diag *= this->weight(*v_it);
175  uu += Base::mesh_.property(umbrellas_, *v_it);
176  if (diag) uu *= static_cast<typename Mesh::Scalar>(1.0) / diag;
177 
178  // damping
179  uu *= static_cast<typename vector_traits<typename Mesh::Normal>::value_type>(0.25);
180 
181  // store new position
182  p = vector_cast<typename Mesh::Normal>(Base::mesh_.point(*v_it));
183  p -= uu;
184  this->set_new_position(*v_it, p);
185  }
186  }
187 }
188 
189 
190 //=============================================================================
191 } // namespace Smoother
192 } // namespace OpenMesh
193 //=============================================================================
virtual void smooth(unsigned int _n)
Do _n smoothing iterations.
void vector_cast(const src_t &_src, dst_t &_dst, GenProg::Int2Type< n >)
Cast vector type to another vector type by copying the vector elements.
Definition: vector_cast.hh:81
Kernel::Normal Normal
Normal type.
Definition: PolyMeshT.hh:114
void smooth(unsigned int _n)
Do _n smoothing iterations.
Kernel::Scalar Scalar
Scalar type.
Definition: PolyMeshT.hh:110
Kernel::ConstVertexOHalfedgeIter ConstVertexOHalfedgeIter
Circulator.
Definition: PolyMeshT.hh:173
T::value_type value_type
Type of the scalar value.