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