From f2c774d3275adf72862a9cfb38c13a13b2817a56 Mon Sep 17 00:00:00 2001 From: Konstantinos Katrioplas Date: Wed, 2 May 2018 13:28:47 +0200 Subject: [PATCH] use convex hull --- .../include/CGAL/Optimal_bounding_box/obb.h | 48 +++++++++---- .../test_optimization_algorithms.cpp | 70 ++++++++++++++++++- .../Plugins/PCA/Create_obb_mesh_plugin.cpp | 2 +- 3 files changed, 104 insertions(+), 16 deletions(-) diff --git a/Optimal_bounding_box/include/CGAL/Optimal_bounding_box/obb.h b/Optimal_bounding_box/include/CGAL/Optimal_bounding_box/obb.h index 48e03ee2ece..fb936a53491 100644 --- a/Optimal_bounding_box/include/CGAL/Optimal_bounding_box/obb.h +++ b/Optimal_bounding_box/include/CGAL/Optimal_bounding_box/obb.h @@ -26,14 +26,17 @@ #include #include #include -#include -#include #include #include #include +#include #include +#include +#include +#include +#include namespace CGAL { namespace Optimal_bounding_box { @@ -136,11 +139,23 @@ void post_processing(Matrix& points, Matrix& R, Matrix& obb) } +template +void fill_matrix(std::vector& v_points, Matrix& points_mat) +{ + points_mat.resize(v_points.size(), 3); + for(std::size_t i = 0; i < v_points.size(); ++i) + { + Point p = v_points[i]; + points_mat(i, 0) = p.x(); + points_mat(i, 1) = p.y(); + points_mat(i, 2) = p.z(); + } +} /// @param points point coordinates of the input mesh /// @param obb_points the 8 points of the obb. template -void find_obb(std::vector& points, std::vector& obb_points) +void find_obb(std::vector& points, std::vector& obb_points, bool use_ch) { CGAL_assertion(points.size() >= 3); @@ -148,18 +163,27 @@ void find_obb(std::vector& points, std::vector& obb_points) obb_points.resize(8); CGAL_assertion(obb_points.size() == 8); - // points: vector -> matrix - typedef Eigen::MatrixXf MatrixXf; - MatrixXf points_mat(points.size(), 3); - for(std::size_t i = 0; i < points.size(); ++i) + typedef Eigen::MatrixXf MatrixXf; // using eigen internally + MatrixXf points_mat; + + // get the ch3 + if(use_ch) { - Point p = points[i]; - points_mat(i, 0) = p.x(); - points_mat(i, 1) = p.y(); - points_mat(i, 2) = p.z(); - } + // find the ch - todo: template kernel + typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; + CGAL::Polyhedron_3 poly; + convex_hull_3(points.begin(), points.end(), poly); + std::vector ch_points(poly.points_begin(), poly.points_end()); + // points: vector -> matrix + fill_matrix(ch_points, points_mat); + } + else + { + // points: vector -> matrix + fill_matrix(points, points_mat); + } MatrixXf R(3, 3); std::size_t generations = 10; diff --git a/Optimal_bounding_box/test/Optimal_bounding_box/test_optimization_algorithms.cpp b/Optimal_bounding_box/test/Optimal_bounding_box/test_optimization_algorithms.cpp index 8e646c68479..caf02e2334c 100644 --- a/Optimal_bounding_box/test/Optimal_bounding_box/test_optimization_algorithms.cpp +++ b/Optimal_bounding_box/test/Optimal_bounding_box/test_optimization_algorithms.cpp @@ -41,6 +41,16 @@ void sm_to_matrix(SurfaceMesh& sm, Matrix& mat) } } +template +void gather_mesh_points(SurfaceMesh& mesh, std::vector& points) +{ + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::property_map::type PointPMap; + PointPMap pmap = get(boost::vertex_point, mesh); + BOOST_FOREACH(vertex_descriptor v, vertices(mesh)) + points.push_back(get(pmap, v)); +} + void test_population() { @@ -293,7 +303,63 @@ void rotate_tetrahedron(const char* fname, const char* Rname) MatrixXf obb(8, 3); CGAL::Optimal_bounding_box::post_processing(points, R, obb); CGAL::Optimal_bounding_box::matrix_to_mesh_and_draw(obb, "data/inverse_rotated.off"); +} +void test_find_obb(std::string fname) +{ + std::ifstream input(fname); + CGAL::Surface_mesh mesh; + if (!input || !(input >> mesh) || mesh.is_empty()) { + std::cerr << fname << " is not a valid off file.\n"; + exit(1); + } + + // get mesh points + std::vector sm_points; + gather_mesh_points(mesh, sm_points); + + std::vector obb_points; + CGAL::Optimal_bounding_box::find_obb(sm_points, obb_points, true); + + double epsilon = 1e-4; + CGAL_assertion(assert_doubles(obb_points[0].x(), 1.01752, epsilon)); + CGAL_assertion(assert_doubles(obb_points[0].y(), 0.437675, epsilon)); + CGAL_assertion(assert_doubles(obb_points[0].z(), 0.382697, epsilon)); + CGAL_assertion(assert_doubles(obb_points[1].x(), 0.912648, epsilon)); + CGAL_assertion(assert_doubles(obb_points[1].y(), 0.761563, epsilon)); + CGAL_assertion(assert_doubles(obb_points[1].z(), 0.160329, epsilon)); + CGAL_assertion(assert_doubles(obb_points[2].x(), 0.0615854, epsilon)); + CGAL_assertion(assert_doubles(obb_points[2].y(), 0.473799, epsilon)); + CGAL_assertion(assert_doubles(obb_points[2].z(), 0.142574, epsilon)); + CGAL_assertion(assert_doubles(obb_points[3].x(), 0.166461, epsilon)); + CGAL_assertion(assert_doubles(obb_points[3].y(), 0.149911, epsilon)); + CGAL_assertion(assert_doubles(obb_points[3].z(), 0.364943, epsilon)); + CGAL_assertion(assert_doubles(obb_points[4].x(), 0.0316104, epsilon)); + CGAL_assertion(assert_doubles(obb_points[4].y(), 0.512247, epsilon)); + CGAL_assertion(assert_doubles(obb_points[4].z(), 0.956296, epsilon)); + CGAL_assertion(assert_doubles(obb_points[5].x(), 0.882673, epsilon)); + CGAL_assertion(assert_doubles(obb_points[5].y(), 0.800011, epsilon)); + CGAL_assertion(assert_doubles(obb_points[5].z(), 0.97405, epsilon)); + CGAL_assertion(assert_doubles(obb_points[6].x(), 0.777797, epsilon)); + CGAL_assertion(assert_doubles(obb_points[6].y(), 1.1239, epsilon)); + CGAL_assertion(assert_doubles(obb_points[6].z(), 0.751681, epsilon)); + CGAL_assertion(assert_doubles(obb_points[7].x(), -0.0732647, epsilon)); + CGAL_assertion(assert_doubles(obb_points[7].y(), 0.836134, epsilon)); + CGAL_assertion(assert_doubles(obb_points[7].z(), 0.733927, epsilon)); + + /* debug + for(int i = 0; i < 8; ++i) + { + std::cout << obb_points[i].x() << " " << obb_points[i].y() << " " << obb_points[i].z() << "\n" ; + } + CGAL::Surface_mesh result_mesh; + CGAL::make_hexahedron(obb_points[0], obb_points[1], obb_points[2], obb_points[3], + obb_points[4], obb_points[5], obb_points[6], obb_points[7], result_mesh); + + std::ofstream out("data/obb_result.off"); + out << result_mesh; + out.close(); + */ } @@ -306,12 +372,10 @@ int main() test_nelder_mead(); test_genetic_algorithm(); test_random_unit_tetra(); - test_reference_tetrahedron("data/reference_tetrahedron.off"); test_long_tetrahedron("data/long_tetrahedron.off"); rotate_tetrahedron("data/random_unit_tetra.off", "data/rotation.dat"); - - + test_find_obb("data/random_unit_tetra.off"); diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Create_obb_mesh_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Create_obb_mesh_plugin.cpp index 22af3fa7a0b..35c98a4d74f 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Create_obb_mesh_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Create_obb_mesh_plugin.cpp @@ -107,7 +107,7 @@ void Create_obb_mesh_plugin::obb() // find obb std::vector obb_points(8); - CGAL::Optimal_bounding_box::find_obb(points, obb_points); + CGAL::Optimal_bounding_box::find_obb(points, obb_points, true); Scene_item* item; if(mw->property("is_polyhedorn_mode").toBool()){