Developer Documentation
JacobiLaplaceSmootherT.cc
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  * *
44  * $Revision$ *
45  * $Date$ *
46  * *
47 \*===========================================================================*/
48 
53 //=============================================================================
54 //
55 // CLASS JacobiLaplaceSmootherT - IMPLEMENTATION
56 //
57 //=============================================================================
58 
59 #define OPENMESH_JACOBI_LAPLACE_SMOOTHERT_C
60 
61 //== INCLUDES =================================================================
62 
64 
65 
66 //== NAMESPACES ===============================================================
67 
68 
69 namespace OpenMesh {
70 namespace Smoother {
71 
72 
73 //== IMPLEMENTATION ==========================================================
74 
75 
76 template <class Mesh>
77 void
79 smooth(unsigned int _n)
80 {
81  if (Base::continuity() > Base::C0)
82  {
83  Base::mesh_.add_property(umbrellas_);
84  if (Base::continuity() > Base::C1)
85  Base::mesh_.add_property(squared_umbrellas_);
86  }
87 
89 
90  if (Base::continuity() > Base::C0)
91  {
92  Base::mesh_.remove_property(umbrellas_);
93  if (Base::continuity() > Base::C1)
94  Base::mesh_.remove_property(squared_umbrellas_);
95  }
96 }
97 
98 
99 //-----------------------------------------------------------------------------
100 
101 
102 template <class Mesh>
103 void
106 {
107  typename Mesh::VertexIter v_it, v_end(Base::mesh_.vertices_end());
108  typename Mesh::ConstVertexOHalfedgeIter voh_it;
109  typename Mesh::Normal u, p, zero(0,0,0);
110  typename Mesh::Scalar w;
111 
112  for (v_it=Base::mesh_.vertices_begin(); v_it!=v_end; ++v_it)
113  {
114  if (this->is_active(*v_it))
115  {
116  // compute umbrella
117  u = zero;
118  for (voh_it = Base::mesh_.cvoh_iter(*v_it); voh_it.is_valid(); ++voh_it) {
119  w = this->weight(Base::mesh_.edge_handle(*voh_it));
120  u += vector_cast<typename Mesh::Normal>(Base::mesh_.point(Base::mesh_.to_vertex_handle(*voh_it))) * w;
121  }
122  u *= this->weight(*v_it);
123  u -= vector_cast<typename Mesh::Normal>(Base::mesh_.point(*v_it));
124 
125  // damping
126  u *= 0.5;
127 
128  // store new position
129  p = vector_cast<typename Mesh::Normal>(Base::mesh_.point(*v_it));
130  p += u;
131  this->set_new_position(*v_it, p);
132  }
133  }
134 }
135 
136 
137 //-----------------------------------------------------------------------------
138 
139 
140 template <class Mesh>
141 void
144 {
145  typename Mesh::VertexIter v_it, v_end(Base::mesh_.vertices_end());
146  typename Mesh::ConstVertexOHalfedgeIter voh_it;
147  typename Mesh::Normal u, uu, p, zero(0,0,0);
148  typename Mesh::Scalar w, diag;
149 
150 
151  // 1st pass: compute umbrellas
152  for (v_it=Base::mesh_.vertices_begin(); v_it!=v_end; ++v_it)
153  {
154  u = zero;
155  for (voh_it = Base::mesh_.cvoh_iter(*v_it); voh_it.is_valid(); ++voh_it) {
156  w = this->weight(Base::mesh_.edge_handle(*voh_it));
157  u -= vector_cast<typename Mesh::Normal>(Base::mesh_.point(Base::mesh_.to_vertex_handle(*voh_it)))*w;
158  }
159  u *= this->weight(*v_it);
160  u += vector_cast<typename Mesh::Normal>(Base::mesh_.point(*v_it));
161 
162  Base::mesh_.property(umbrellas_, *v_it) = u;
163  }
164 
165 
166  // 2nd pass: compute updates
167  for (v_it=Base::mesh_.vertices_begin(); v_it!=v_end; ++v_it)
168  {
169  if (this->is_active(*v_it))
170  {
171  uu = zero;
172  diag = 0.0;
173  for (voh_it = Base::mesh_.cvoh_iter(*v_it); voh_it.is_valid(); ++voh_it) {
174  w = this->weight(Base::mesh_.edge_handle(*voh_it));
175  uu -= Base::mesh_.property(umbrellas_, Base::mesh_.to_vertex_handle(*voh_it));
176  diag += (w * this->weight(Base::mesh_.to_vertex_handle(*voh_it)) + static_cast<typename Mesh::Scalar>(1.0) ) * w;
177  }
178  uu *= this->weight(*v_it);
179  diag *= this->weight(*v_it);
180  uu += Base::mesh_.property(umbrellas_, *v_it);
181  if (diag) uu *= static_cast<typename Mesh::Scalar>(1.0) / diag;
182 
183  // damping
184  uu *= 0.25;
185 
186  // store new position
187  p = vector_cast<typename Mesh::Normal>(Base::mesh_.point(*v_it));
188  p -= uu;
189  this->set_new_position(*v_it, p);
190  }
191  }
192 }
193 
194 
195 //=============================================================================
196 } // namespace Smoother
197 } // namespace OpenMesh
198 //=============================================================================
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:86
void smooth(unsigned int _n)
Do _n smoothing iterations.
virtual void smooth(unsigned int _n)
Do _n smoothing iterations.
Definition: SmootherT.cc:307
Kernel::Normal Normal
Normal type.
Definition: PolyMeshT.hh:117
Kernel::ConstVertexOHalfedgeIter ConstVertexOHalfedgeIter
Circulator.
Definition: PolyMeshT.hh:176
Kernel::Scalar Scalar
Scalar type.
Definition: PolyMeshT.hh:113