Skip to content
Snippets Groups Projects
Commit f7de6b45 authored by Arch de Noé's avatar Arch de Noé
Browse files

chore: improved readability

parent 3f9ffb18
No related merge requests found
......@@ -5,6 +5,16 @@
#include "pmp/algorithms/differential_geometry.h"
// Monadic or else for optionals
template <typename T>
std::optional<T> operator|(std::optional<T> a, std::optional<T> b)
{
if (a.has_value())
return a;
else
return b;
}
MeshBVH::MeshBVH(pmp::SurfaceMesh &mesh) : _target_mesh(mesh)
{
// Compute face centroids
......@@ -75,10 +85,15 @@ std::shared_ptr<MeshBVH::Node> MeshBVH::split(face_iter_t first, face_iter_t las
pmp::Face MeshBVH::get_closest_face(pmp::Point point)
{
auto result = search_closest_face(point, _root, std::numeric_limits<float>::infinity());
if (result.has_value())
return result.value();
if (result)
{
return *result;
}
else
{
throw std::runtime_error("No face found");
}
}
std::optional<pmp::Face> MeshBVH::search_closest_face(pmp::Point const &point, std::shared_ptr<MeshBVH::Node> &node, float current_min_distance)
......@@ -87,7 +102,7 @@ std::optional<pmp::Face> MeshBVH::search_closest_face(pmp::Point const &point, s
/* Helper functions */
auto sqr_distance_to_bb = [&](pmp::BoundingBox &bb) -> float
auto squared_distance_to_bb = [&](pmp::BoundingBox &bb) -> float
{
pmp::Point point_on_bb;
......@@ -99,7 +114,7 @@ std::optional<pmp::Face> MeshBVH::search_closest_face(pmp::Point const &point, s
return pmp::sqrnorm(point_on_bb - point);
};
auto sqr_distance_to_face = [&](pmp::Face const &f) -> float
auto squared_distance_to_face = [&](pmp::Face const &f) -> float
{
auto face_iterator = _target_mesh.vertices(f).begin();
pmp::Vertex a = *(face_iterator++);
......@@ -115,26 +130,30 @@ std::optional<pmp::Face> MeshBVH::search_closest_face(pmp::Point const &point, s
auto is_closer = [&](pmp::Face const &f1, pmp::Face const &f2) -> bool
{
return sqr_distance_to_face(f1) < sqr_distance_to_face(f2);
return squared_distance_to_face(f1) < squared_distance_to_face(f2);
};
// Leaf case
/* -- Leaf case -- */
if (node->is_leaf())
{
return *std::min_element(node->_items.begin(), node->_items.end(), is_closer);
}
std::shared_ptr<MeshBVH::Node> first_seach_space;
std::shared_ptr<MeshBVH::Node> second_seach_space;
if (sqr_distance_to_bb(node->_left->_bounds) < sqr_distance_to_bb(node->_right->_bounds))
/* -- General case -- */
std::shared_ptr<MeshBVH::Node> first_search_space;
std::shared_ptr<MeshBVH::Node> second_search_space;
// Search closest first (heuristic)
if (squared_distance_to_bb(node->_left->_bounds) < squared_distance_to_bb(node->_right->_bounds))
{
first_seach_space = node->_left;
second_seach_space = node->_right;
first_search_space = node->_left;
second_search_space = node->_right;
}
else
{
first_seach_space = node->_right;
second_seach_space = node->_left;
first_search_space = node->_right;
second_search_space = node->_left;
}
std::optional<pmp::Face> first_candidate = std::nullopt;
......@@ -142,35 +161,26 @@ std::optional<pmp::Face> MeshBVH::search_closest_face(pmp::Point const &point, s
float local_min_distance = current_min_distance;
if (sqr_distance_to_bb(first_seach_space->_bounds) <= local_min_distance)
// Search first_search_space if closer than min distance
if (squared_distance_to_bb(first_search_space->_bounds) <= local_min_distance)
{
first_candidate = search_closest_face(point, first_seach_space, current_min_distance);
if (first_candidate.has_value())
local_min_distance = std::min(sqr_distance_to_face(first_candidate.value()), local_min_distance);
}
if (sqr_distance_to_bb(second_seach_space->_bounds) <= local_min_distance)
{
second_candidate = search_closest_face(point, second_seach_space, local_min_distance);
}
if (first_candidate.has_value())
{
if (second_candidate.has_value())
{
return is_closer(first_candidate.value(), second_candidate.value()) ? first_candidate : second_candidate;
}
else
first_candidate = search_closest_face(point, first_search_space, current_min_distance);
if (first_candidate)
{
return first_candidate;
local_min_distance = std::min(squared_distance_to_face(*first_candidate),
local_min_distance);
}
}
else if (second_candidate.has_value())
if (squared_distance_to_bb(second_search_space->_bounds) <= local_min_distance)
{
return second_candidate;
second_candidate = search_closest_face(point, second_search_space, local_min_distance);
}
else
if (first_candidate && second_candidate)
{
return std::nullopt;
return is_closer(*first_candidate, *second_candidate) ? first_candidate : second_candidate;
}
}
return first_candidate | second_candidate;
}
\ No newline at end of file
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment