change enumeration swith to explicit seeding API

This commit is contained in:
Lingjie Zhu 2017-08-28 15:23:26 +08:00
parent bd3dcc8ebc
commit 8e1cd3a2df
9 changed files with 112 additions and 91 deletions

View File

@ -64,7 +64,19 @@ int main(int argc, char *argv[])
std::cerr << "start initialization" << std::endl;
t0.reset();
t0.start();
l21_vsa.init_proxies(num_proxies, static_cast<L21VSA::Initialization>(init));
switch(init) {
case 0:
l21_vsa.seed_random(num_proxies);
break;
case 1:
l21_vsa.seed_incremental(num_proxies, 5);
break;
case 2:
l21_vsa.seed_hierarchical(num_proxies, 5);
break;
default:
return 1;
}
t0.stop();
std::cerr << "initialization time " << t0.time() << " sec." << std::endl;

View File

@ -35,7 +35,7 @@ int main()
l21_approx.set_metric(metric, proxy_fitting);
// initialize proxies randomly on the mesh
l21_approx.init_proxies(100, L21VSA::RandomInit);
l21_approx.seed_random(100);
// run the iteration to minimize the error
for (std::size_t i = 0; i < 30; ++i)

View File

@ -108,7 +108,7 @@ int main()
compact_approx.set_metric(metric, proxy_fitting);
// using 200 proxies to approximate the shape
compact_approx.init_proxies(200, CompactVSA::HierarchicalInit);
compact_approx.seed_hierarchical(200, 5);
for (std::size_t i = 0; i < 30; ++i)
compact_approx.run_one_step();

View File

