mirror of https://github.com/CGAL/cgal
remove optional
adjust parameters before init, unspecified / out-of-bounds parameters are treated equally
This commit is contained in:
parent
07b923383c
commit
dad6a07e00
|
|
@ -327,64 +327,37 @@ public:
|
||||||
|
|
||||||
const Surface_mesh_approximation::Seeding_method method = choose_param(
|
const Surface_mesh_approximation::Seeding_method method = choose_param(
|
||||||
get_param(np, internal_np::seeding_method), Surface_mesh_approximation::HIERARCHICAL);
|
get_param(np, internal_np::seeding_method), Surface_mesh_approximation::HIERARCHICAL);
|
||||||
const std::size_t max_nb_proxies = choose_param(
|
std::size_t max_nb_proxies = choose_param(
|
||||||
get_param(np, internal_np::max_number_of_proxies), m_nb_of_faces);
|
get_param(np, internal_np::max_number_of_proxies), 0);
|
||||||
const FT min_error_drop = choose_param(
|
FT min_error_drop = choose_param(
|
||||||
get_param(np, internal_np::min_error_drop), FT(0));
|
get_param(np, internal_np::min_error_drop), FT(0.0));
|
||||||
const std::size_t nb_relaxations = choose_param(get_param(np, internal_np::number_of_relaxations), 5);
|
const std::size_t nb_relaxations = choose_param(
|
||||||
|
get_param(np, internal_np::number_of_relaxations), 5);
|
||||||
|
|
||||||
// maximum number of proxies internally, maybe better choice?
|
// adjust parameters
|
||||||
const std::size_t nb_px = m_nb_of_faces / 3;
|
if (max_nb_proxies < (m_nb_of_faces / 3) && max_nb_proxies > 0) {
|
||||||
|
if(!(min_error_drop < FT(1.0)) || !(min_error_drop > FT(0.0)))
|
||||||
|
min_error_drop = FT(-1.0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
max_nb_proxies = m_nb_of_faces / 3;
|
||||||
|
if (!(min_error_drop < FT(1.0)) || !(min_error_drop > FT(0.0)))
|
||||||
|
min_error_drop = FT(0.1);
|
||||||
|
}
|
||||||
|
|
||||||
// initialize proxies and the proxy map to prepare for insertion
|
// initialize proxies and the proxy map to prepare for insertion
|
||||||
bootstrap_from_connected_components();
|
bootstrap_from_connected_components();
|
||||||
|
|
||||||
if (min_error_drop > FT(0.0) && min_error_drop < FT(1.0)) {
|
|
||||||
// as long as minimum error is specified and valid
|
|
||||||
// maximum number of proxies always exists, no matter specified or not or out of range
|
|
||||||
// there is always a maximum number of proxies explicitly (max_nb_proxies) or implicitly (nb_px)
|
|
||||||
std::size_t max_nb_px_adjusted = nb_px;
|
|
||||||
if (max_nb_proxies < nb_px)
|
|
||||||
max_nb_px_adjusted = max_nb_proxies;
|
|
||||||
switch (method) {
|
switch (method) {
|
||||||
case Surface_mesh_approximation::RANDOM:
|
case Surface_mesh_approximation::RANDOM:
|
||||||
return init_random_error(max_nb_px_adjusted, min_error_drop, nb_relaxations);
|
return init_random(max_nb_proxies, min_error_drop, nb_relaxations);
|
||||||
case Surface_mesh_approximation::INCREMENTAL:
|
case Surface_mesh_approximation::INCREMENTAL:
|
||||||
return init_incremental_error(max_nb_px_adjusted, min_error_drop, nb_relaxations);
|
return init_incremental(max_nb_proxies, min_error_drop, nb_relaxations);
|
||||||
case Surface_mesh_approximation::HIERARCHICAL:
|
case Surface_mesh_approximation::HIERARCHICAL:
|
||||||
return init_hierarchical_error(max_nb_px_adjusted, min_error_drop, nb_relaxations);
|
return init_hierarchical(max_nb_proxies, min_error_drop, nb_relaxations);
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (max_nb_proxies < nb_px) {
|
|
||||||
// no valid min_error_drop provided, only max_nb_proxies
|
|
||||||
switch (method) {
|
|
||||||
case Surface_mesh_approximation::RANDOM:
|
|
||||||
return init_random(max_nb_proxies, nb_relaxations);
|
|
||||||
case Surface_mesh_approximation::INCREMENTAL:
|
|
||||||
return init_incremental(max_nb_proxies, nb_relaxations);
|
|
||||||
case Surface_mesh_approximation::HIERARCHICAL:
|
|
||||||
return init_hierarchical(max_nb_proxies, nb_relaxations);
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// both parameters are unspecified or out of range
|
|
||||||
const FT e(0.1);
|
|
||||||
switch (method) {
|
|
||||||
case Surface_mesh_approximation::RANDOM:
|
|
||||||
return init_random_error(nb_px, e, nb_relaxations);
|
|
||||||
case Surface_mesh_approximation::INCREMENTAL:
|
|
||||||
return init_incremental_error(nb_px, e, nb_relaxations);
|
|
||||||
case Surface_mesh_approximation::HIERARCHICAL:
|
|
||||||
return init_hierarchical_error(nb_px, e, nb_relaxations);
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief runs the partitioning and fitting processes on the whole surface.
|
* @brief runs the partitioning and fitting processes on the whole surface.
|
||||||
|
|
@ -1023,81 +996,31 @@ public:
|
||||||
|
|
||||||
// private member functions
|
// private member functions
|
||||||
private:
|
private:
|
||||||
/*!
|
|
||||||
* @brief randomly initializes proxies to target number of proxies.
|
|
||||||
* @note To ensure the randomness, call `std::srand()` beforehand.
|
|
||||||
* @param max_nb_proxies maximum number of proxies,
|
|
||||||
* should be in range `(nb_connected_components, nb_faces)`
|
|
||||||
* @param nb_iterations number of re-fitting iterations
|
|
||||||
* @return number of proxies initialized
|
|
||||||
*/
|
|
||||||
std::size_t init_random(const std::size_t max_nb_proxies,
|
|
||||||
const std::size_t nb_iterations) {
|
|
||||||
// pick from current non seed faces randomly
|
|
||||||
std::vector<face_descriptor> picked_seeds;
|
|
||||||
if (random_pick_non_seed_faces(max_nb_proxies - m_proxies.size(), picked_seeds)) {
|
|
||||||
BOOST_FOREACH(face_descriptor f, picked_seeds)
|
|
||||||
add_one_proxy_at(f);
|
|
||||||
run(nb_iterations);
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_proxies.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* @brief incrementally initializes proxies to target number of proxies.
|
|
||||||
* @param max_nb_proxies maximum number of proxies,
|
|
||||||
* should be in range `(nb_connected_components, nb_faces)`
|
|
||||||
* @param nb_iterations number of re-fitting iterations
|
|
||||||
* before each incremental proxy insertion
|
|
||||||
* @return number of proxies initialized
|
|
||||||
*/
|
|
||||||
std::size_t init_incremental(const std::size_t max_nb_proxies,
|
|
||||||
const std::size_t nb_iterations) {
|
|
||||||
if (m_proxies.size() < max_nb_proxies)
|
|
||||||
add_to_furthest_proxies(max_nb_proxies - m_proxies.size(), nb_iterations);
|
|
||||||
|
|
||||||
return m_proxies.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* @brief hierarchically initializes proxies to target number of proxies.
|
|
||||||
* @param max_nb_proxies maximum number of proxies,
|
|
||||||
* should be in range `(nb_connected_components, nb_faces)`
|
|
||||||
* @param nb_iterations number of re-fitting iterations
|
|
||||||
* before each hierarchical proxy insertion
|
|
||||||
* @return number of proxies initialized
|
|
||||||
*/
|
|
||||||
std::size_t init_hierarchical(const std::size_t max_nb_proxies,
|
|
||||||
const std::size_t nb_iterations) {
|
|
||||||
while (m_proxies.size() < max_nb_proxies) {
|
|
||||||
// try to double current number of proxies each time
|
|
||||||
std::size_t target_px = m_proxies.size();
|
|
||||||
if (target_px * 2 > max_nb_proxies)
|
|
||||||
target_px = max_nb_proxies;
|
|
||||||
else
|
|
||||||
target_px *= 2;
|
|
||||||
// add proxies by error diffusion
|
|
||||||
add_proxies_error_diffusion(target_px - m_proxies.size());
|
|
||||||
run(nb_iterations);
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_proxies.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief randomly initializes proxies
|
* @brief randomly initializes proxies
|
||||||
* with both maximum number of proxies and minimum error drop stop criteria,
|
* with both maximum number of proxies and minimum error drop stop criteria,
|
||||||
* where the first criterion met stops the seeding.
|
* where the first criterion met stops the seeding.
|
||||||
* @note To ensure the randomness, call `std::srand()` beforehand.
|
* @note To ensure the randomness, call `std::srand()` beforehand.
|
||||||
* @param max_nb_proxies maximum number of proxies, should be in range `(nb_connected_components, nb_faces / 3)`
|
* @param max_nb_proxies maximum number of proxies, should be in range `(nb_connected_components, nb_faces / 3)`
|
||||||
* @param min_error_drop minimum error drop, should be in range `(0.0, 1.0)`
|
* @param min_error_drop minimum error drop, should be in range `(0.0, 1.0)`,
|
||||||
* @param nb_iterations number of re-fitting iterations
|
* negative value is ignored
|
||||||
|
* @param nb_relaxations number of re-fitting iterations
|
||||||
* @return number of proxies initialized
|
* @return number of proxies initialized
|
||||||
*/
|
*/
|
||||||
std::size_t init_random_error(const std::size_t max_nb_proxies,
|
std::size_t init_random(const std::size_t max_nb_proxies,
|
||||||
const FT min_error_drop,
|
const FT min_error_drop,
|
||||||
const std::size_t nb_iterations) {
|
const std::size_t nb_relaxations) {
|
||||||
|
|
||||||
|
if (min_error_drop >= FT(0.0)) {
|
||||||
|
// pick from current non seed faces randomly
|
||||||
|
std::vector<face_descriptor> picked_seeds;
|
||||||
|
if (random_pick_non_seed_faces(max_nb_proxies - m_proxies.size(), picked_seeds)) {
|
||||||
|
BOOST_FOREACH(face_descriptor f, picked_seeds)
|
||||||
|
add_one_proxy_at(f);
|
||||||
|
run(nb_relaxations);
|
||||||
|
}
|
||||||
|
return m_proxies.size();
|
||||||
|
}
|
||||||
|
|
||||||
const FT initial_err = compute_total_error();
|
const FT initial_err = compute_total_error();
|
||||||
FT error_drop = min_error_drop * FT(2.0);
|
FT error_drop = min_error_drop * FT(2.0);
|
||||||
|
|
@ -1114,7 +1037,7 @@ private:
|
||||||
|
|
||||||
BOOST_FOREACH(face_descriptor f, picked_seeds)
|
BOOST_FOREACH(face_descriptor f, picked_seeds)
|
||||||
add_one_proxy_at(f);
|
add_one_proxy_at(f);
|
||||||
const FT err = run(nb_iterations);
|
const FT err = run(nb_relaxations);
|
||||||
error_drop = err / initial_err;
|
error_drop = err / initial_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1126,18 +1049,26 @@ private:
|
||||||
* with both maximum number of proxies and minimum error drop stop criteria,
|
* with both maximum number of proxies and minimum error drop stop criteria,
|
||||||
* The first criterion met stops the seeding.
|
* The first criterion met stops the seeding.
|
||||||
* @param max_nb_proxies maximum number of proxies, should be in range `(nb_connected_components, nb_faces / 3)`
|
* @param max_nb_proxies maximum number of proxies, should be in range `(nb_connected_components, nb_faces / 3)`
|
||||||
* @param min_error_drop minimum error drop, should be in range `(0.0, 1.0)`
|
* @param min_error_drop minimum error drop, should be in range `(0.0, 1.0)`,
|
||||||
* @param nb_iterations number of re-fitting iterations
|
* negative value is ignored
|
||||||
|
* @param nb_relaxations number of re-fitting iterations
|
||||||
* @return number of proxies initialized
|
* @return number of proxies initialized
|
||||||
*/
|
*/
|
||||||
std::size_t init_incremental_error(const std::size_t max_nb_proxies,
|
std::size_t init_incremental(const std::size_t max_nb_proxies,
|
||||||
const FT min_error_drop,
|
const FT min_error_drop,
|
||||||
const std::size_t nb_iterations) {
|
const std::size_t nb_relaxations) {
|
||||||
|
|
||||||
|
if (min_error_drop >= FT(0.0)) {
|
||||||
|
if (m_proxies.size() < max_nb_proxies)
|
||||||
|
add_to_furthest_proxies(max_nb_proxies - m_proxies.size(), nb_relaxations);
|
||||||
|
return m_proxies.size();
|
||||||
|
}
|
||||||
|
|
||||||
const FT initial_err = compute_total_error();
|
const FT initial_err = compute_total_error();
|
||||||
FT error_drop = min_error_drop * FT(2.0);
|
FT error_drop = min_error_drop * FT(2.0);
|
||||||
while (m_proxies.size() < max_nb_proxies && error_drop > min_error_drop) {
|
while (m_proxies.size() < max_nb_proxies && error_drop > min_error_drop) {
|
||||||
add_to_furthest_proxy();
|
add_to_furthest_proxy();
|
||||||
const FT err = run(nb_iterations);
|
const FT err = run(nb_relaxations);
|
||||||
error_drop = err / initial_err;
|
error_drop = err / initial_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1149,15 +1080,17 @@ private:
|
||||||
* with both maximum number of proxies and minimum error drop stop criteria,
|
* with both maximum number of proxies and minimum error drop stop criteria,
|
||||||
* where the first criterion met stops the seeding.
|
* where the first criterion met stops the seeding.
|
||||||
* @param max_nb_proxies maximum number of proxies, should be in range `(nb_connected_components, nb_faces / 3)`
|
* @param max_nb_proxies maximum number of proxies, should be in range `(nb_connected_components, nb_faces / 3)`
|
||||||
* @param min_error_drop minimum error drop, should be in range `(0.0, 1.0)`
|
* @param min_error_drop minimum error drop, should be in range `(0.0, 1.0)`,
|
||||||
* @param nb_iterations number of re-fitting iterations
|
* negative value is ignored
|
||||||
|
* @param nb_relaxations number of re-fitting iterations
|
||||||
* @return number of proxies initialized
|
* @return number of proxies initialized
|
||||||
*/
|
*/
|
||||||
std::size_t init_hierarchical_error(const std::size_t max_nb_proxies,
|
std::size_t init_hierarchical(const std::size_t max_nb_proxies,
|
||||||
const FT min_error_drop,
|
const FT min_error_drop,
|
||||||
const std::size_t nb_iterations) {
|
const std::size_t nb_relaxations) {
|
||||||
|
|
||||||
const FT initial_err = compute_total_error();
|
const FT initial_err = compute_total_error();
|
||||||
FT error_drop = min_error_drop * FT(2.0);
|
FT error_drop = min_error_drop >= FT(0.0) ? FT(1.0) : min_error_drop * FT(2.0);
|
||||||
while (m_proxies.size() < max_nb_proxies && error_drop > min_error_drop) {
|
while (m_proxies.size() < max_nb_proxies && error_drop > min_error_drop) {
|
||||||
// try to double current number of proxies each time
|
// try to double current number of proxies each time
|
||||||
std::size_t target_px = m_proxies.size();
|
std::size_t target_px = m_proxies.size();
|
||||||
|
|
@ -1166,7 +1099,7 @@ private:
|
||||||
else
|
else
|
||||||
target_px *= 2;
|
target_px *= 2;
|
||||||
add_proxies_error_diffusion(target_px - m_proxies.size());
|
add_proxies_error_diffusion(target_px - m_proxies.size());
|
||||||
const FT err = run(nb_iterations);
|
const FT err = run(nb_relaxations);
|
||||||
error_drop = err / initial_err;
|
error_drop = err / initial_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue