mirror of https://github.com/CGAL/cgal
split at the midpoint to avoid patterns leading to infinite loop
This commit is contained in:
parent
9c6452dfaf
commit
9ff2696011
|
|
@ -480,47 +480,50 @@ acvd_impl(TriangleMesh& tmesh,
|
||||||
}
|
}
|
||||||
FT threshold = 3. * cum / nbe;
|
FT threshold = 3. * cum / nbe;
|
||||||
|
|
||||||
std::vector<std::pair<edge_descriptor, double>> to_split;
|
std::vector<edge_descriptor> to_split;
|
||||||
int ei = -1;
|
int ei = -1;
|
||||||
for (edge_descriptor e : edges(tmesh))
|
for (edge_descriptor e : edges(tmesh))
|
||||||
{
|
{
|
||||||
FT l = lengths[++ei];
|
FT l = lengths[++ei];
|
||||||
if (l >= threshold)
|
if (l >= threshold)
|
||||||
{
|
{
|
||||||
double nb_subsegments = std::ceil(l / threshold);
|
to_split.emplace_back(e);
|
||||||
to_split.emplace_back(e, nb_subsegments);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto el = [>, &vpm, &tmesh](halfedge_descriptor h)
|
||||||
|
{
|
||||||
|
return edge_length(h, tmesh, parameters::vertex_point_map(vpm).geom_traits(gt));
|
||||||
|
};
|
||||||
|
|
||||||
while (!to_split.empty())
|
while (!to_split.empty())
|
||||||
{
|
{
|
||||||
std::vector<std::pair<edge_descriptor, double>> to_split_new;
|
std::vector<edge_descriptor> to_split_new;
|
||||||
to_split_new.reserve(2*to_split.size()); //upper bound
|
to_split_new.reserve(3*to_split.size()); // upper bound
|
||||||
for (const auto& [e, nb_subsegments] : to_split)
|
for (edge_descriptor e : to_split)
|
||||||
{
|
{
|
||||||
halfedge_descriptor h = halfedge(e, tmesh);
|
halfedge_descriptor h = halfedge(e, tmesh);
|
||||||
Point_3 s = get(vpm, source(h,tmesh));
|
Point_3 s = get(vpm, source(h,tmesh));
|
||||||
Point_3 t = get(vpm, target(h,tmesh));
|
Point_3 t = get(vpm, target(h,tmesh));
|
||||||
|
|
||||||
for (double k=1; k<nb_subsegments; ++k)
|
|
||||||
{
|
|
||||||
// the new halfedge hnew pointing to the inserted vertex.
|
// the new halfedge hnew pointing to the inserted vertex.
|
||||||
// The new halfedge is followed by the old halfedge, i.e., next(hnew,g) == h.
|
// The new halfedge is followed by the old halfedge, i.e., next(hnew,g) == h.
|
||||||
halfedge_descriptor hnew = Euler::split_edge(h, tmesh);
|
halfedge_descriptor hnew = Euler::split_edge(h, tmesh);
|
||||||
put(vpm, target(hnew, tmesh), barycenter(t, k/nb_subsegments, s));
|
|
||||||
|
put(vpm, target(hnew, tmesh), midpoint(s,t));
|
||||||
for (halfedge_descriptor hhh : {hnew, opposite(h, tmesh)})
|
for (halfedge_descriptor hhh : {hnew, opposite(h, tmesh)})
|
||||||
{
|
{
|
||||||
if (!is_border(hhh, tmesh))
|
if (!is_border(hhh, tmesh))
|
||||||
{
|
{
|
||||||
halfedge_descriptor hf = Euler::split_face(hhh, next(next(hhh, tmesh), tmesh), tmesh);
|
halfedge_descriptor hf = Euler::split_face(hhh, next(next(hhh, tmesh), tmesh), tmesh);
|
||||||
FT l = edge_length(hf, tmesh, parameters::vertex_point_map(vpm).geom_traits(gt));
|
if (el(hf) >= threshold)
|
||||||
if (l >= threshold)
|
to_split_new.emplace_back(edge(hf,tmesh));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (el(hnew) >= threshold)
|
||||||
{
|
{
|
||||||
double nb_subsegments = std::ceil(l / threshold);
|
to_split_new.push_back(edge(h, tmesh));
|
||||||
to_split_new.emplace_back(edge(hf,tmesh), nb_subsegments);
|
to_split_new.push_back(edge(hnew, tmesh));
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
to_split.swap(to_split_new);
|
to_split.swap(to_split_new);
|
||||||
|
|
|
||||||
|
|
@ -20,12 +20,13 @@ using Polyhedron = CGAL::Polyhedron_3<K>;
|
||||||
namespace params = CGAL::parameters;
|
namespace params = CGAL::parameters;
|
||||||
|
|
||||||
template <class Mesh>
|
template <class Mesh>
|
||||||
void run_test(std::string fname, std::size_t genus)
|
void run_test(std::string fname, std::size_t genus, bool subdiv)
|
||||||
{
|
{
|
||||||
Mesh mesh;
|
Mesh mesh;
|
||||||
CGAL::IO::read_polygon_mesh(fname, mesh);
|
CGAL::IO::read_polygon_mesh(fname, mesh);
|
||||||
|
|
||||||
PMP::triangulate_faces(mesh);
|
PMP::triangulate_faces(mesh);
|
||||||
|
if (subdiv)
|
||||||
CGAL::Subdivision_method_3::Loop_subdivision(mesh, params::number_of_iterations(5));
|
CGAL::Subdivision_method_3::Loop_subdivision(mesh, params::number_of_iterations(5));
|
||||||
|
|
||||||
Mesh ref=mesh;
|
Mesh ref=mesh;
|
||||||
|
|
@ -52,9 +53,12 @@ void run_test(std::string fname, std::size_t genus)
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
run_test<Surface_mesh>(CGAL::data_file_path("meshes/tetrahedron.off"), 0);
|
run_test<Surface_mesh>(CGAL::data_file_path("meshes/tetrahedron.off"), 0, true);
|
||||||
run_test<Polyhedron>(CGAL::data_file_path("meshes/torus_quad.off"), 1);
|
run_test<Surface_mesh>(CGAL::data_file_path("meshes/tetrahedron.off"), 0, false);
|
||||||
run_test<Surface_mesh>(CGAL::data_file_path("meshes/double-torus-example.off"), 2);
|
run_test<Polyhedron>(CGAL::data_file_path("meshes/torus_quad.off"), 1, true);
|
||||||
|
run_test<Polyhedron>(CGAL::data_file_path("meshes/torus_quad.off"), 1, false);
|
||||||
|
run_test<Surface_mesh>(CGAL::data_file_path("meshes/double-torus-example.off"), 2, true);
|
||||||
|
run_test<Surface_mesh>(CGAL::data_file_path("meshes/double-torus-example.off"), 2, false);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue