mirror of https://github.com/CGAL/cgal
parent
aa695bdf6a
commit
a57c658ca7
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
project( Surface_mesh_approximation )
|
project( Surface_mesh_approximation )
|
||||||
|
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 2.8.11)
|
cmake_minimum_required(VERSION 2.8.11)
|
||||||
|
|
||||||
# CGAL and its components
|
# CGAL and its components
|
||||||
|
|
@ -44,10 +43,10 @@ include_directories( BEFORE ../../include )
|
||||||
|
|
||||||
include( CGAL_CreateSingleSourceCGALProgram )
|
include( CGAL_CreateSingleSourceCGALProgram )
|
||||||
|
|
||||||
create_single_source_cgal_program( "vsa_class_interface_example.cpp" )
|
|
||||||
|
|
||||||
create_single_source_cgal_program( "vsa_example.cpp" )
|
create_single_source_cgal_program( "vsa_example.cpp" )
|
||||||
|
|
||||||
|
create_single_source_cgal_program( "vsa_class_interface_example.cpp" )
|
||||||
|
|
||||||
create_single_source_cgal_program( "vsa_metric_example.cpp" )
|
create_single_source_cgal_program( "vsa_metric_example.cpp" )
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ typedef L21VSA::ProxyFitting L21ProxyFitting;
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
// read Polyhedron
|
// create polyhedral surface and read input mesh
|
||||||
Polyhedron input;
|
Polyhedron input;
|
||||||
std::ifstream file("data/bear.off");
|
std::ifstream file("data/bear.off");
|
||||||
if (!file || !(file >> input) || input.empty()) {
|
if (!file || !(file >> input) || input.empty()) {
|
||||||
|
|
@ -29,24 +29,26 @@ int main()
|
||||||
// create VSA L21 metric approximation algorithm instance
|
// create VSA L21 metric approximation algorithm instance
|
||||||
L21VSA l21_approx(input,
|
L21VSA l21_approx(input,
|
||||||
get(boost::vertex_point, const_cast<Polyhedron &>(input)));
|
get(boost::vertex_point, const_cast<Polyhedron &>(input)));
|
||||||
|
|
||||||
// set error and fitting functors
|
// set error and fitting functors
|
||||||
L21Metric metric(input);
|
L21Metric metric(input);
|
||||||
L21ProxyFitting proxy_fitting(input);
|
L21ProxyFitting proxy_fitting(input);
|
||||||
l21_approx.set_metric(metric, proxy_fitting);
|
l21_approx.set_metric(metric, proxy_fitting);
|
||||||
|
|
||||||
// initialize proxies randomly on the mesh
|
// initialize 100 random proxies
|
||||||
l21_approx.init_by_number(CGAL::VSA_seeding::Random, 100);
|
l21_approx.init_by_number(CGAL::VSA_seeding::Random, 100);
|
||||||
|
|
||||||
// run the iteration to minimize the error
|
// run 30 iterations to reduce the approximation error
|
||||||
for (std::size_t i = 0; i < 30; ++i)
|
for (std::size_t i = 0; i < 30; ++i)
|
||||||
l21_approx.run_one_step();
|
l21_approx.run_one_step();
|
||||||
|
|
||||||
// add proxies to the one with the maximum fitting error
|
// add proxies to the one with the maximum fitting error
|
||||||
|
// and run 10 iterations
|
||||||
l21_approx.add_proxies_furthest(3, 5);
|
l21_approx.add_proxies_furthest(3, 5);
|
||||||
for (std::size_t i = 0; i < 10; ++i)
|
for (std::size_t i = 0; i < 10; ++i)
|
||||||
l21_approx.run_one_step();
|
l21_approx.run_one_step();
|
||||||
|
|
||||||
// merge and teleport the proxies from local minimal
|
// teleport 2 proxies from local minima
|
||||||
l21_approx.teleport_proxies(2);
|
l21_approx.teleport_proxies(2);
|
||||||
for (std::size_t i = 0; i < 10; ++i)
|
for (std::size_t i = 0; i < 10; ++i)
|
||||||
l21_approx.run_one_step();
|
l21_approx.run_one_step();
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ typedef CGAL::Polyhedron_3<Kernel> Polyhedron;
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
// create and read Polyhedron
|
// create polyhedral surface and read input mesh
|
||||||
Polyhedron input;
|
Polyhedron input;
|
||||||
std::ifstream file("data/bear.off");
|
std::ifstream file("data/bear.off");
|
||||||
if (!file || !(file >> input) || input.empty()) {
|
if (!file || !(file >> input) || input.empty()) {
|
||||||
|
|
@ -20,7 +20,7 @@ int main()
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// output data
|
// output polyhedral surface and triangle soup
|
||||||
Polyhedron output;
|
Polyhedron output;
|
||||||
std::vector<std::size_t> triangles;
|
std::vector<std::size_t> triangles;
|
||||||
std::vector<Kernel::Point_3> anchors;
|
std::vector<Kernel::Point_3> anchors;
|
||||||
|
|
@ -30,10 +30,10 @@ int main()
|
||||||
CGAL::VSA::parameters::init_by_number(200). // seeding by target number of proxies
|
CGAL::VSA::parameters::init_by_number(200). // seeding by target number of proxies
|
||||||
init_method(CGAL::VSA_seeding::Hierarchical). // hierarchical init
|
init_method(CGAL::VSA_seeding::Hierarchical). // hierarchical init
|
||||||
iterations(30). // number of relaxation iterations after seeding
|
iterations(30). // number of relaxation iterations after seeding
|
||||||
anchor_point(std::back_inserter(anchors)). // get anchor points
|
anchor_point(std::back_inserter(anchors)). // get anchor vertices
|
||||||
indexed_triangles(std::back_inserter(triangles))); // get indexed triangles
|
indexed_triangles(std::back_inserter(triangles))); // get indexed triangles
|
||||||
|
|
||||||
std::cout << "#anchors: " << anchors.size() << std::endl;
|
std::cout << "#anchor vertices: " << anchors.size() << std::endl;
|
||||||
std::cout << "#triangles: " << triangles.size() << std::endl;
|
std::cout << "#triangles: " << triangles.size() << std::endl;
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|
|
||||||
|
|
@ -23,19 +23,20 @@ typedef boost::property_map<Polyhedron, boost::vertex_point_t>::type VertexPoint
|
||||||
typedef boost::associative_property_map<std::map<Facet_handle, FT> > FacetAreaMap;
|
typedef boost::associative_property_map<std::map<Facet_handle, FT> > FacetAreaMap;
|
||||||
typedef boost::associative_property_map<std::map<Facet_handle, Point> > FacetCenterMap;
|
typedef boost::associative_property_map<std::map<Facet_handle, Point> > FacetCenterMap;
|
||||||
|
|
||||||
// use a point as proxy
|
// use point as proxy
|
||||||
typedef Point PointProxy;
|
typedef Point PointProxy;
|
||||||
|
|
||||||
// user defined point-wise compact metric
|
// user-defined "compact" error metric
|
||||||
struct CompactMetric {
|
struct CompactMetric {
|
||||||
typedef PointProxy Proxy;
|
typedef PointProxy Proxy;
|
||||||
|
|
||||||
// keeping a precomputed property map to speed up the computation
|
// we keep a precomputed property map to speed up computations
|
||||||
CompactMetric(const FacetCenterMap &_center_pmap)
|
CompactMetric(const FacetCenterMap &_center_pmap)
|
||||||
: center_pmap(_center_pmap) {}
|
: center_pmap(_center_pmap) {}
|
||||||
|
|
||||||
// calculate the error of a facet to a proxy
|
// compute and return error from a facet to a proxy,
|
||||||
// here is just the Euclidean distance
|
// defined as the Euclidean distance between
|
||||||
|
// the facet center of mass and proxy point.
|
||||||
FT operator()(const Facet_handle &f, const Proxy &px) const {
|
FT operator()(const Facet_handle &f, const Proxy &px) const {
|
||||||
return FT(std::sqrt(CGAL::to_double(
|
return FT(std::sqrt(CGAL::to_double(
|
||||||
CGAL::squared_distance(center_pmap[f], px))));
|
CGAL::squared_distance(center_pmap[f], px))));
|
||||||
|
|
@ -48,21 +49,22 @@ struct CompactMetric {
|
||||||
struct PointProxyFitting {
|
struct PointProxyFitting {
|
||||||
typedef PointProxy Proxy;
|
typedef PointProxy Proxy;
|
||||||
|
|
||||||
// keeping precomputed property maps to speed up the computation
|
// we keep a precomputed property map to speed up computations
|
||||||
PointProxyFitting(const FacetCenterMap &_center_pmap, const FacetAreaMap &_area_pmap)
|
PointProxyFitting(const FacetCenterMap &_center_pmap, const FacetAreaMap &_area_pmap)
|
||||||
: center_pmap(_center_pmap), area_pmap(_area_pmap) {}
|
: center_pmap(_center_pmap), area_pmap(_area_pmap) {}
|
||||||
|
|
||||||
// a template functor fit a new proxy from a range of facets
|
// template functor to compute a best-fit
|
||||||
|
// proxy from a range of facets
|
||||||
template<typename FacetIterator>
|
template<typename FacetIterator>
|
||||||
Proxy operator()(const FacetIterator beg, const FacetIterator end) const {
|
Proxy operator()(const FacetIterator beg, const FacetIterator end) const {
|
||||||
// fitting center
|
// fitting center
|
||||||
Vector center = CGAL::NULL_VECTOR;
|
Vector center = CGAL::NULL_VECTOR;
|
||||||
FT area = FT(0.0);
|
FT sum_areas = FT(0.0);
|
||||||
for (FacetIterator fitr = beg; fitr != end; ++fitr) {
|
for (FacetIterator fitr = beg; fitr != end; ++fitr) {
|
||||||
center = center + (center_pmap[*fitr] - CGAL::ORIGIN) * area_pmap[*fitr];
|
center = center + (center_pmap[*fitr] - CGAL::ORIGIN) * area_pmap[*fitr];
|
||||||
area += area_pmap[*fitr];
|
sum_areas += area_pmap[*fitr];
|
||||||
}
|
}
|
||||||
center = center / area;
|
center = center / sum_areas;
|
||||||
return CGAL::ORIGIN + center;
|
return CGAL::ORIGIN + center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -74,7 +76,7 @@ typedef CGAL::VSA_approximation<Polyhedron, VertexPointMap,
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
// create and read Polyhedron
|
// create polyhedral surface and read input mesh
|
||||||
Polyhedron input;
|
Polyhedron input;
|
||||||
std::ifstream file("data/bear.off");
|
std::ifstream file("data/bear.off");
|
||||||
if (!file || !(file >> input) || input.empty()) {
|
if (!file || !(file >> input) || input.empty()) {
|
||||||
|
|
@ -107,7 +109,7 @@ int main()
|
||||||
PointProxyFitting proxy_fitting(center_pmap, area_pmap);
|
PointProxyFitting proxy_fitting(center_pmap, area_pmap);
|
||||||
compact_approx.set_metric(metric, proxy_fitting);
|
compact_approx.set_metric(metric, proxy_fitting);
|
||||||
|
|
||||||
// using 200 proxies to approximate the shape
|
// approximation via 200 proxies and 30 iterations
|
||||||
compact_approx.init_by_number(CGAL::VSA_seeding::Hierarchical, 200);
|
compact_approx.init_by_number(CGAL::VSA_seeding::Hierarchical, 200);
|
||||||
for (std::size_t i = 0; i < 30; ++i)
|
for (std::size_t i = 0; i < 30; ++i)
|
||||||
compact_approx.run_one_step();
|
compact_approx.run_one_step();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue