diff --git a/Convex_decomposition_3/test/Convex_decomposition_3/cd_nested_holes_test.cpp b/Convex_decomposition_3/test/Convex_decomposition_3/cd_nested_holes_test.cpp new file mode 100644 index 00000000000..37a3c68264f --- /dev/null +++ b/Convex_decomposition_3/test/Convex_decomposition_3/cd_nested_holes_test.cpp @@ -0,0 +1,53 @@ +#include +#include +#include +#include +#include +#include +#include + +typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel; +typedef CGAL::Polyhedron_3 Polyhedron_3; +typedef CGAL::Nef_polyhedron_3 Nef_polyhedron_3; +typedef Nef_polyhedron_3::Volume_const_iterator Volume_const_iterator; + +std::size_t run(std::string path) +{ + Polyhedron_3 input; + std::ifstream(path) >> input; + + Nef_polyhedron_3 N(input); + + CGAL::convex_decomposition_3(N); + std::list convex_parts; + + Volume_const_iterator ci = ++N.volumes_begin(); + for( ; ci != N.volumes_end(); ++ci) { + if(ci->mark()) { + Polyhedron_3 P; + N.convert_inner_shell_to_polyhedron(ci->shells_begin(), P); + convex_parts.push_back(P); + } + } + +// int i=0; + for (const Polyhedron_3& P : convex_parts) + { +// std::ofstream("out_"+std::to_string(i++)+".off") << std::setprecision(17) << P; + assert(P.size_of_vertices()!=0); + } + + return convex_parts.size(); +} + +int main() +{ + std::size_t val = run("data/in1.off"); + assert(val==9); + val = run("data/in2.off"); + assert(val==10); + val = run("data/in3.off"); + assert(val==13); + val = run("data/in4.off"); + assert(val==17); +} diff --git a/Convex_decomposition_3/test/Convex_decomposition_3/data/in1.off b/Convex_decomposition_3/test/Convex_decomposition_3/data/in1.off new file mode 100644 index 00000000000..dabda4d9d3e --- /dev/null +++ b/Convex_decomposition_3/test/Convex_decomposition_3/data/in1.off @@ -0,0 +1,117 @@ +OFF 40 76 0 +5 -5 4 +5 -5 2 +5 5 2 +5 5 4 +5 -5 -2 +5 -5 -4 +5 5 -4 +5 5 -2 +-5 5 4 +-5 -5 4 +-4 -4 4 +-4 4 4 +4 4 4 +4 -4 4 +-5 -5 -4 +-5 5 -4 +-4 4 -4 +-4 -4 -4 +4 -4 -4 +4 4 -4 +-5 5 2 +-5 -5 2 +-5 -5 -2 +-5 5 -2 +4 4 2 +4 -4 2 +4 -4 -2 +4 4 -2 +-4 4 2 +-4 -4 2 +-4 4 -2 +-4 -4 -2 +6 -6 2 +6 -6 -2 +6 6 -2 +6 6 2 +-6 6 2 +-6 -6 2 +-6 -6 -2 +-6 6 -2 +3 0 2 3 +3 2 0 1 +3 4 6 7 +3 6 4 5 +3 3 12 0 +3 3 11 12 +3 11 8 10 +3 8 11 3 +3 13 0 12 +3 10 0 13 +3 10 9 0 +3 9 10 8 +3 5 18 6 +3 5 17 18 +3 17 14 16 +3 14 17 5 +3 19 6 18 +3 16 6 19 +3 16 15 6 +3 15 16 14 +3 21 8 20 +3 8 21 9 +3 14 23 15 +3 23 14 22 +3 2 8 3 +3 8 2 20 +3 6 23 7 +3 23 6 15 +3 21 0 9 +3 0 21 1 +3 14 4 22 +3 4 14 5 +3 25 12 24 +3 12 25 13 +3 18 27 19 +3 27 18 26 +3 10 28 11 +3 28 10 29 +3 31 16 30 +3 16 31 17 +3 28 12 11 +3 12 28 24 +3 16 27 30 +3 27 16 19 +3 25 10 13 +3 10 25 29 +3 18 31 26 +3 31 18 17 +3 32 34 35 +3 34 32 33 +3 35 2 32 +3 35 20 2 +3 20 36 21 +3 36 20 35 +3 1 32 2 +3 21 32 1 +3 21 37 32 +3 37 21 36 +3 28 25 24 +3 25 28 29 +3 33 4 34 +3 33 22 4 +3 22 38 23 +3 38 22 33 +3 7 34 4 +3 23 34 7 +3 23 39 34 +3 39 23 38 +3 31 27 26 +3 27 31 30 +3 38 36 39 +3 36 38 37 +3 34 36 35 +3 36 34 39 +3 38 32 37 +3 32 38 33 diff --git a/Convex_decomposition_3/test/Convex_decomposition_3/data/in2.off b/Convex_decomposition_3/test/Convex_decomposition_3/data/in2.off new file mode 100644 index 00000000000..d09ff781d58 --- /dev/null +++ b/Convex_decomposition_3/test/Convex_decomposition_3/data/in2.off @@ -0,0 +1,144 @@ +OFF +48 92 0 + +2 2 2 +2 -2 2 +-2 2 2 +-2 -2 2 +-2 2 4 +2 2 4 +-2 -2 4 +2 -2 4 +5 -5 4 +-4 4 4 +5 5 4 +4 -4 4 +-5 -5 4 +-4 -4 -4 +5 -5 -4 +4 4 -4 +-5 5 -4 +-5 5 4 +5 5 -4 +-5 -5 -4 +4 4 4 +4 -4 -2 +-4 -4 4 +-4 4 -2 +-4 4 -4 +4 4 -2 +4 -4 -4 +6 -6 2 +5 5 2 +-5 5 2 +6 6 2 +5 -5 2 +-5 -5 2 +-6 -6 2 +5 -5 -2 +-5 -5 -2 +6 -6 -2 +5 5 -2 +-5 5 -2 +-6 6 -2 +-4 -4 -2 +-6 6 2 +6 6 -2 +-6 -6 -2 +-4 -4 2 +-4 4 2 +4 4 2 +4 -4 2 +3 2 4 5 +3 7 6 3 +3 5 7 1 +3 6 7 5 +3 3 6 4 +3 5 0 2 +3 3 1 7 +3 1 0 5 +3 5 4 6 +3 4 2 3 +3 8 28 10 +3 28 8 31 +3 34 18 37 +3 18 34 14 +3 10 20 8 +3 10 9 20 +3 9 17 22 +3 17 9 10 +3 11 8 20 +3 22 8 11 +3 22 12 8 +3 12 22 17 +3 14 26 18 +3 14 13 26 +3 13 19 24 +3 19 13 14 +3 15 18 26 +3 24 18 15 +3 24 16 18 +3 16 24 19 +3 32 17 29 +3 17 32 12 +3 19 38 16 +3 38 19 35 +3 28 17 10 +3 17 28 29 +3 18 38 37 +3 38 18 16 +3 32 8 12 +3 8 32 31 +3 19 34 35 +3 34 19 14 +3 47 20 46 +3 20 47 11 +3 26 25 15 +3 25 26 21 +3 22 45 9 +3 45 22 44 +3 40 24 23 +3 24 40 13 +3 45 20 9 +3 20 45 46 +3 24 25 23 +3 25 24 15 +3 47 22 11 +3 22 47 44 +3 26 40 21 +3 40 26 13 +3 27 42 30 +3 42 27 36 +3 30 28 27 +3 30 29 28 +3 29 41 32 +3 41 29 30 +3 31 27 28 +3 32 27 31 +3 32 33 27 +3 33 32 41 +3 2 0 45 +3 1 44 47 +3 36 34 42 +3 36 35 34 +3 35 43 38 +3 43 35 36 +3 37 42 34 +3 38 42 37 +3 38 39 42 +3 39 38 43 +3 40 25 21 +3 25 40 23 +3 43 41 39 +3 41 43 33 +3 42 41 30 +3 41 42 39 +3 43 27 33 +3 27 43 36 +3 44 1 3 +3 44 3 45 +3 45 3 2 +3 46 45 0 +3 46 0 47 +3 47 0 1 + diff --git a/Convex_decomposition_3/test/Convex_decomposition_3/data/in3.off b/Convex_decomposition_3/test/Convex_decomposition_3/data/in3.off new file mode 100644 index 00000000000..7685150981d --- /dev/null +++ b/Convex_decomposition_3/test/Convex_decomposition_3/data/in3.off @@ -0,0 +1,180 @@ +OFF +60 116 0 + +1 1 4 +1 0.33333333333333337 4 +1 -1 4 +0.33333333333333337 -1 4 +-1 -1 4 +-1 0.33333333333333337 4 +-1 1 4 +0.33333333333333337 1 4 +-2 2 2 +5 -5 4 +-4 4 4 +5 5 4 +4 -4 4 +-5 -5 4 +-4 -4 -4 +5 -5 -4 +4 4 -4 +-5 5 -4 +-5 5 4 +5 5 -4 +-5 -5 -4 +4 4 4 +4 -4 -2 +-4 -4 4 +-4 4 -2 +-4 4 -4 +4 4 -2 +4 -4 -4 +6 -6 2 +5 5 2 +-5 5 2 +6 6 2 +5 -5 2 +-5 -5 2 +-6 -6 2 +5 -5 -2 +-5 -5 -2 +6 -6 -2 +5 5 -2 +-5 5 -2 +-6 6 -2 +-4 -4 -2 +-6 6 2 +6 6 -2 +-6 -6 -2 +-2 -2 2 +-4 -4 2 +-4 4 2 +4 4 2 +4 -4 2 +2 -2 2 +2 2 2 +-2 2 4 +2 2 4 +2 -2 4 +-2 -2 4 +1 1 2 +1 -1 2 +-1 -1 2 +-1 1 2 +3 8 52 53 +3 54 55 45 +3 53 54 50 +3 0 1 53 +3 45 55 52 +3 53 51 8 +3 45 50 54 +3 50 51 53 +3 4 5 55 +3 52 8 45 +3 9 29 11 +3 29 9 32 +3 35 19 38 +3 19 35 15 +3 11 21 9 +3 11 10 21 +3 10 18 23 +3 18 10 11 +3 12 9 21 +3 23 9 12 +3 23 13 9 +3 13 23 18 +3 15 27 19 +3 15 14 27 +3 14 20 25 +3 20 14 15 +3 16 19 27 +3 25 19 16 +3 25 17 19 +3 17 25 20 +3 33 18 30 +3 18 33 13 +3 20 39 17 +3 39 20 36 +3 29 18 11 +3 18 29 30 +3 19 39 38 +3 39 19 17 +3 33 9 13 +3 9 33 32 +3 20 35 36 +3 35 20 15 +3 49 21 48 +3 21 49 12 +3 27 26 16 +3 26 27 22 +3 23 47 10 +3 47 23 46 +3 41 25 24 +3 25 41 14 +3 47 21 10 +3 21 47 48 +3 25 26 24 +3 26 25 16 +3 49 23 12 +3 23 49 46 +3 27 41 22 +3 41 27 14 +3 28 43 31 +3 43 28 37 +3 31 29 28 +3 31 30 29 +3 30 42 33 +3 42 30 31 +3 32 28 29 +3 33 28 32 +3 33 34 28 +3 34 33 42 +3 8 51 47 +3 50 46 49 +3 37 35 43 +3 37 36 35 +3 36 44 39 +3 44 36 37 +3 38 43 35 +3 39 43 38 +3 39 40 43 +3 40 39 44 +3 41 26 22 +3 26 41 24 +3 44 42 40 +3 42 44 34 +3 43 42 31 +3 42 43 40 +3 44 28 34 +3 28 44 37 +3 46 50 45 +3 46 45 47 +3 47 45 8 +3 48 47 51 +3 48 51 49 +3 49 51 50 +3 52 55 5 +3 52 7 53 +3 52 5 6 +3 53 7 0 +3 52 6 7 +3 54 53 1 +3 54 2 3 +3 54 1 2 +3 55 54 3 +3 55 3 4 +3 58 57 56 +3 59 56 7 +3 2 57 3 +3 0 56 1 +3 5 59 6 +3 56 59 58 +3 57 1 56 +3 57 2 1 +3 58 5 4 +3 7 56 0 +3 58 3 57 +3 4 3 58 +3 59 5 58 +3 7 6 59 + diff --git a/Convex_decomposition_3/test/Convex_decomposition_3/data/in4.off b/Convex_decomposition_3/test/Convex_decomposition_3/data/in4.off new file mode 100644 index 00000000000..1a7bbd1ba82 --- /dev/null +++ b/Convex_decomposition_3/test/Convex_decomposition_3/data/in4.off @@ -0,0 +1,180 @@ +OFF +60 116 0 + +1 1 4 +1 0.5 4 +1 -1 4 +0.5 -1 4 +-1 -1 4 +-1 0.5 4 +-1 1 4 +0.5 1 4 +-2 2 2 +5 -5 4 +-4 4 4 +5 5 4 +4 -4 4 +-5 -5 4 +-4 -4 -4 +5 -5 -4 +4 4 -4 +-5 5 -4 +-5 5 4 +5 5 -4 +-5 -5 -4 +4 4 4 +4 -4 -2 +-4 -4 4 +-4 4 -2 +-4 4 -4 +4 4 -2 +4 -4 -4 +6 -6 2 +5 5 2 +-5 5 2 +6 6 2 +5 -5 2 +-5 -5 2 +-6 -6 2 +5 -5 -2 +-5 -5 -2 +6 -6 -2 +5 5 -2 +-5 5 -2 +-6 6 -2 +-4 -4 -2 +-6 6 2 +6 6 -2 +-6 -6 -2 +-2 -2 2 +-4 -4 2 +-4 4 2 +4 4 2 +4 -4 2 +2 -2 2 +2 2 2 +-2 2 4 +2 2 4 +2 -2 4 +-2 -2 4 +1 1 1 +1 -1 1 +-1 -1 1 +-1 1 1 +3 8 52 53 +3 54 55 45 +3 53 54 50 +3 0 1 53 +3 45 55 52 +3 53 51 8 +3 45 50 54 +3 50 51 53 +3 4 5 55 +3 52 8 45 +3 9 29 11 +3 29 9 32 +3 35 19 38 +3 19 35 15 +3 11 21 9 +3 11 10 21 +3 10 18 23 +3 18 10 11 +3 12 9 21 +3 23 9 12 +3 23 13 9 +3 13 23 18 +3 15 27 19 +3 15 14 27 +3 14 20 25 +3 20 14 15 +3 16 19 27 +3 25 19 16 +3 25 17 19 +3 17 25 20 +3 33 18 30 +3 18 33 13 +3 20 39 17 +3 39 20 36 +3 29 18 11 +3 18 29 30 +3 19 39 38 +3 39 19 17 +3 33 9 13 +3 9 33 32 +3 20 35 36 +3 35 20 15 +3 49 21 48 +3 21 49 12 +3 27 26 16 +3 26 27 22 +3 23 47 10 +3 47 23 46 +3 41 25 24 +3 25 41 14 +3 47 21 10 +3 21 47 48 +3 25 26 24 +3 26 25 16 +3 49 23 12 +3 23 49 46 +3 27 41 22 +3 41 27 14 +3 28 43 31 +3 43 28 37 +3 31 29 28 +3 31 30 29 +3 30 42 33 +3 42 30 31 +3 32 28 29 +3 33 28 32 +3 33 34 28 +3 34 33 42 +3 8 51 47 +3 50 46 49 +3 37 35 43 +3 37 36 35 +3 36 44 39 +3 44 36 37 +3 38 43 35 +3 39 43 38 +3 39 40 43 +3 40 39 44 +3 41 26 22 +3 26 41 24 +3 44 42 40 +3 42 44 34 +3 43 42 31 +3 42 43 40 +3 44 28 34 +3 28 44 37 +3 46 50 45 +3 46 45 47 +3 47 45 8 +3 48 47 51 +3 48 51 49 +3 49 51 50 +3 52 55 5 +3 52 7 53 +3 52 5 6 +3 53 7 0 +3 52 6 7 +3 54 53 1 +3 54 2 3 +3 54 1 2 +3 55 54 3 +3 55 3 4 +3 58 57 56 +3 59 56 7 +3 2 57 3 +3 0 56 1 +3 5 59 6 +3 56 59 58 +3 57 1 56 +3 57 2 1 +3 58 5 4 +3 7 56 0 +3 58 3 57 +3 4 3 58 +3 59 5 58 +3 7 6 59 + diff --git a/Nef_3/include/CGAL/Nef_polyhedron_3.h b/Nef_3/include/CGAL/Nef_polyhedron_3.h index 74bb56ba885..bb41e3417a3 100644 --- a/Nef_3/include/CGAL/Nef_polyhedron_3.h +++ b/Nef_3/include/CGAL/Nef_polyhedron_3.h @@ -901,10 +901,11 @@ class Nef_polyhedron_3 : public CGAL::Handle_for< Nef_polyhedron_3_rep& omit_vertex; int nov, nof; + bool hh; public: Find_holes(Unique_hash_map& omit_vertex_) - : omit_vertex(omit_vertex_), nov(0), nof(0) {} + : omit_vertex(omit_vertex_), nov(0), nof(0), hh(false) {} void visit(Halffacet_const_handle f) { ++nof; @@ -917,10 +918,11 @@ class Nef_polyhedron_3 : public CGAL::Handle_for< Nef_polyhedron_3_repsource()->source()] = true; --nov; + hh=true; } } else if(fc.is_shalfloop()) { SHalfloop_const_handle sl(fc); - omit_vertex[sl->incident_sface()->center_vertex()]; + omit_vertex[sl->incident_sface()->center_vertex()] = true; --nov; } else CGAL_error_msg( "wrong handle type"); @@ -940,6 +942,63 @@ class Nef_polyhedron_3 : public CGAL::Handle_for< Nef_polyhedron_3_rep& omit_vertex; + int norv, nof; + + public: + Nested_holes(Unique_hash_map& omit_vertex_) + : omit_vertex(omit_vertex_), norv(0), nof(0) {} + + void visit(Halffacet_const_handle f) { + Halffacet_cycle_const_iterator fc = f->facet_cycles_begin(); + CGAL_assertion(fc.is_shalfedge()); + + SHalfedge_around_facet_const_circulator sfc(fc), send(sfc); + bool all_in=true; + bool all_out=true; + CGAL_For_all(sfc, send) { + if (omit_vertex[sfc->source()->source()]) + all_in=false; + else + all_out=false; + } + if (!all_in && !all_out) + { + SHalfedge_around_facet_const_circulator sfc(fc), send(sfc); + ++nof; + CGAL_For_all(sfc, send) { + if (!omit_vertex[sfc->source()->source()]) + { + omit_vertex[sfc->source()->source()]=true; + ++norv; + } + } + } + if (all_in) + ++nof; + } + + void visit(Vertex_const_handle) {} + void visit(SFace_const_handle) {} + void visit(Halfedge_const_handle) {} + void visit(SHalfedge_const_handle) {} + void visit(SHalfloop_const_handle) {} + + int number_of_removed_vertices() const { + return norv; + } + + int number_of_facets() const { + return nof; + } }; class Add_vertices { @@ -998,14 +1057,19 @@ class Nef_polyhedron_3 : public CGAL::Handle_for< Nef_polyhedron_3_repsource()->source()]) return; - B.begin_facet(); + SHalfedge_around_facet_const_circulator hc_start(se); SHalfedge_around_facet_const_circulator hc_end(hc_start); + std::vector vids; CGAL_For_all(hc_start,hc_end) { - CGAL_NEF_TRACEN(" add vertex " << hc_start->source()->center_vertex()->point()); - B.add_vertex_to_facet(VI[hc_start->source()->center_vertex()]); + if (omit_vertex[hc_start->source()->center_vertex()]) + { + std::cout << "issue with " << se->source()->source()->point() << "\n"; + return; + } + vids.push_back(VI[hc_start->source()->center_vertex()]); } - B.end_facet(); + B.add_facet (vids.begin(), vids.end()); } void visit(SFace_const_handle) {} @@ -1030,11 +1094,29 @@ class Nef_polyhedron_3 : public CGAL::Handle_for< Nef_polyhedron_3_rep B(hds, true); + // first mark vertices of holes of each halffacet as omitted. Find_holes F(omit_vertex); scd.visit_shell_objects(sf, F); + std::size_t nb_v = F.number_of_vertices(); + std::size_t nb_f = F.number_of_facets(); + + // then if a halffacet contains a vertex marked as omitted, all its vertices + // must be marked as such + if (F.holes_detected()) + { + while(true) + { + Nested_holes F2(omit_vertex); + scd.visit_shell_objects(sf, F2); + if (F2.number_of_removed_vertices()==0) break; + nb_v-=F2.number_of_removed_vertices(); + nb_f=F2.number_of_facets(); + } + } + - B.begin_surface(F.number_of_vertices(), - F.number_of_facets(), + B.begin_surface(nb_v, + nb_f, F.number_of_vertices()+F.number_of_facets()-2); Add_vertices A(B,omit_vertex, VI); diff --git a/Ridges_3/doc/Ridges_3/Ridges_3.txt b/Ridges_3/doc/Ridges_3/Ridges_3.txt index e060ec4d1c4..81357ee8903 100644 --- a/Ridges_3/doc/Ridges_3/Ridges_3.txt +++ b/Ridges_3/doc/Ridges_3/Ridges_3.txt @@ -44,8 +44,8 @@ functions of the package are provided in Section \ref Ridges_3Examples. For a detailed introduction to ridges and related topics, the reader may consult -\cgalCite{cgal:hgygm-ttdpf-99},cgal:p-gd-01, as well as -the following survey article \cgalCite{cgal:cp-ssulc-05}. +\cgalCite{cgal:hgygm-ttdpf-99}, as well as +the survey article \cgalCite{cgal:cp-ssulc-05}. In the sequel, we just introduce the basic notions so as to explain our algorithms. Consider a smooth embedded surface, and denote \f$ k_1\f$ and \f$ k_2\f$ the principal curvatures, with \f$ k_1\geq k_2\f$. Umbilics are @@ -399,7 +399,7 @@ neighborhood. \subsection Ridges_3Exampleprogram Example Program The following program computes ridges and umbilics from an off -file.\cgalFootnote{Model data may be downloaded via ftp://ftp.mpi-sb.mpg.de/pub/outgoing/CGAL/Ridges_3_datafiles.tgz . The mechanical part model has been provided courtesy of Dassault System to produce \cgalFigureRef{figmechanical_crest_filteredintro}, due to copyright issues the available model is not the same, it is provided by the AIM\@SHAPE Shape Repository.} It uses the package \ref PkgJetFitting3 to estimate the differential +file. It uses the package \ref PkgJetFitting3 to estimate the differential quantities. The default output file gives rough data for visualization purpose, a verbose output file may also be asked for. Parameters are @@ -533,11 +533,7 @@ Ridges on the ellipsoid, normals pointing outward. Color coding : \subsection Ridges_3ExampleFilteringofCrestRidgesona Example: Filtering of Crest Ridges on a Mechanical Part \cgalFigureRef{figmechanical_crest_filteredintro} illustrates the filtering -of crest ridges on a mechanical model, and has been computed as follows: - -\code{.cpp} -./Compute_Ridges_Umbilics -f data/mecanic.off -d 4 -m 4 -a 4 -t 4 -\endcode +of crest ridges on a mechanical model. \cgalFigureBegin{figmechanical_crest_filteredintro,mecanic-sub1_crest-jpg.png} Mechanical part (37k pts). Left: All crest lines. Middle: crests filtered