incomplete (single vertex curvature)

This commit is contained in:
hoskillua 2022-11-18 12:56:08 +02:00
parent e79e34df4f
commit 80e3522eaa
1 changed files with 457 additions and 12 deletions

View File

@ -598,7 +598,7 @@ namespace internal {
private:
void interpolated_corrected_all_measures_all_faces()
void interpolated_corrected_selected_measures_all_faces()
{
std::vector<Vector_3> x;
std::vector<Vector_3> u;
@ -629,26 +629,26 @@ namespace internal {
Vertex_measures<GT> expand_interpolated_corrected_measure_vertex_no_radius(Vertex_descriptor v)
{
Vertex_measures<GT> vertex_curvatures;
Vertex_measures<GT> vertex_measures;
for (Face_descriptor f : faces_around_target(halfedge(v, pmesh), pmesh)) {
vertex_curvatures.area_measure += get(mu0_map, f);
vertex_measures.area_measure += get(mu0_map, f);
if (is_mean_curvature_selected)
vertex_curvatures.mean_curvature_measure += get(mu1_map, f);
vertex_measures.mean_curvature_measure += get(mu1_map, f);
if (is_gaussian_curvature_selected)
vertex_curvatures.gaussian_curvature_measure += get(mu2_map, f);
vertex_measures.gaussian_curvature_measure += get(mu2_map, f);
if (is_principal_curvature_selected)
{
const std::array<FT, 3 * 3> face_anisotropic_measure = get(muXY_map, f);
for (std::size_t i = 0; i < 3 * 3; i++)
vertex_curvatures.anisotropic_measure[i] += face_anisotropic_measure[i];
vertex_measures.anisotropic_measure[i] += face_anisotropic_measure[i];
}
}
return vertex_curvatures;
return vertex_measures;
}
Vertex_measures<GT> expand_interpolated_corrected_measure_vertex(Vertex_descriptor v)
@ -659,7 +659,7 @@ namespace internal {
Point_3 vp = get(vpm, v);
Vector_3 c = Vector_3(vp.x(), vp.y(), vp.z());
Vertex_measures<GT> vertex_curvatures;
Vertex_measures<GT> vertex_measures;
for (Face_descriptor f : faces_around_target(halfedge(v, pmesh), pmesh)) {
if (f != boost::graph_traits<PolygonMesh>::null_face())
@ -684,6 +684,230 @@ namespace internal {
if (f_ratio != 0.0)
{
vertex_measures.area_measure += f_ratio * get(mu0_map, fi);
if (is_mean_curvature_selected)
vertex_measures.mean_curvature_measure += f_ratio * get(mu1_map, fi);
if (is_gaussian_curvature_selected)
vertex_measures.gaussian_curvature_measure += f_ratio * get(mu2_map, fi);
if (is_principal_curvature_selected)
{
const std::array<FT, 3 * 3> face_anisotropic_measure = get(muXY_map, fi);
for (std::size_t i = 0; i < 3 * 3; i++)
vertex_measures.anisotropic_measure[i] += f_ratio * face_anisotropic_measure[i];
}
for (Face_descriptor fj : faces_around_face(halfedge(fi, pmesh), pmesh))
{
if (bfs_visited.find(fj) == bfs_visited.end() && fj != boost::graph_traits<PolygonMesh>::null_face())
{
bfs_queue.push(fj);
bfs_visited.insert(fj);
}
}
}
}
return vertex_measures;
}
void compute_selected_curvatures() {
interpolated_corrected_selected_measures_all_faces();
for (Vertex_descriptor v : vertices(pmesh))
{
Vertex_measures<GT> vertex_measures = (ball_radius < 0) ?
expand_interpolated_corrected_measure_vertex_no_radius(v) :
expand_interpolated_corrected_measure_vertex(v);
if (is_mean_curvature_selected) {
vertex_measures.area_measure != 0 ?
put(mean_curvature_map, v, 0.5 * vertex_measures.mean_curvature_measure / vertex_measures.area_measure) :
put(mean_curvature_map, v, 0);
}
if (is_gaussian_curvature_selected) {
vertex_measures.area_measure != 0 ?
put(gaussian_curvature_map, v, vertex_measures.gaussian_curvature_measure / vertex_measures.area_measure) :
put(gaussian_curvature_map, v, 0);
}
if (is_principal_curvature_selected) {
const Vector_3 v_normal = get(vnm, v);
const Principal_curvature<GT> principal_curvature = principal_curvature_from_anisotropic_measures<GT>(
vertex_measures.anisotropic_measure,
vertex_measures.area_measure,
v_normal
);
put(principal_curvature_map, v, principal_curvature);
}
}
}
};
template<typename PolygonMesh, typename NamedParameters = parameters::Default_named_parameters>
class Interpolated_corrected_curvatures_point_computer
{
typedef typename GetGeomTraits<PolygonMesh, NamedParameters>::type GT;
typedef typename GT::FT FT;
typedef typename GT::Point_3 Point_3;
typedef typename GT::Vector_3 Vector_3;
typedef typename boost::graph_traits<PolygonMesh>::halfedge_descriptor Halfedge_descriptor;
typedef typename boost::graph_traits<PolygonMesh>::edge_descriptor Edge_descriptor;
typedef typename boost::graph_traits<PolygonMesh>::face_descriptor Face_descriptor;
typedef typename boost::graph_traits<PolygonMesh>::vertex_descriptor Vertex_descriptor;
typedef typename GetVertexPointMap<PolygonMesh, NamedParameters>::const_type Vertex_position_map;
typedef dynamic_vertex_property_t<Vector_3> Vector_map_tag;
typedef typename boost::property_map<PolygonMesh, Vector_map_tag>::const_type Default_vector_map;
typedef typename internal_np::Lookup_named_param_def<internal_np::vertex_normal_map_t,
NamedParameters,
Default_vector_map>::type Vertex_normal_map;
private:
const PolygonMesh& pmesh;
Vertex_position_map vpm;
Vertex_normal_map vnm;
FT ball_radius;
bool is_mean_curvature_selected;
bool is_gaussian_curvature_selected;
bool is_principal_curvature_selected;
Point_3 point;
void set_named_params(const NamedParameters& np)
{
using parameters::choose_parameter;
using parameters::get_parameter;
using parameters::is_default_parameter;
vpm = choose_parameter(get_parameter(np, CGAL::vertex_point),
get_const_property_map(CGAL::vertex_point, pmesh));
vnm = choose_parameter(get_parameter(np, internal_np::vertex_normal_map),
get(Vector_map_tag(), pmesh));
if (is_default_parameter<NamedParameters, internal_np::vertex_normal_map_t>::value)
compute_vertex_normals(pmesh, vnm, np);
const FT radius = choose_parameter(get_parameter(np, internal_np::ball_radius), -1);
is_mean_curvature_selected = !is_default_parameter<NamedParameters, internal_np::vertex_mean_curvature_map_t>::value;
is_gaussian_curvature_selected = !is_default_parameter<NamedParameters, internal_np::vertex_gaussian_curvature_map_t>::value;
is_principal_curvature_selected = !is_default_parameter<NamedParameters, internal_np::vertex_principal_curvature_map_t>::value;
set_ball_radius(radius);
}
void set_ball_radius(const FT radius) {
if (radius == 0)
ball_radius = average_edge_length<PolygonMesh, GT>(pmesh) * EXPANDING_RADIUS_EPSILON;
else
ball_radius = radius;
}
public:
Interpolated_corrected_curvatures_computer(const PolygonMesh& pmesh,
const NamedParameters& np = parameters::default_values()
) :
pmesh(pmesh)
{
set_named_params(np);
if (is_mean_curvature_selected || is_gaussian_curvature_selected || is_principal_curvature_selected)
{
set_property_maps();
compute_selected_curvatures();
}
}
private:
Vertex_measures<GT> expand_interpolated_corrected_measure_vertex_no_radius(Vertex_descriptor v)
{
Vertex_measures<GT> vertex_curvatures;
std::vector<Vector_3> x;
std::vector<Vector_3> u;
for (Face_descriptor f : faces_around_target(halfedge(v, pmesh), pmesh)) {
for (Vertex_descriptor v : vertices_around_face(halfedge(f, pmesh), pmesh))
{
Point_3 p = get(vpm, v);
x.push_back(Vector_3(p.x(), p.y(), p.z()));
u.push_back(get(vnm, v));
}
vertex_curvatures.area_measure += interpolated_corrected_area_measure_face<GT>(u, x);
if (is_mean_curvature_selected)
vertex_curvatures.mean_curvature_measure += interpolated_corrected_mean_curvature_measure_face<GT>(u, x);
if (is_gaussian_curvature_selected)
vertex_curvatures.gaussian_curvature_measure += interpolated_corrected_gaussian_curvature_measure_face<GT>(u, x);
if (is_principal_curvature_selected)
{
const std::array<FT, 3 * 3> face_anisotropic_measure = interpolated_corrected_anisotropic_measure_face<GT>(u, x);
for (std::size_t i = 0; i < 3 * 3; i++)
vertex_curvatures.anisotropic_measure[i] += face_anisotropic_measure[i];
}
x.clear();
u.clear();
}
return vertex_curvatures;
}
Vertex_measures<GT> expand_interpolated_corrected_measure_vertex(Vertex_descriptor v)
{
std::queue<Face_descriptor> bfs_queue;
std::unordered_set<Face_descriptor> bfs_visited;
Point_3 vp = get(vpm, v);
Vector_3 c = Vector_3(vp.x(), vp.y(), vp.z());
Vertex_measures<GT> vertex_curvatures;
for (Face_descriptor f : faces_around_target(halfedge(v, pmesh), pmesh)) {
if (f != boost::graph_traits<PolygonMesh>::null_face())
{
bfs_queue.push(f);
bfs_visited.insert(f);
}
}
std::vector<Vector_3> x;
std::vector<Vector_3> u;
while (!bfs_queue.empty()) {
Face_descriptor fi = bfs_queue.front();
bfs_queue.pop();
// looping over vertices in face to get point coordinates
for (Vertex_descriptor vi : vertices_around_face(halfedge(fi, pmesh), pmesh))
{
Point_3 pi = get(vpm, vi);
x.push_back(Vector_3(pi.x(), pi.y(), pi.z()));
}
const FT f_ratio = face_in_ball_ratio<GT>(x, ball_radius, c);
if (f_ratio != 0.0)
{
for (Vertex_descriptor vi : vertices_around_face(halfedge(f, pmesh), pmesh))
{
u.push_back(get(vnm, vi));
}
vertex_curvatures.area_measure += f_ratio * get(mu0_map, fi);
if (is_mean_curvature_selected)
@ -699,6 +923,9 @@ namespace internal {
vertex_curvatures.anisotropic_measure[i] += f_ratio * face_anisotropic_measure[i];
}
x.clear();
u.clear();
for (Face_descriptor fj : faces_around_face(halfedge(fi, pmesh), pmesh))
{
if (bfs_visited.find(fj) == bfs_visited.end() && fj != boost::graph_traits<PolygonMesh>::null_face())
@ -713,13 +940,11 @@ namespace internal {
}
void compute_selected_curvatures() {
interpolated_corrected_all_measures_all_faces();
for (Vertex_descriptor v : vertices(pmesh))
{
Vertex_measures<GT> vertex_curvatures = (ball_radius < 0) ?
expand_interpolated_corrected_measure_vertex_no_radius(v) :
expand_interpolated_corrected_measure_vertex(v);
compute_expanded_interpolated_corrected_measure_vertex_no_radius(v) :
compute_expanded_interpolated_corrected_measure_vertex(v);
if (is_mean_curvature_selected) {
vertex_curvatures.area_measure != 0 ?
@ -745,7 +970,227 @@ namespace internal {
}
}
};
template<typename PolygonMesh, typename NamedParameters = parameters::Default_named_parameters>
class Interpolated_corrected_curvatures_element_computer
{
typedef typename GetGeomTraits<PolygonMesh, NamedParameters>::type GT;
typedef typename GT::FT FT;
typedef typename GT::Point_3 Point_3;
typedef typename GT::Vector_3 Vector_3;
typedef typename boost::graph_traits<PolygonMesh>::halfedge_descriptor Halfedge_descriptor;
typedef typename boost::graph_traits<PolygonMesh>::edge_descriptor Edge_descriptor;
typedef typename boost::graph_traits<PolygonMesh>::face_descriptor Face_descriptor;
typedef typename boost::graph_traits<PolygonMesh>::vertex_descriptor Vertex_descriptor;
typedef typename GetVertexPointMap<PolygonMesh, NamedParameters>::const_type Vertex_position_map;
typedef dynamic_vertex_property_t<Vector_3> Vector_map_tag;
typedef typename boost::property_map<PolygonMesh, Vector_map_tag>::const_type Default_vector_map;
typedef typename internal_np::Lookup_named_param_def<internal_np::vertex_normal_map_t,
NamedParameters,
Default_vector_map>::type Vertex_normal_map;
private:
const PolygonMesh& pmesh;
Vertex_position_map vpm;
Vertex_normal_map vnm;
FT ball_radius;
bool is_mean_curvature_selected;
bool is_gaussian_curvature_selected;
bool is_principal_curvature_selected;
void set_named_params(const NamedParameters& np)
{
using parameters::choose_parameter;
using parameters::get_parameter;
using parameters::is_default_parameter;
vpm = choose_parameter(get_parameter(np, CGAL::vertex_point),
get_const_property_map(CGAL::vertex_point, pmesh));
vnm = choose_parameter(get_parameter(np, internal_np::vertex_normal_map),
get(Vector_map_tag(), pmesh));
if (is_default_parameter<NamedParameters, internal_np::vertex_normal_map_t>::value)
compute_vertex_normals(pmesh, vnm, np);
const FT radius = choose_parameter(get_parameter(np, internal_np::ball_radius), -1);
is_mean_curvature_selected = !is_default_parameter<NamedParameters, internal_np::vertex_mean_curvature_map_t>::value;
is_gaussian_curvature_selected = !is_default_parameter<NamedParameters, internal_np::vertex_gaussian_curvature_map_t>::value;
is_principal_curvature_selected = !is_default_parameter<NamedParameters, internal_np::vertex_principal_curvature_map_t>::value;
set_ball_radius(radius);
}
void set_ball_radius(const FT radius) {
if (radius == 0)
ball_radius = average_edge_length<PolygonMesh, GT>(pmesh) * EXPANDING_RADIUS_EPSILON;
else
ball_radius = radius;
}
public:
Interpolated_corrected_curvatures_computer(const PolygonMesh& pmesh,
const NamedParameters& np = parameters::default_values()
) :
pmesh(pmesh)
{
set_named_params(np);
if (is_mean_curvature_selected || is_gaussian_curvature_selected || is_principal_curvature_selected)
{
set_property_maps();
}
}
private:
Vertex_measures<GT> expand_interpolated_corrected_measure_vertex_no_radius(Vertex_descriptor v)
{
Vertex_measures<GT> vertex_curvatures;
std::vector<Vector_3> x;
std::vector<Vector_3> u;
for (Face_descriptor f : faces_around_target(halfedge(v, pmesh), pmesh)) {
for (Vertex_descriptor v : vertices_around_face(halfedge(f, pmesh), pmesh))
{
Point_3 p = get(vpm, v);
x.push_back(Vector_3(p.x(), p.y(), p.z()));
u.push_back(get(vnm, v));
}
vertex_curvatures.area_measure += interpolated_corrected_area_measure_face<GT>(u, x);
if (is_mean_curvature_selected)
vertex_curvatures.mean_curvature_measure += interpolated_corrected_mean_curvature_measure_face<GT>(u, x);
if (is_gaussian_curvature_selected)
vertex_curvatures.gaussian_curvature_measure += interpolated_corrected_gaussian_curvature_measure_face<GT>(u, x);
if (is_principal_curvature_selected)
{
const std::array<FT, 3 * 3> face_anisotropic_measure = interpolated_corrected_anisotropic_measure_face<GT>(u, x);
for (std::size_t i = 0; i < 3 * 3; i++)
vertex_curvatures.anisotropic_measure[i] += face_anisotropic_measure[i];
}
x.clear();
u.clear();
}
return vertex_curvatures;
}
Vertex_measures<GT> expand_interpolated_corrected_measure_vertex(Vertex_descriptor v)
{
std::queue<Face_descriptor> bfs_queue;
std::unordered_set<Face_descriptor> bfs_visited;
Point_3 vp = get(vpm, v);
Vector_3 c = Vector_3(vp.x(), vp.y(), vp.z());
Vertex_measures<GT> vertex_curvatures;
for (Face_descriptor f : faces_around_target(halfedge(v, pmesh), pmesh)) {
if (f != boost::graph_traits<PolygonMesh>::null_face())
{
bfs_queue.push(f);
bfs_visited.insert(f);
}
}
std::vector<Vector_3> x;
std::vector<Vector_3> u;
while (!bfs_queue.empty()) {
Face_descriptor fi = bfs_queue.front();
bfs_queue.pop();
// looping over vertices in face to get point coordinates
for (Vertex_descriptor vi : vertices_around_face(halfedge(fi, pmesh), pmesh))
{
Point_3 pi = get(vpm, vi);
x.push_back(Vector_3(pi.x(), pi.y(), pi.z()));
}
const FT f_ratio = face_in_ball_ratio<GT>(x, ball_radius, c);
if (f_ratio != 0.0)
{
for (Vertex_descriptor vi : vertices_around_face(halfedge(f, pmesh), pmesh))
{
u.push_back(get(vnm, vi));
}
vertex_curvatures.area_measure += f_ratio * get(mu0_map, fi);
if (is_mean_curvature_selected)
vertex_curvatures.mean_curvature_measure += f_ratio * get(mu1_map, fi);
if (is_gaussian_curvature_selected)
vertex_curvatures.gaussian_curvature_measure += f_ratio * get(mu2_map, fi);
if (is_principal_curvature_selected)
{
const std::array<FT, 3 * 3> face_anisotropic_measure = get(muXY_map, fi);
for (std::size_t i = 0; i < 3 * 3; i++)
vertex_curvatures.anisotropic_measure[i] += f_ratio * face_anisotropic_measure[i];
}
x.clear();
u.clear();
for (Face_descriptor fj : faces_around_face(halfedge(fi, pmesh), pmesh))
{
if (bfs_visited.find(fj) == bfs_visited.end() && fj != boost::graph_traits<PolygonMesh>::null_face())
{
bfs_queue.push(fj);
bfs_visited.insert(fj);
}
}
}
}
return vertex_curvatures;
}
void compute_selected_curvatures() {
for (Vertex_descriptor v : vertices(pmesh))
{
Vertex_measures<GT> vertex_curvatures = (ball_radius < 0) ?
compute_expanded_interpolated_corrected_measure_vertex_no_radius(v) :
compute_expanded_interpolated_corrected_measure_vertex(v);
if (is_mean_curvature_selected) {
vertex_curvatures.area_measure != 0 ?
put(mean_curvature_map, v, 0.5 * vertex_curvatures.mean_curvature_measure / vertex_curvatures.area_measure) :
put(mean_curvature_map, v, 0);
}
if (is_gaussian_curvature_selected) {
vertex_curvatures.area_measure != 0 ?
put(gaussian_curvature_map, v, vertex_curvatures.gaussian_curvature_measure / vertex_curvatures.area_measure) :
put(gaussian_curvature_map, v, 0);
}
if (is_principal_curvature_selected) {
const Vector_3 v_normal = get(vnm, v);
const Principal_curvature<GT> principal_curvature = principal_curvature_from_anisotropic_measures<GT>(
vertex_curvatures.anisotropic_measure,
vertex_curvatures.area_measure,
v_normal
);
put(principal_curvature_map, v, principal_curvature);
}
}
}
};