73 weights_computed_(false),
86 mesh_.remove_property(area_);
87 mesh_.remove_property(gauss_curvature_);
88 mesh_.remove_property(mean_curvature_);
89 mesh_.remove_property(edge_weight_);
99compute(
unsigned int _post_smoothing_iters)
101 compute_edge_weights();
103 compute_gauss_curvature();
104 compute_mean_curvature();
105 post_smoothing(_post_smoothing_iters);
115compute_edge_weights()
117 if (!edge_weight_.is_valid())
118 mesh_.add_property(edge_weight_);
126 for (e_it=mesh_.edges_begin(); e_it!=e_end; ++e_it)
129 const typename Mesh::Point& p0 = mesh_.point(mesh_.to_vertex_handle(heh0));
132 const typename Mesh::Point& p1 = mesh_.point(mesh_.to_vertex_handle(heh1));
134 heh2 = mesh_.next_halfedge_handle(heh0);
135 const typename Mesh::Point& p2 = mesh_.point(mesh_.to_vertex_handle(heh2));
138 weight = 1.0 / tan(acos(d0|d1));
140 heh2 = mesh_.next_halfedge_handle(heh1);
141 const typename Mesh::Point& p3 = mesh_.point(mesh_.to_vertex_handle(heh2));
144 weight += 1.0 / tan(acos(d2|d3));
146 mesh_.property(edge_weight_, *e_it) = weight;
150 weights_computed_ =
true;
162 if (!area_.is_valid())
163 mesh_.add_property(area_);
169 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
170 mesh_.property(area_, *v_it) = compute_area(*v_it);
173 area_computed_ =
true;
183compute_area(VertexHandle _vh)
const
189 double normPQ, normQR, normPR;
190 double angleP, angleQ, angleR;
192 double ub(0.999), lb(-0.999);
193 const double epsilon( 1e-12 );
197 for (voh_it=mesh_.voh_iter(_vh); voh_it.is_valid(); ++voh_it)
200 heh1 = mesh_.next_halfedge_handle(heh0);
201 heh2 = mesh_.next_halfedge_handle(heh1);
203 if (mesh_.is_boundary(heh0))
continue;
205 P = mesh_.point(mesh_.to_vertex_handle(heh2));
206 Q = mesh_.point(mesh_.to_vertex_handle(heh0));
207 R = mesh_.point(mesh_.to_vertex_handle(heh1));
217 if( normPQ <= epsilon || normQR <= epsilon || normPR <= epsilon )
220 angleP = (PQ | PR) / normPQ / normPR;
221 angleQ = -(PQ | QR) / normPQ / normQR;
222 angleR = (QR | PR) / normQR / normPR;
224 if (angleP > ub) angleP = ub;
else if (angleP < lb) angleP = lb;
225 if (angleQ > ub) angleQ = ub;
else if (angleQ < lb) angleQ = lb;
226 if (angleR > ub) angleR = ub;
else if (angleR < lb) angleR = lb;
228 angleP = acos(angleP);
229 angleQ = acos(angleQ);
230 angleR = acos(angleR);
232 if (angleP >= M_PI_2 || angleQ >= M_PI_2 || angleR >= M_PI_2)
234 if (angleP >= M_PI_2)
235 area += 0.25 * (PQ % PR).
norm();
237 area += 0.125 * (PQ % PR).
norm();
241 area += 0.125 * (normPR * normPR / tan(angleQ) +
242 normPQ * normPQ / tan(angleR));
256compute_gauss_curvature()
258 if (!gauss_curvature_.is_valid())
259 mesh_.add_property(gauss_curvature_);
274 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
276 if (!mesh_.is_boundary(*v_it))
280 for (vv_it=mesh_.vv_iter(*v_it); vv_it.is_valid(); ++vv_it)
282 vv_it2 = vv_it; ++vv_it2;
284 d0 = (mesh_.point(*vv_it) - mesh_.point(*v_it)).
normalize();
285 d1 = (mesh_.point(*vv_it2) - mesh_.point(*v_it)).
normalize();
287 cos_angle = std::max(lb, std::min(ub, (d0 | d1)));
288 angles += acos(cos_angle);
291 mesh_.property(gauss_curvature_, *v_it) = (2*M_PI-angles) / mesh_.property(area_, *v_it);
297 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
299 if (mesh_.is_boundary(*v_it))
303 for (vv_it=mesh_.vv_iter(*v_it); vv_it.is_valid(); ++vv_it)
304 if (!mesh_.is_boundary(*vv_it))
306 curv += mesh_.property(gauss_curvature_, *vv_it);
311 mesh_.property(gauss_curvature_, *v_it) = curv / count;
323compute_mean_curvature()
325 if (!mean_curvature_.is_valid())
326 mesh_.add_property(mean_curvature_);
328 if (!weights_computed_)
329 compute_edge_weights();
345 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
347 if (!mesh_.is_boundary(*v_it))
349 umbrella[0] = umbrella[1] = umbrella[2] = 0.0;
351 for (voh_it=mesh_.voh_iter(*v_it); voh_it.is_valid(); ++voh_it)
353 eh = mesh_.edge_handle(*voh_it);
354 weight = mesh_.property(edge_weight_, eh);
355 umbrella += (mesh_.point(*v_it) - mesh_.point(mesh_.to_vertex_handle(*voh_it))) * weight;
358 mesh_.property(mean_curvature_, *v_it) =
359 umbrella.norm() / (4.0 * mesh_.property(area_, *v_it));
365 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
367 if (mesh_.is_boundary(*v_it))
371 for (vv_it=mesh_.vv_iter(*v_it); vv_it.is_valid(); ++vv_it)
372 if (!mesh_.is_boundary(*vv_it))
374 curv += mesh_.property(mean_curvature_, *vv_it);
379 mesh_.property(mean_curvature_, *v_it) = curv / count;
391post_smoothing(
unsigned int _iters)
398 if (! (weights_computed_ &&
400 mean_curvature_.is_valid() &&
401 gauss_curvature_.is_valid()) )
403 std::cerr <<
"DiffGeoT::post_smoothing: something is wrong!\n";
419 mesh_.add_property(new_gauss);
420 mesh_.add_property(new_mean);
424 for (
unsigned int i=0; i<_iters; ++i)
428 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
430 if (!mesh_.is_boundary(*v_it))
434 for (voh_it=mesh_.voh_iter(*v_it); voh_it.is_valid(); ++voh_it)
436 eh = mesh_.edge_handle(*voh_it);
437 ww += (w = mesh_.property(edge_weight_, eh));
438 mc += w * mesh_.property(mean_curvature_, mesh_.to_vertex_handle(*voh_it));
439 gc += w * mesh_.property(gauss_curvature_, mesh_.to_vertex_handle(*voh_it));
444 mesh_.property(new_mean, *v_it) = mc / ww;
445 mesh_.property(new_gauss, *v_it) = gc / ww;
452 for (v_it=mesh_.vertices_begin(); v_it!=v_end; ++v_it)
454 if (!mesh_.is_boundary(*v_it))
456 mesh_.property(mean_curvature_, *v_it) = mesh_.property(new_mean, *v_it);
458 mesh_.property(gauss_curvature_, *v_it) = mesh_.property(new_gauss, *v_it);
465 mesh_.remove_property(new_gauss);
466 mesh_.remove_property(new_mean);
Kernel::Scalar Scalar
Scalar type.
Kernel::EdgeHandle EdgeHandle
Scalar type.
Kernel::VertexOHalfedgeIter VertexOHalfedgeIter
Circulator.
Kernel::HalfedgeHandle HalfedgeHandle
Scalar type.
Kernel::EdgeIter EdgeIter
Scalar type.
Kernel::VertexVertexIter VertexVertexIter
Circulator.
Kernel::Point Point
Coordinate type.
Kernel::VertexIter VertexIter
Scalar type.
VectorT< Scalar, DIM > & normalize(VectorT< Scalar, DIM > &_v)
Scalar norm(const VectorT< Scalar, DIM > &_v)