mirror of https://github.com/CGAL/cgal
134 lines
3.6 KiB
C++
134 lines
3.6 KiB
C++
|
|
//#define CGAL_PMP_REMESHING_DEBUG
|
|
|
|
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
|
#include <CGAL/Surface_mesh.h>
|
|
#include <CGAL/boost/graph/graph_traits_Surface_mesh.h>
|
|
|
|
#include <CGAL/Polygon_mesh_processing/remesh.h>
|
|
#include <CGAL/Polygon_mesh_processing/get_border.h>
|
|
|
|
#include <CGAL/Timer.h>
|
|
#include <boost/foreach.hpp>
|
|
#include <fstream>
|
|
#include <vector>
|
|
#include <cstdlib>
|
|
|
|
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
|
typedef CGAL::Surface_mesh<K::Point_3> Mesh;
|
|
|
|
typedef boost::graph_traits<Mesh>::halfedge_descriptor halfedge_descriptor;
|
|
typedef boost::graph_traits<Mesh>::edge_descriptor edge_descriptor;
|
|
typedef boost::graph_traits<Mesh>::vertex_descriptor vertex_descriptor;
|
|
typedef boost::graph_traits<Mesh>::face_descriptor face_descriptor;
|
|
|
|
// extract vertices which are at most k (inclusive) far from vertex v
|
|
std::vector<vertex_descriptor> extract_k_ring(vertex_descriptor v,
|
|
int k,
|
|
const Mesh& m)
|
|
{
|
|
vertex_descriptor vv = v;
|
|
|
|
std::map<vertex_descriptor, int> D;
|
|
std::vector<vertex_descriptor> Q;
|
|
Q.push_back(vv);
|
|
D[vv] = 0;
|
|
|
|
std::size_t current_index = 0;
|
|
int dist_v;
|
|
while (current_index < Q.size() && (dist_v = D[Q[current_index]]) < k)
|
|
{
|
|
vv = Q[current_index++];
|
|
BOOST_FOREACH(halfedge_descriptor he,
|
|
halfedges_around_target(halfedge(vv,m), m))
|
|
{
|
|
vertex_descriptor new_v = source(he, m);
|
|
if (D.insert(std::make_pair(new_v, dist_v + 1)).second) {
|
|
Q.push_back(new_v);
|
|
}
|
|
}
|
|
}
|
|
return Q;
|
|
}
|
|
|
|
std::set<face_descriptor> k_ring(vertex_descriptor v,
|
|
int k,
|
|
const Mesh& m)
|
|
{
|
|
std::vector<vertex_descriptor> vring
|
|
= extract_k_ring(v, k - 1, m);
|
|
|
|
std::set<face_descriptor> kring;
|
|
BOOST_FOREACH(vertex_descriptor vd, vring)
|
|
{
|
|
BOOST_FOREACH(face_descriptor f,
|
|
faces_around_target(halfedge(vd, m), m))
|
|
{
|
|
if (f == boost::graph_traits<Mesh>::null_face())
|
|
continue;
|
|
if (kring.find(f) == kring.end())
|
|
kring.insert(f);
|
|
}
|
|
}
|
|
return kring;
|
|
}
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
std::cout.precision(17);
|
|
const char* filename = (argc > 1) ? argv[1] : "data/U.off";
|
|
std::ifstream input(filename);
|
|
|
|
Mesh m;
|
|
if (!input || !(input >> m)){
|
|
std::cerr << "Error: can not read file.\n";
|
|
return 1;
|
|
}
|
|
|
|
double target_edge_length = (argc > 2) ? atof(argv[2]) : 0.01;
|
|
double low = 4. / 5. * target_edge_length;
|
|
double high = 4. / 3. * target_edge_length;
|
|
|
|
unsigned int nb_iter = (argc > 3) ? atoi(argv[3]) : 5;
|
|
|
|
unsigned int center_id = 26;
|
|
unsigned int i = 0;
|
|
vertex_descriptor patch_center;
|
|
BOOST_FOREACH(vertex_descriptor v, vertices(m))
|
|
{
|
|
if (i++ == center_id)
|
|
{
|
|
patch_center = v;
|
|
break;
|
|
}
|
|
}
|
|
const std::set<face_descriptor>& patch = k_ring(patch_center, 3, m);
|
|
|
|
std::vector<halfedge_descriptor> border;
|
|
PMP::get_border(m, patch, std::back_inserter(border));
|
|
|
|
CGAL::Polygon_mesh_processing::split_long_edges(
|
|
m, border, 1.5 * target_edge_length);
|
|
|
|
CGAL::Timer t;
|
|
t.start();
|
|
|
|
CGAL::Polygon_mesh_processing::incremental_triangle_based_remeshing(m,
|
|
patch,
|
|
target_edge_length,
|
|
CGAL::Polygon_mesh_processing::parameters::number_of_iterations(nb_iter)
|
|
.protect_constraints(true)
|
|
);
|
|
|
|
t.stop();
|
|
std::cout << "Remeshing took " << t.time() << std::endl;
|
|
|
|
//boost::property_map<Mesh, boost::vertex_point_t>::const_type vpmap
|
|
// = boost::get(CGAL::vertex_point, m);
|
|
|
|
std::ofstream out("remeshed.off");
|
|
out << m;
|
|
out.close();
|
|
|
|
return 0;
|
|
} |