Developer Documentation
Loading...
Searching...
No Matches
CurvatureT_impl.hh
1/*===========================================================================*\
2* *
3* OpenFlipper *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openflipper.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenFlipper. *
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
45
46
47//=============================================================================
48//
49// IMPLEMENTATION
50//
51//=============================================================================
52
53#define CURVATURE_C
54
55//== INCLUDES =================================================================
56
57#include <ACG/Geometry/Algorithms.hh>
58#include "Math_Tools/Math_Tools.hh"
59
60#include <iostream>
61#include <OpenMesh/Core/Geometry/MathDefs.hh>
62
63#include <cmath>
64
65//== NAMESPACES ===============================================================
66
67namespace curvature {
68
69//== IMPLEMENTATION ==========================================================
70
73template< typename MeshT >
74double
75gauss_curvature(MeshT& _mesh, const typename MeshT::VertexHandle& _vh) {
76 if (_mesh.status(_vh).deleted())
77 return 0.0;
78
79 double gauss_curv = 2.0 * M_PI;
80
81 /*
82
83 TODO: Check the boundary case.
84
85 If the vertex is a boundary vertex
86 if ( _mesh.is_boundary(_vh) )
87 gauss_curv = M_PI;
88
89 */
90
91 const typename MeshT::Point p0 = _mesh.point(_vh);
92
93 typename MeshT::CVOHIter voh_it( _mesh.cvoh_iter(_vh));
94
95 if ( ! voh_it->is_valid() )
96 return 0.0;
97
98
99
100 for (auto voh_it : _mesh.voh_range(_vh))
101 {
102 typename MeshT::Point p1 = _mesh.point(voh_it.to());
103 typename MeshT::Point p2 = _mesh.point(voh_it.opp().next().to());
104
105 gauss_curv -= acos(OpenMesh::sane_aarg( ((p1-p0).normalize() | (p2-p0).normalize()) ));
106 }
107
108 return gauss_curv;
109}
110
111
112template<class MeshT, class VectorT, class REALT>
113void discrete_mean_curv_op( const MeshT& _m, const typename MeshT::VertexHandle& _vh, VectorT& _n, REALT& _area )
114{
115 _n = VectorT(0,0,0);
116 _area = 0.0;
117
118 if ( ! _m.cvoh_iter(_vh)->is_valid() )
119 return;
120
121 for(auto voh_it : _m.voh_range(_vh))
122 {
123 if ( voh_it.edge().is_boundary() )
124 continue;
125
126 const typename MeshT::Point p0 = _m.point( _vh );
127 const typename MeshT::Point p1 = _m.point(voh_it.to());
128 const typename MeshT::Point p2 = _m.point(voh_it.prev().from());
129
130 const typename MeshT::Point p3 = _m.point(voh_it.opp().next().to());
131
132 const REALT alpha = acos( OpenMesh::sane_aarg((p0-p2).normalize() | (p1-p2).normalize()) );
133 const REALT beta = acos( OpenMesh::sane_aarg((p0-p3).normalize() | (p1-p3).normalize()) );
134
135 REALT cotw = 0.0;
136
137 if ( !OpenMesh::is_eq(alpha,M_PI/2.0) )
138 cotw += (REALT(1.0))/tan(alpha);
139
140 if ( !OpenMesh::is_eq(beta,M_PI/2.0) )
141 cotw += (REALT(1.0))/tan(beta);
142
143#ifdef WIN32
144 if ( OpenMesh::is_zero(cotw) )
145 continue;
146#else
147 if ( OpenMesh::is_zero(cotw) || std::isinf(cotw) )
148 continue;
149#endif
150
151 // calculate area
152 const int obt = ACG::Geometry::isObtuse(p0,p1,p2);
153 if(obt == 0)
154 {
155 REALT gamma = acos( OpenMesh::sane_aarg((p0-p1).normalize() | (p2-p1).normalize()) );
156
157 REALT tmp = 0.0;
158 if ( !OpenMesh::is_eq(alpha,M_PI/2.0) )
159 tmp += (p0-p1).sqrnorm()*1.0/tan(alpha);
160
161 if ( !OpenMesh::is_eq(gamma,M_PI/2.0) )
162 tmp += (p0-p2).sqrnorm()*1.0/tan(gamma);
163
164#ifdef WIN32
165 if ( OpenMesh::is_zero(tmp) )
166 continue;
167#else
168 if ( OpenMesh::is_zero(tmp) || std::isinf(tmp) )
169 continue;
170#endif
171
172 _area += 0.125*( tmp );
173 }
174 else
175 {
176 if(obt == 1)
177 {
178 _area += ((p1-p0) % (p2-p0)).norm() * 0.5 * 0.5;
179 }
180 else
181 {
182 _area += ((p1-p0) % (p2-p0)).norm() * 0.5 * 0.25;
183 }
184 }
185
186 _n += ((p0-p1)*cotw);
187
188 // error handling
189 //if(_area < 0) std::cerr << "error: triangle area < 0\n";
190// if(isnan(_area))
191// {
192// REALT gamma = acos( ((p0-p1).normalize() | (p2-p1).normalize()) );
193
194/*
195 std::cerr << "***************************\n";
196 std::cerr << "error : trianlge area = nan\n";
197 std::cerr << "alpha : " << alpha << std::endl;
198 std::cerr << "beta : " << beta << std::endl;
199 std::cerr << "gamma : " << gamma << std::endl;
200 std::cerr << "cotw : " << cotw << std::endl;
201 std::cerr << "normal: " << _n << std::endl;
202 std::cerr << "p0 : " << p0 << std::endl;
203 std::cerr << "p1 : " << p1 << std::endl;
204 std::cerr << "p2 : " << p2 << std::endl;
205 std::cerr << "p3 : " << p3 << std::endl;
206 std::cerr << "***************************\n";
207*/
208// }
209 }
210
211 _n /= 4.0*_area;
212}
213
214
215
216//=============================================================================
217} // curvature Namespace
218//=============================================================================
double gauss_curvature(MeshT &_mesh, const typename MeshT::VertexHandle &_vh)
void discrete_mean_curv_op(const MeshT &_m, const typename MeshT::VertexHandle &_vh, VectorT &_n, REALT &_area)
bool is_valid(Handle _h) const
test is_valid and perform index range check
int isObtuse(const VectorT &_p0, const VectorT &_p1, const VectorT &_p2)
bool is_zero(const T &_a, Real _eps)
Definition MathDefs.hh:61
T sane_aarg(T _aarg)
Trigonometry/angles - related.
Definition MathDefs.hh:122