Developer Documentation
LaplaceSmootherT_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 LaplaceSmootherT - IMPLEMENTATION
51 //
52 //=============================================================================
53 
54 #define OPENMESH_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 LaplaceSmootherT<Mesh>::
73 LaplaceSmootherT(Mesh& _mesh)
74  : SmootherT<Mesh>(_mesh)
75 {
76  // custom properties
77  Base::mesh_.add_property(vertex_weights_);
78  Base::mesh_.add_property(edge_weights_);
79 }
80 
81 
82 //-----------------------------------------------------------------------------
83 
84 
85 template <class Mesh>
86 LaplaceSmootherT<Mesh>::
87 ~LaplaceSmootherT()
88 {
89  // free custom properties
90  Base::mesh_.remove_property(vertex_weights_);
91  Base::mesh_.remove_property(edge_weights_);
92 }
93 
94 
95 //-----------------------------------------------------------------------------
96 
97 
98 template <class Mesh>
99 void
100 LaplaceSmootherT<Mesh>::
101 initialize(Component _comp, Continuity _cont)
102 {
103  SmootherT<Mesh>::initialize(_comp, _cont);
104 
105  // calculate weights
106  switch (_comp)
107  {
108  case Base::Tangential:
109  compute_weights(UniformWeighting);
110  break;
111 
112 
113  case Base::Normal:
114  compute_weights(CotWeighting);
115  break;
116 
117 
119  compute_weights(UniformWeighting);
120  break;
121  }
122 }
123 
124 
125 //-----------------------------------------------------------------------------
126 
127 
128 template <class Mesh>
129 void
130 LaplaceSmootherT<Mesh>::
131 compute_weights(LaplaceWeighting _weighting)
132 {
133  typename Mesh::VertexIter v_it, v_end(Base::mesh_.vertices_end());
134  typename Mesh::EdgeIter e_it, e_end(Base::mesh_.edges_end());
135  typename Mesh::HalfedgeHandle heh0, heh1, heh2;
136  typename Mesh::VertexHandle v0, v1;
137  typename Mesh::Normal d0, d1;
138  typename Mesh::Scalar weight, lb(-1.0), ub(1.0);
139 
140 
141 
142  // init vertex weights
143  for (v_it=Base::mesh_.vertices_begin(); v_it!=v_end; ++v_it)
144  Base::mesh_.property(vertex_weights_, *v_it) = 0.0;
145 
146 
147 
148  switch (_weighting)
149  {
150  // Uniform weighting
151  case UniformWeighting:
152  {
153  for (e_it=Base::mesh_.edges_begin(); e_it!=e_end; ++e_it)
154  {
155  heh0 = Base::mesh_.halfedge_handle(*e_it, 0);
156  heh1 = Base::mesh_.halfedge_handle(*e_it, 1);
157  v0 = Base::mesh_.to_vertex_handle(heh0);
158  v1 = Base::mesh_.to_vertex_handle(heh1);
159 
160  Base::mesh_.property(edge_weights_, *e_it) = 1.0;
161  Base::mesh_.property(vertex_weights_, v0) += 1.0;
162  Base::mesh_.property(vertex_weights_, v1) += 1.0;
163  }
164 
165  break;
166  }
167 
168 
169  // Cotangent weighting
170  case CotWeighting:
171  {
172  for (e_it=Base::mesh_.edges_begin(); e_it!=e_end; ++e_it)
173  {
174  const typename Mesh::Point *p0, *p1, *p2;
175 
176  weight = 0.0;
177 
178  heh0 = Base::mesh_.halfedge_handle(*e_it, 0);
179  v0 = Base::mesh_.to_vertex_handle(heh0);
180  p0 = &Base::mesh_.point(v0);
181 
182  heh1 = Base::mesh_.halfedge_handle(*e_it, 1);
183  v1 = Base::mesh_.to_vertex_handle(heh1);
184  p1 = &Base::mesh_.point(v1);
185 
186  heh2 = Base::mesh_.next_halfedge_handle(heh0);
187  p2 = &Base::mesh_.point(Base::mesh_.to_vertex_handle(heh2));
188  d0 = (*p0 - *p2); d0.normalize();
189  d1 = (*p1 - *p2); d1.normalize();
190  weight += static_cast<typename Mesh::Scalar>(1.0) / tan(acos(std::max(lb, std::min(ub, dot(d0,d1) ))));
191 
192  heh2 = Base::mesh_.next_halfedge_handle(heh1);
193  p2 = &Base::mesh_.point(Base::mesh_.to_vertex_handle(heh2));
194  d0 = (*p0 - *p2); d0.normalize();
195  d1 = (*p1 - *p2); d1.normalize();
196  weight += static_cast<typename Mesh::Scalar>(1.0) / tan(acos(std::max(lb, std::min(ub, dot(d0,d1) ))));
197 
198  Base::mesh_.property(edge_weights_, *e_it) = weight;
199  Base::mesh_.property(vertex_weights_, v0) += weight;
200  Base::mesh_.property(vertex_weights_, v1) += weight;
201  }
202  break;
203  }
204  }
205 
206 
207  // invert vertex weights:
208  // before: sum of edge weights
209  // after: one over sum of edge weights
210  for (v_it=Base::mesh_.vertices_begin(); v_it!=v_end; ++v_it)
211  {
212  weight = Base::mesh_.property(vertex_weights_, *v_it);
213  if (weight)
214  Base::mesh_.property(vertex_weights_, *v_it) = static_cast<typename Mesh::Scalar>(1.0) / weight;
215  }
216 }
217 
218 
219 
220 //=============================================================================
221 } // namespace Smoother
222 } // namespace OpenMesh
223 //=============================================================================
Smooth tangential direction.
Definition: SmootherT.hh:88
Kernel::Normal Normal
Normal type.
Definition: PolyMeshT.hh:114
Kernel::Point Point
Coordinate type.
Definition: PolyMeshT.hh:112
Smooth tangential and normal direction.
Definition: SmootherT.hh:90
Smooth normal direction.
Definition: SmootherT.hh:89
void initialize(Component _comp, Continuity _cont)
Kernel::Scalar Scalar
Scalar type.
Definition: PolyMeshT.hh:110
osg::Vec3f::ValueType dot(const osg::Vec3f &_v1, const osg::Vec3f &_v2)
Adapter for osg vector member computing a scalar product.
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
Definition: PolyMeshT.hh:136