diff --git a/Kinetic_shape_reconstruction/include/CGAL/KSR_3/Data_structure.h b/Kinetic_shape_reconstruction/include/CGAL/KSR_3/Data_structure.h index f09a04d715b..e6944df1beb 100644 --- a/Kinetic_shape_reconstruction/include/CGAL/KSR_3/Data_structure.h +++ b/Kinetic_shape_reconstruction/include/CGAL/KSR_3/Data_structure.h @@ -137,6 +137,23 @@ public: } }; + struct Halfedge_to_pface { + using argument_type = Halfedge_index; + using result_type = PFace; + + const KSR::size_t support_plane_idx; + const Mesh& mesh; + + Halfedge_to_pface(const KSR::size_t sp_idx, const Mesh& m) : + support_plane_idx(sp_idx), + mesh(m) + { } + + const result_type operator()(const argument_type& arg) const { + return result_type(support_plane_idx, mesh.face(arg)); + } + }; + using PEdge_around_pvertex_iterator = boost::transform_iterator >; using PEdges_around_pvertex = CGAL::Iterator_range; @@ -145,6 +162,10 @@ public: boost::transform_iterator >; using PEdges_of_pface = CGAL::Iterator_range; + using PFace_around_pvertex_iterator = + boost::transform_iterator >; + using PFaces_around_pvertex = CGAL::Iterator_range; + using IVertex = typename Intersection_graph::Vertex_descriptor; using IEdge = typename Intersection_graph::Edge_descriptor; @@ -692,6 +713,28 @@ public: return out; } + const PFaces_around_pvertex pfaces_around_pvertex(const PVertex& pvertex) const { + + return PFaces_around_pvertex( + boost::make_transform_iterator( + halfedges_around_target(halfedge(pvertex.second, mesh(pvertex)), mesh(pvertex)).begin(), + Halfedge_to_pface(pvertex.first, mesh(pvertex))), + boost::make_transform_iterator( + halfedges_around_target(halfedge(pvertex.second, mesh(pvertex)), mesh(pvertex)).end(), + Halfedge_to_pface(pvertex.first, mesh(pvertex)))); + } + + void non_null_pfaces_around_pvertex( + const PVertex& pvertex, std::vector& pfaces) const { + + pfaces.clear(); + const auto nfaces = pfaces_around_pvertex(pvertex); + for (const auto pface : nfaces) { + if (pface.second == Support_plane::Mesh::null_face()) continue; + pfaces.push_back(pface); + } + } + const PVertices_of_pface pvertices_of_pface(const PFace& pface) const { return PVertices_of_pface( @@ -1402,12 +1445,9 @@ public: pvertices[2] = propagated; const PFace new_pface = add_pface(pvertices); + if (m_verbose) std::cout << "- new pface: " << lstr(new_pface) << std::endl; this->k(new_pface) = k; CGAL_assertion(new_pface.second != Face_index()); - - if (m_verbose) { - std::cout << "- new face: " << lstr(new_pface) << std::endl; - } return pvertices; } @@ -1977,6 +2017,7 @@ public: if (m_verbose) std::cout << "- propagated: " << point_3(propagated) << std::endl; const PFace new_pface = add_pface(std::array{pvertex, propagated, previous}); + if (m_verbose) std::cout << "- new pface: " << lstr(new_pface) << std::endl; this->k(new_pface) = this->k(pface); previous = propagated; @@ -2164,6 +2205,7 @@ public: if (m_verbose) std::cout << "- propagated: " << point_3(propagated) << std::endl; const PFace new_pface = add_pface(std::array{pvertex, previous, propagated}); + if (m_verbose) std::cout << "- new pface: " << lstr(new_pface) << std::endl; this->k(new_pface) = this->k(pface); previous = propagated; @@ -2454,6 +2496,7 @@ public: std::cout << "- adding new pface" << std::endl; } const PFace new_pface = add_pface(std::array{new_pvertices[i], new_pvertices[i + 1], pvertex}); + if (m_verbose) std::cout << "- new pface: " << lstr(new_pface) << std::endl; this->k(new_pface) = k; ++num_added_pfaces; } @@ -2549,6 +2592,10 @@ public: std::cout << "* number of removed hanging faces: " << num_removed_faces << std::endl; } // CGAL_assertion_msg(false, "TODO: DEBUG THIS FUNCTION!"); + + // TODO: Should I also implement here the part that removes all + // identical pfaces within the same support plane? If the k intersection + // criteria works well, that should not be necessary! } const std::size_t check_edge(const IEdge& iedge) { @@ -2793,7 +2840,7 @@ public: boost::make_transform_iterator(pvertices.end(), unary_f)); // Very slow! - if (true) { + if (check_equal_faces) { for (const auto oface : pfaces) { if (oface == pface) continue; @@ -2882,7 +2929,7 @@ public: void check_integrity( const bool check_simplicity = false, const bool check_convexity = false, - const bool check_equal_faces = false) const { + const bool check_equal_faces = true) const { for (KSR::size_t i = 0; i < number_of_support_planes(); ++i) { if (!is_mesh_valid(check_simplicity, check_convexity, check_equal_faces, i)) { diff --git a/Kinetic_shape_reconstruction/include/CGAL/Kinetic_shape_reconstruction_3.h b/Kinetic_shape_reconstruction/include/CGAL/Kinetic_shape_reconstruction_3.h index 975082a89e0..45e248ed87a 100644 --- a/Kinetic_shape_reconstruction/include/CGAL/Kinetic_shape_reconstruction_3.h +++ b/Kinetic_shape_reconstruction/include/CGAL/Kinetic_shape_reconstruction_3.h @@ -540,6 +540,9 @@ private: dump(m_data, "iter-" + std::to_string(iteration)); dump_event(m_data, event, "iter-" + std::to_string(iteration)); } + // const KSR::size_t sp_debug_idx = 23; + // dump_2d_surface_mesh(m_data, sp_debug_idx, "iter-" + std::to_string(iteration) + + // "-surface-mesh-" + std::to_string(sp_debug_idx)); } m_data.update_positions(current_time); diff --git a/Kinetic_shape_reconstruction/test/Kinetic_shape_reconstruction/kinetic_3d_test_all.cpp b/Kinetic_shape_reconstruction/test/Kinetic_shape_reconstruction/kinetic_3d_test_all.cpp index 1ea67377886..3b06fdd739b 100644 --- a/Kinetic_shape_reconstruction/test/Kinetic_shape_reconstruction/kinetic_3d_test_all.cpp +++ b/Kinetic_shape_reconstruction/test/Kinetic_shape_reconstruction/kinetic_3d_test_all.cpp @@ -35,6 +35,7 @@ struct Polygon_map { const bool run_test( const std::string input_filename, + const std::vector& ks, const std::size_t num_iters, std::size_t& num_tests) { @@ -47,7 +48,7 @@ const bool run_test( std::cout << std::endl; std::cout << "--INPUT FILE: " << input_filename << std::endl; const Polygon_map polygon_map(input_vertices); - for (unsigned int k = 1; k <= 6; ++k) { + for (const auto k : ks) { std::cout << std::endl << "--INPUT K: " << k << std::endl; for (std::size_t iter = 0; iter < num_iters; ++iter) { std::cout << std::endl << "--ITERATION #" << iter + 1 << " BEGIN!" << std::endl; @@ -57,16 +58,6 @@ const bool run_test( std::cout << std::endl << "--ITERATION #" << iter + 1 << " END!" << std::endl; } } - - std::cout << std::endl << "--INPUT K: " << 100 << std::endl; - for (std::size_t iter = 0; iter < num_iters; ++iter) { - std::cout << std::endl << "--ITERATION #" << iter + 1 << " BEGIN!" << std::endl; - KSR ksr(false, false); - assert(ksr.partition(input_faces, polygon_map, 100)); - ksr.clear(); - std::cout << std::endl << "--ITERATION #" << iter + 1 << " END!" << std::endl; - } - return true; } @@ -75,78 +66,92 @@ int main (const int argc, const char** argv) { std::size_t num_tests = 0; const std::size_t num_iters = 3; + std::vector ks; + for (unsigned int k = 1; k <= 6; ++k) { + ks.push_back(k); + } + ks.push_back(100); + // Stress tests 0. - assert(run_test("data/stress-test-0/test-1-polygon-a.off" , num_iters, num_tests)); - assert(run_test("data/stress-test-0/test-1-polygon-b.off" , num_iters, num_tests)); - assert(run_test("data/stress-test-0/test-1-polygon-c.off" , num_iters, num_tests)); - assert(run_test("data/stress-test-0/test-1-polygon-d.off" , num_iters, num_tests)); - assert(run_test("data/stress-test-0/test-2-polygons-ab.off" , num_iters, num_tests)); - assert(run_test("data/stress-test-0/test-2-polygons-ac.off" , num_iters, num_tests)); - assert(run_test("data/stress-test-0/test-2-polygons-ad.off" , num_iters, num_tests)); - assert(run_test("data/stress-test-0/test-2-polygons-bc.off" , num_iters, num_tests)); - assert(run_test("data/stress-test-0/test-2-polygons-bd.off" , num_iters, num_tests)); - assert(run_test("data/stress-test-0/test-2-polygons-cd.off" , num_iters, num_tests)); - assert(run_test("data/stress-test-0/test-3-polygons-abc.off" , num_iters, num_tests)); - assert(run_test("data/stress-test-0/test-3-polygons-abd.off" , num_iters, num_tests)); - assert(run_test("data/stress-test-0/test-3-polygons-acd.off" , num_iters, num_tests)); - assert(run_test("data/stress-test-0/test-3-polygons-bcd.off" , num_iters, num_tests)); - assert(run_test("data/stress-test-0/test-4-polygons-abcd.off", num_iters, num_tests)); - assert(run_test("data/stress-test-0/test-6-polygons.off" , num_iters, num_tests)); + assert(run_test("data/stress-test-0/test-1-polygon-a.off" , ks, num_iters, num_tests)); + assert(run_test("data/stress-test-0/test-1-polygon-b.off" , ks, num_iters, num_tests)); + assert(run_test("data/stress-test-0/test-1-polygon-c.off" , ks, num_iters, num_tests)); + assert(run_test("data/stress-test-0/test-1-polygon-d.off" , ks, num_iters, num_tests)); + assert(run_test("data/stress-test-0/test-2-polygons-ab.off" , ks, num_iters, num_tests)); + assert(run_test("data/stress-test-0/test-2-polygons-ac.off" , ks, num_iters, num_tests)); + assert(run_test("data/stress-test-0/test-2-polygons-ad.off" , ks, num_iters, num_tests)); + assert(run_test("data/stress-test-0/test-2-polygons-bc.off" , ks, num_iters, num_tests)); + assert(run_test("data/stress-test-0/test-2-polygons-bd.off" , ks, num_iters, num_tests)); + assert(run_test("data/stress-test-0/test-2-polygons-cd.off" , ks, num_iters, num_tests)); + assert(run_test("data/stress-test-0/test-3-polygons-abc.off" , ks, num_iters, num_tests)); + assert(run_test("data/stress-test-0/test-3-polygons-abd.off" , ks, num_iters, num_tests)); + assert(run_test("data/stress-test-0/test-3-polygons-acd.off" , ks, num_iters, num_tests)); + assert(run_test("data/stress-test-0/test-3-polygons-bcd.off" , ks, num_iters, num_tests)); + assert(run_test("data/stress-test-0/test-4-polygons-abcd.off", ks, num_iters, num_tests)); + assert(run_test("data/stress-test-0/test-6-polygons.off" , ks, num_iters, num_tests)); // Stress tests 1. - assert(run_test("data/stress-test-1/test-1-rnd-polygons-1-4.off", num_iters, num_tests)); - assert(run_test("data/stress-test-1/test-2-rnd-polygons-1-4.off", num_iters, num_tests)); - assert(run_test("data/stress-test-1/test-3-rnd-polygons-1-4.off", num_iters, num_tests)); - assert(run_test("data/stress-test-1/test-4-rnd-polygons-1-4.off", num_iters, num_tests)); - assert(run_test("data/stress-test-1/test-5-rnd-polygons-2-4.off", num_iters, num_tests)); - assert(run_test("data/stress-test-1/test-6-rnd-polygons-2-4.off", num_iters, num_tests)); - assert(run_test("data/stress-test-1/test-7-rnd-polygons-2-4.off", num_iters, num_tests)); - assert(run_test("data/stress-test-1/test-8-rnd-polygons-3-4.off", num_iters, num_tests)); + assert(run_test("data/stress-test-1/test-1-rnd-polygons-1-4.off", ks, num_iters, num_tests)); + assert(run_test("data/stress-test-1/test-2-rnd-polygons-1-4.off", ks, num_iters, num_tests)); + assert(run_test("data/stress-test-1/test-3-rnd-polygons-1-4.off", ks, num_iters, num_tests)); + assert(run_test("data/stress-test-1/test-4-rnd-polygons-1-4.off", ks, num_iters, num_tests)); + assert(run_test("data/stress-test-1/test-5-rnd-polygons-2-4.off", ks, num_iters, num_tests)); + assert(run_test("data/stress-test-1/test-6-rnd-polygons-2-4.off", ks, num_iters, num_tests)); + assert(run_test("data/stress-test-1/test-7-rnd-polygons-2-4.off", ks, num_iters, num_tests)); + assert(run_test("data/stress-test-1/test-8-rnd-polygons-3-4.off", ks, num_iters, num_tests)); // Stress tests 2. - assert(run_test("data/stress-test-2/test-1-rnd-polygons-1-4.off", num_iters, num_tests)); - assert(run_test("data/stress-test-2/test-2-rnd-polygons-1-4.off", num_iters, num_tests)); - assert(run_test("data/stress-test-2/test-3-rnd-polygons-1-4.off", num_iters, num_tests)); - assert(run_test("data/stress-test-2/test-4-rnd-polygons-1-3.off", num_iters, num_tests)); - assert(run_test("data/stress-test-2/test-5-rnd-polygons-2-4.off", num_iters, num_tests)); - assert(run_test("data/stress-test-2/test-6-rnd-polygons-3-4.off", num_iters, num_tests)); + assert(run_test("data/stress-test-2/test-1-rnd-polygons-1-4.off", ks, num_iters, num_tests)); + assert(run_test("data/stress-test-2/test-2-rnd-polygons-1-4.off", ks, num_iters, num_tests)); + assert(run_test("data/stress-test-2/test-3-rnd-polygons-1-4.off", ks, num_iters, num_tests)); + assert(run_test("data/stress-test-2/test-4-rnd-polygons-1-3.off", ks, num_iters, num_tests)); + assert(run_test("data/stress-test-2/test-5-rnd-polygons-2-4.off", ks, num_iters, num_tests)); + assert(run_test("data/stress-test-2/test-6-rnd-polygons-3-4.off", ks, num_iters, num_tests)); // Stress tests 3. - assert(run_test("data/stress-test-3/test-1-rnd-polygons-2-3.off" , num_iters, num_tests)); - assert(run_test("data/stress-test-3/test-2-rnd-polygons-2-3.off" , num_iters, num_tests)); - assert(run_test("data/stress-test-3/test-3-rnd-polygons-2-3.off" , num_iters, num_tests)); - assert(run_test("data/stress-test-3/test-4-rnd-polygons-2-4.off" , num_iters, num_tests)); - assert(run_test("data/stress-test-3/test-5-rnd-polygons-1-3.off" , num_iters, num_tests)); - assert(run_test("data/stress-test-3/test-6-rnd-polygons-2-3.off" , num_iters, num_tests)); - assert(run_test("data/stress-test-3/test-7-rnd-polygons-2-4.off" , num_iters, num_tests)); - assert(run_test("data/stress-test-3/test-8-rnd-polygons-2-10.off", num_iters, num_tests)); - assert(run_test("data/stress-test-3/test-9-rnd-polygons-4-4.off" , num_iters, num_tests)); - assert(run_test("data/stress-test-3/test-10-rnd-polygons-5-4.off", num_iters, num_tests)); + assert(run_test("data/stress-test-3/test-1-rnd-polygons-2-3.off" , ks, num_iters, num_tests)); + assert(run_test("data/stress-test-3/test-2-rnd-polygons-2-3.off" , ks, num_iters, num_tests)); + assert(run_test("data/stress-test-3/test-3-rnd-polygons-2-3.off" , ks, num_iters, num_tests)); + assert(run_test("data/stress-test-3/test-4-rnd-polygons-2-4.off" , ks, num_iters, num_tests)); + assert(run_test("data/stress-test-3/test-5-rnd-polygons-1-3.off" , ks, num_iters, num_tests)); + assert(run_test("data/stress-test-3/test-6-rnd-polygons-2-3.off" , ks, num_iters, num_tests)); + assert(run_test("data/stress-test-3/test-7-rnd-polygons-2-4.off" , ks, num_iters, num_tests)); + assert(run_test("data/stress-test-3/test-8-rnd-polygons-2-10.off", ks, num_iters, num_tests)); + assert(run_test("data/stress-test-3/test-9-rnd-polygons-4-4.off" , ks, num_iters, num_tests)); + assert(run_test("data/stress-test-3/test-10-rnd-polygons-5-4.off", ks, num_iters, num_tests)); // Stress tests 4. - assert(run_test("data/stress-test-4/test-1-rnd-polygons-2-6.off" , num_iters, num_tests)); - assert(run_test("data/stress-test-4/test-2-rnd-polygons-3-8.off" , num_iters, num_tests)); - assert(run_test("data/stress-test-4/test-3-rnd-polygons-4-4.off" , num_iters, num_tests)); - assert(run_test("data/stress-test-4/test-4-rnd-polygons-4-6.off" , num_iters, num_tests)); - assert(run_test("data/stress-test-4/test-5-rnd-polygons-6-4.off" , num_iters, num_tests)); - assert(run_test("data/stress-test-4/test-6-rnd-polygons-5-6.off" , num_iters, num_tests)); - assert(run_test("data/stress-test-4/test-7-rnd-polygons-7-6.off" , num_iters, num_tests)); - assert(run_test("data/stress-test-4/test-8-rnd-polygons-7-8.off" , num_iters, num_tests)); - assert(run_test("data/stress-test-4/test-9-rnd-polygons-12-4.off", num_iters, num_tests)); + assert(run_test("data/stress-test-4/test-1-rnd-polygons-2-6.off" , ks, num_iters, num_tests)); + assert(run_test("data/stress-test-4/test-2-rnd-polygons-3-8.off" , ks, num_iters, num_tests)); + assert(run_test("data/stress-test-4/test-3-rnd-polygons-4-4.off" , ks, num_iters, num_tests)); + assert(run_test("data/stress-test-4/test-4-rnd-polygons-4-6.off" , ks, num_iters, num_tests)); + assert(run_test("data/stress-test-4/test-5-rnd-polygons-6-4.off" , ks, num_iters, num_tests)); + assert(run_test("data/stress-test-4/test-6-rnd-polygons-5-6.off" , ks, num_iters, num_tests)); + assert(run_test("data/stress-test-4/test-7-rnd-polygons-7-6.off" , ks, num_iters, num_tests)); + assert(run_test("data/stress-test-4/test-8-rnd-polygons-7-8.off" , ks, num_iters, num_tests)); + assert(run_test("data/stress-test-4/test-9-rnd-polygons-12-4.off", ks, num_iters, num_tests)); // Real data tests. - assert(run_test("data/real-data-test/building-a-10polygons-10planes.off", num_iters, num_tests)); - assert(run_test("data/real-data-test/building-b-15squares-15planes.off" , num_iters, num_tests)); + assert(run_test("data/real-data-test/building-a-10polygons-10planes.off", ks, num_iters, num_tests)); + assert(run_test("data/real-data-test/building-b-15squares-15planes.off" , ks, num_iters, num_tests)); // Edge case tests. - assert(run_test("data/edge-case-test/test-2-polygons.off" , num_iters, num_tests)); // edge touch - assert(run_test("data/edge-case-test/test-4-polygons.off" , num_iters, num_tests)); // edge touch / 2 coplanar - assert(run_test("data/edge-case-test/test-5-polygons.off" , num_iters, num_tests)); // edge touch / vertex touch / 2 coplanar - // assert(run_test("data/edge-case-test/test-20-polygons.off", num_iters, num_tests)); // 2 overlap and coplanar + assert(run_test("data/edge-case-test/test-2-polygons.off" , ks, num_iters, num_tests)); // edge touch + assert(run_test("data/edge-case-test/test-4-polygons.off" , ks, num_iters, num_tests)); // edge touch / 2 coplanar + assert(run_test("data/edge-case-test/test-5-polygons.off" , ks, num_iters, num_tests)); // edge touch / vertex touch / 2 coplanar + + std::vector ts; + ts.push_back(1); ts.push_back(2); ts.push_back(4); + ts.push_back(5); ts.push_back(6); ts.push_back(100); + assert(run_test("data/edge-case-test/test-20-polygons.off", ts, num_iters, num_tests)); // 2 overlap and coplanar std::cout << std::endl << "--OUTPUT STATS:" << std::endl; std::cout << "* number of iterations per test: " << num_iters << std::endl; - std::cout << "* k intersections: {1,2,3,4,5,6,100}" << std::endl; + std::cout << "* k intersections: {"; + for (const auto k : ks) { + std::cout << k << ","; + } + std::cout << "...}" << std::endl; std::cout << std::endl << "ALL " << num_tests << " TESTS SUCCESS!" << std::endl; return EXIT_SUCCESS;