MEPP2 Project
vertex_one_ring_angles_based_centroid.hpp
Go to the documentation of this file.
1 // Copyright (c) 2012-2019 University of Lyon and CNRS (France).
2 // All rights reserved.
3 //
4 // This file is part of MEPP2; you can redistribute it and/or modify
5 // it under the terms of the GNU Lesser General Public License as
6 // published by the Free Software Foundation; either version 3 of
7 // the License, or (at your option) any later version.
8 //
9 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
10 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
11 #pragma once
12 
13 #include <boost/graph/graph_traits.hpp>
14 #include <boost/graph/properties.hpp>
15 #include <CGAL/boost/graph/iterator.h> // for circulators
16 #include <cmath> // for std::sqrt()
17 
22 
23 
24 namespace FEVV {
25 namespace Operators {
26 
47 template< typename FaceGraph,
48  typename PointMap,
49  typename GeometryTraits = FEVV::Geometry_traits< FaceGraph > >
50 typename boost::property_traits< PointMap >::value_type
53  const FaceGraph &g,
54  const PointMap &pm,
55  const typename GeometryTraits::Scalar smoothing_factor,
56  const GeometryTraits &gt)
57 {
58  typedef typename GeometryTraits::Vector Vector;
59  typedef typename GeometryTraits::Point Point;
60  // if ( boost::optional<typename
61  // boost::graph_traits<FaceGraph>::halfedge_descriptor> h = CGAL::is_border(v,
62  // g) )
63  //{
64  // return get(pm, v); // for the time being do not change border vertex
65  //}
67  Vector vec = gt.NULL_VECTOR;
68  double sum_iangles = 0.0f, alpha1, alpha2, iangle;
69  // std::cout << "around v " << get(pm, v) << std::endl;
70  CGAL::Halfedge_around_target_circulator< FaceGraph > cir_he(v, g),
71  cir_he_end(cir_he);
72  do
73  {
74  // The angle must be divided in two to take convex and concave cases into
75  // account
76  alpha1 = FEVV::Operators::Geometry::triangle_rad_angle< GeometryTraits >(
77  get(pm, target(*cir_he, g)),
78  get(pm, source(*cir_he, g)),
79  get(pm, source(prev(opposite(*cir_he, g), g), g)),
80  gt);
81  // std::cout << "t1 = " << get(pm, target(*cir_he, g)) << "; " << get(pm,
82  // source(*cir_he, g)) << "; " << get(pm, source(prev(opposite(*cir_he, g),
83  // g), g)) << std::endl;
84  alpha2 = FEVV::Operators::Geometry::triangle_rad_angle< GeometryTraits >(
85  get(pm, target(next(*cir_he, g), g)),
86  get(pm, source(*cir_he, g)),
87  get(pm, target(*cir_he, g)),
88  gt);
89  // std::cout << "t2 = " << get(pm, target(next(*cir_he, g), g)) << "; " <<
90  // get(pm, source(*cir_he, g)) << "; " << get(pm, target(*cir_he, g)) <<
91  // std::endl; std::cout << "alpha1 = " << alpha1 << " alpha2 = " << alpha2 <<
92  // std::endl;
93  if(alpha1 < 0.0 || alpha2 < 0.0)
94  assert(false);
96  Vector d1, d2, c, dc;
97  d1 = gt.sub_p(get(pm, target(next(opposite(*cir_he, g), g), g)),
98  get(pm, source(*cir_he, g)));
99  // d1 = pm[target(next(opposite(*cir_he, g), g), g)] - pm[source(*cir_he,
100  // g)]; // more warnings
101  d1 = gt.normalize(d1);
102  d2 = gt.sub_p(get(pm, target(next(*cir_he, g), g)),
103  get(pm, source(*cir_he, g)));
104  d2 = gt.normalize(d2);
105  c = 0.5 * (d1 + d2);
106 
107  if(FEVV::Operators::
108  is_geometrical_fold< FaceGraph, PointMap, GeometryTraits >(
109  prev(prev(opposite(*cir_he, g), g), g),
110  // prev prev instead of next to handle polygonal cases
111  next(*cir_he, g),
112  g,
113  pm,
114  gt))
115  continue;
117  if(gt.dot_product(c, c) > MACH_EPS_DOUBLE)
118  {
119  c = c * (1.0 / std::sqrt(gt.dot_product(c, c)));
120  Point new_ideal_point = gt.add_pv(
121  get(pm, source(*cir_he, g)),
122  c * std::sqrt(gt.dot_product(gt.sub_p(get(pm, target(*cir_he, g)),
123  get(pm, source(*cir_he, g))),
124  gt.sub_p(get(pm, target(*cir_he, g)),
125  get(pm, source(*cir_he, g))))));
126 
127  // Calculate the difference between two adjacent angles...
128  // Small angles (alpha1+alpha2) must be favorized to avoid foldover
129  iangle = alpha1 + alpha2;
130  iangle = 1.0 / (iangle * iangle);
131  dc = gt.sub_p(new_ideal_point, get(pm, v));
132  // normalize_Vector(dc); // unit direction towards the bissector of that
133  // angle
135  // the current best results:
136  vec = vec + dc * iangle;
137  sum_iangles += iangle;
138  }
139  } while(++cir_he != cir_he_end);
140  if(::fabs(sum_iangles) > MACH_EPS_DOUBLE)
141  vec = vec * (1.0 / sum_iangles);
142 
143  Vector n;
144 #if 0
145  // MORE FIDELITY!!!!!
146  // we do that to not change the NRJ being minimized
147  N = (pVertex->closestObs())->normal();
148  // to be more sensitive to the initial curvature
149  //N = CGAL::cross_product(pVertex->closestObs()->VKmin,
150  // pVertex->closestObs()->VKmax); // too much geometric error
151 #endif
152  // more geometric error, since we use the initial surface as reference
153  n = FEVV::Operators::
154  calculate_vertex_normal< FaceGraph, PointMap, GeometryTraits >(
155  v, g, pm, gt); // to avoid introducing noise in flat region
156 
157  vec = vec - gt.dot_product(vec, n) * n;
158  // std::cout << "vec = (" << vec[0] << ", " << vec[1] << ", " << vec[2] << ")"
159  // << std::endl;
160  return gt.add_pv(get(pm, v), smoothing_factor * vec);
161 }
162 
163 } // namespace Operators
164 } // namespace FEVV
FEVV::DataStructures::AIF::next
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor next(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor h, const FEVV::DataStructures::AIF::AIFMesh &sm)
Returns the next halfedge around its face.
Definition: Graph_traits_aif.h:599
Vector
AIFMesh::Vector Vector
Definition: Graph_properties_aif.h:22
is_geometrical_fold.hpp
FEVV::Operators::vertex_one_ring_angles_based_centroid
boost::property_traits< PointMap >::value_type vertex_one_ring_angles_based_centroid(typename boost::graph_traits< FaceGraph >::vertex_descriptor v, const FaceGraph &g, const PointMap &pm, const typename GeometryTraits::Scalar smoothing_factor, const GeometryTraits &gt)
Angle-based smoothing of the vertex' one ring of vertex positions. Increases the min angle and decrea...
Definition: vertex_one_ring_angles_based_centroid.hpp:51
FEVV::DataStructures::AIF::opposite
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor opposite(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor h, const FEVV::DataStructures::AIF::AIFMesh &sm)
Returns the halfedge with source and target swapped.
Definition: Graph_traits_aif.h:625
FEVV::Geometry_traits
Refer to Geometry_traits_documentation_dummy for further documentation on provided types and algorith...
Definition: Geometry_traits.h:162
Point
AIFMesh::Point Point
Definition: Graph_properties_aif.h:21
triangle_rad_angle.hpp
FEVV::DataStructures::AIF::source
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor source(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::edge_descriptor e, const FEVV::DataStructures::AIF::AIFMesh &)
Returns the source vertex of e.
Definition: Graph_traits_aif.h:387
FEVV::get
FEVV::PCLPointCloudPointMap::value_type get(const FEVV::PCLPointCloudPointMap &pm, FEVV::PCLPointCloudPointMap::key_type key)
Specialization of get(point_map, key) for PCLPointCloud.
Definition: Graph_properties_pcl_point_cloud.h:117
FEVV
Interfaces for plugins These interfaces will be used for different plugins.
Definition: Assert.h:16
MACH_EPS_DOUBLE
#define MACH_EPS_DOUBLE
Definition: MatrixOperations.hpp:29
FEVV::DataStructures::AIF::target
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor target(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::edge_descriptor e, const FEVV::DataStructures::AIF::AIFMesh &)
Returns the target vertex of e.
Definition: Graph_traits_aif.h:400
Geometry_traits.h
FEVV::Operators
Definition: collapse_edge.hpp:25
FEVV::DataStructures::AIF::AIFVector
Definition: AIFProperties.h:173
FEVV::DataStructures::AIF::prev
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor prev(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor h, const FEVV::DataStructures::AIF::AIFMesh &sm)
Returns the previous halfedge around its face.
Definition: Graph_traits_aif.h:612
msdm2::vertex_descriptor
boost::graph_traits< MeshT >::vertex_descriptor vertex_descriptor
Definition: msdm2_surfacemesh.h:33
FEVV::Filters::fabs
double fabs(const v_Curv< HalfedgeGraph > &input)
Definition: curvature.hpp:54
calculate_vertex_normal.hpp
FEVV::DataStructures::AIF::AIFPoint
Definition: AIFProperties.h:31