@ -47,20 +47,28 @@ class VSA_approximation {
// public typedefs
public:
// Default typdefs
/// GeomTraits typdef
typedef typename CGAL::Default::Get<
GeomTraits_,
typename Kernel_traits<
typename boost::property_traits<VertexPointMap>::value_type
>::Kernel >::type GeomTraits;
/// ErrorMetric typdef
typedef typename CGAL::Default::Get<ErrorMetric_,
CGAL::L21Metric<TriangleMesh, VertexPointMap, GeomTraits> >::type ErrorMetric;
/// ProxyFitting typdef
typedef typename CGAL::Default::Get<ProxyFitting_,
CGAL::L21ProxyFitting<TriangleMesh, VertexPointMap, GeomTraits> >::type ProxyFitting;
/// Proxy typdef
typedef typename ErrorMetric::Proxy Proxy;
/// Enueration typdef
enum Initialization {
/// Random initialization
RandomInit,
/// Incremental initialization
IncrementalInit,
/// Hierarchical initialization
HierarchicalInit
};
@ -302,24 +310,81 @@ public:
}
/*!
* @brief Initialize by number of proxies.
* @param num_proxy number of proxies
* @param seeding_method select one of the seeding method: random, hierarchical, incremental
* @brief Random initialize proxies.
* @param num_seed number of proxies seed
* @return number of proxies initialized
*/
std::size_t init_proxies(const std::size_t num_proxy, const Initialization &seeding_method) {
std::size_t seed_random(const std::size_t num_seed) {
proxies.clear();
if (num_faces(*m_pmesh) < num_proxy)
if (num_faces(*m_pmesh) < num_seed)
return 0;
switch (seeding_method) {
case IncrementalInit:
return seed_incremental(num_proxy);
case HierarchicalInit:
return seed_hierarchical(num_proxy);
default:
return seed_random(num_proxy);
const std::size_t interval = num_faces(*m_pmesh) / num_seed;
std::size_t index = 0;
BOOST_FOREACH(face_descriptor f, faces(*m_pmesh)) {
if ((index++) % interval == 0) {
proxies.push_back(fit_new_proxy(f));
}
if (proxies.size() >= num_seed)
break;
}
return proxies.size();
}
/*!
* @brief Incremental initialize proxies.
* @param num_seed number of proxies seed
* @param inner_iteration number of iterations of coarse re-fitting
* before each incremental proxy insertion
* @return number of proxies initialized
*/
std::size_t seed_incremental(const std::size_t num_seed,
const std::size_t inner_iteration = 5) {
proxies.clear();
if (num_faces(*m_pmesh) < num_seed)
return 0;
// initialize a proxy and the proxy map to prepare for the insertion
proxies.push_back(fit_new_proxy(*(faces(*m_pmesh).first)));
BOOST_FOREACH(face_descriptor f, faces(*m_pmesh))
fproxy_map[f] = 0;
insert_proxy_furthest(num_seed - 1, inner_iteration);
return proxies.size();
}
/*!
* @brief Hierarchical initialize proxies.
* @param num_seed number of proxies seed
* @param inner_iteration number of iterations of coarse re-fitting
* before each hierarchical proxy insertion
* @return number of proxies initialized
*/
std::size_t seed_hierarchical(const std::size_t num_seed,
const std::size_t inner_iteration = 5) {
proxies.clear();
if (num_faces(*m_pmesh) < num_seed)
return 0;
// initialize 2 proxy
typename boost::graph_traits<TriangleMesh>::face_iterator
fitr = faces(*m_pmesh).first;
proxies.push_back(fit_new_proxy(*fitr));
proxies.push_back(fit_new_proxy(*(++fitr)));
while (proxies.size() < num_seed) {
for (std::size_t i = 0; i < inner_iteration; ++i) {
partition();
fit();
}
// add proxies by error diffusion
const std::size_t num_proxies = proxies.size();
const std::size_t num_proxies_to_be_added =
(num_proxies * 2 < num_seed) ? num_proxies : (num_seed - num_proxies);
insert_proxy_hierarchical(num_proxies_to_be_added);
}
return proxies.size();
}
/*!
@ -837,71 +902,7 @@ public:
// private member functions
private:
/*!
* @brief Random initialize proxies.
* @param initial_px number of proxies
* @return number of proxies initialized
*/
std::size_t seed_random(const std::size_t initial_px) {
const std::size_t interval = num_faces(*m_pmesh) / initial_px;
std::size_t index = 0;
BOOST_FOREACH(face_descriptor f, faces(*m_pmesh)) {
if ((index++) % interval == 0) {
proxies.push_back(fit_new_proxy(f));
}
if (proxies.size() >= initial_px)
break;
}
return proxies.size();
}
/*!
* @brief Incremental initialize proxies.
* @param initial_px number of proxies
* @param inner_iteration number of iterations of coarse re-fitting
* before each incremental proxy insertion
* @return number of proxies initialized
*/
std::size_t seed_incremental(const std::size_t initial_px,
const std::size_t inner_iteration = 5) {
// initialize a proxy and the proxy map to prepare for the insertion
proxies.push_back(fit_new_proxy(*(faces(*m_pmesh).first)));
BOOST_FOREACH(face_descriptor f, faces(*m_pmesh))
fproxy_map[f] = 0;
insert_proxy_furthest(initial_px - 1, inner_iteration);
return proxies.size();
}
/*!
* @brief Hierarchical initialize proxies.
* @param initial_px number of proxies
* @param inner_iteration number of iterations of coarse re-fitting
* before each hierarchical proxy insertion
* @return number of proxies initialized
*/
std::size_t seed_hierarchical(const std::size_t initial_px,
const std::size_t inner_iteration = 5) {
// initialize 2 proxy
typename boost::graph_traits<TriangleMesh>::face_iterator
fitr = faces(*m_pmesh).first;
proxies.push_back(fit_new_proxy(*fitr));
proxies.push_back(fit_new_proxy(*(++fitr)));
while (proxies.size() < initial_px) {
for (std::size_t i = 0; i < inner_iteration; ++i) {
partition();
fit();
}
// add proxies by error diffusion
const std::size_t num_proxies = proxies.size();
const std::size_t num_proxies_to_be_added =
(num_proxies * 2 < initial_px) ? num_proxies : (initial_px - num_proxies);
insert_proxy_hierarchical(num_proxies_to_be_added);
}
return proxies.size();
}
/*!
* @brief Inserts a proxy at the furthest facet of the region with the maximum fitting error.

View File

@ -531,9 +531,7 @@ private:
const VertexPointMap point_pmap;
};
/*!
* Specialization.
*/
// specialization.
template <typename TriangleMesh,
typename GeomTraits,
typename PlaneProxy>

View File

@ -92,11 +92,21 @@ bool vsa_mesh_approximation(const TriangleMesh &tm_in,
std::size_t num_iterations = choose_param(get_param(np, internal_np::number_of_iterations), 10);
std::cout << "#px = " << num_proxies << ", #itr = " << num_iterations << std::endl;
int init = choose_param(get_param(np, internal_np::init_method), 0);
if (init < 0 || init > 2)
std::size_t init = choose_param(get_param(np, internal_np::init_method), 0);
switch (static_cast<typename VSAL21::Initialization>(init)) {
case VSAL21::RandomInit:
vsa_l21.seed_random(num_proxies);
break;
case VSAL21::IncrementalInit:
vsa_l21.seed_incremental(num_proxies, 5);
break;
case VSAL21::HierarchicalInit:
vsa_l21.seed_hierarchical(num_proxies, 5);
break;
default:
std::cout << "Error: invalid initialization method parameter." << std::endl;
return false;
vsa_l21.init_proxies(num_proxies, static_cast<typename VSAL21::Initialization>(init));
}
for (std::size_t i = 0; i < num_iterations; ++i)
vsa_l21.run_one_step();

View File

@ -53,7 +53,7 @@ int main()
// random init and run
std::cout << "random init and run" << std::endl;
l2_approx.init_proxies(10, L2VSA::RandomInit);
l2_approx.seed_random(10);
for (std::size_t i = 0; i < 10; ++i)
l2_approx.run_one_step();
if (l2_approx.get_proxies_size() != 10)

View File

@ -51,7 +51,7 @@ int main()
L21ProxyFitting l21_fitting(mesh);
vsa_l21.set_metric(l21_metric, l21_fitting);
vsa_l21.init_proxies(100, L21VSA::RandomInit);
vsa_l21.seed_random(100);
std::vector<FT> error;
for (std::size_t i = 0; i < 30; ++i)
error.push_back(vsa_l21.run_one_step());

View File

@ -99,7 +99,7 @@ int main()
compact_approx.set_metric(metric, proxy_fitting);
std::cout << "random init and run" << std::endl;
compact_approx.init_proxies(20, CompactVSA::RandomInit);
compact_approx.seed_random(20);
for (std::size_t i = 0; i < 20; ++i)
compact_approx.run_one_step();
if (compact_approx.get_proxies_size() != 20)