mirror of https://github.com/CGAL/cgal
use convex hull
This commit is contained in:
parent
07a6d3ae4d
commit
f2c774d327
|
|
@ -26,14 +26,17 @@
|
||||||
#include <CGAL/Optimal_bounding_box/population.h>
|
#include <CGAL/Optimal_bounding_box/population.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <CGAL/Surface_mesh.h>
|
|
||||||
#include <CGAL/Simple_cartesian.h>
|
|
||||||
#include <CGAL/boost/graph/helpers.h>
|
#include <CGAL/boost/graph/helpers.h>
|
||||||
#include <CGAL/Bbox_3.h>
|
#include <CGAL/Bbox_3.h>
|
||||||
#include <CGAL/Iso_cuboid_3.h>
|
#include <CGAL/Iso_cuboid_3.h>
|
||||||
|
#include <CGAL/convex_hull_3.h>
|
||||||
|
|
||||||
#include <Eigen/Dense>
|
#include <Eigen/Dense>
|
||||||
|
|
||||||
|
#include <CGAL/Surface_mesh.h>
|
||||||
|
#include <CGAL/Polyhedron_3.h>
|
||||||
|
#include <CGAL/Simple_cartesian.h>
|
||||||
|
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
namespace Optimal_bounding_box {
|
namespace Optimal_bounding_box {
|
||||||
|
|
@ -136,11 +139,23 @@ void post_processing(Matrix& points, Matrix& R, Matrix& obb)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Matrix, typename Point>
|
||||||
|
void fill_matrix(std::vector<Point>& 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 points point coordinates of the input mesh
|
||||||
/// @param obb_points the 8 points of the obb.
|
/// @param obb_points the 8 points of the obb.
|
||||||
template <typename Point>
|
template <typename Point>
|
||||||
void find_obb(std::vector<Point>& points, std::vector<Point>& obb_points)
|
void find_obb(std::vector<Point>& points, std::vector<Point>& obb_points, bool use_ch)
|
||||||
{
|
{
|
||||||
CGAL_assertion(points.size() >= 3);
|
CGAL_assertion(points.size() >= 3);
|
||||||
|
|
||||||
|
|
@ -148,18 +163,27 @@ void find_obb(std::vector<Point>& points, std::vector<Point>& obb_points)
|
||||||
obb_points.resize(8);
|
obb_points.resize(8);
|
||||||
CGAL_assertion(obb_points.size() == 8);
|
CGAL_assertion(obb_points.size() == 8);
|
||||||
|
|
||||||
// points: vector -> matrix
|
|
||||||
typedef Eigen::MatrixXf MatrixXf;
|
|
||||||
|
|
||||||
MatrixXf points_mat(points.size(), 3);
|
typedef Eigen::MatrixXf MatrixXf; // using eigen internally
|
||||||
for(std::size_t i = 0; i < points.size(); ++i)
|
MatrixXf points_mat;
|
||||||
|
|
||||||
|
// get the ch3
|
||||||
|
if(use_ch)
|
||||||
{
|
{
|
||||||
Point p = points[i];
|
// find the ch - todo: template kernel
|
||||||
points_mat(i, 0) = p.x();
|
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
||||||
points_mat(i, 1) = p.y();
|
CGAL::Polyhedron_3<Kernel> poly;
|
||||||
points_mat(i, 2) = p.z();
|
convex_hull_3(points.begin(), points.end(), poly);
|
||||||
}
|
std::vector<Kernel::Point_3> 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);
|
MatrixXf R(3, 3);
|
||||||
std::size_t generations = 10;
|
std::size_t generations = 10;
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,16 @@ void sm_to_matrix(SurfaceMesh& sm, Matrix& mat)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename SurfaceMesh, typename Point>
|
||||||
|
void gather_mesh_points(SurfaceMesh& mesh, std::vector<Point>& points)
|
||||||
|
{
|
||||||
|
typedef typename boost::graph_traits<SurfaceMesh>::vertex_descriptor vertex_descriptor;
|
||||||
|
typedef typename boost::property_map<SurfaceMesh, CGAL::vertex_point_t>::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()
|
void test_population()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -293,7 +303,63 @@ void rotate_tetrahedron(const char* fname, const char* Rname)
|
||||||
MatrixXf obb(8, 3);
|
MatrixXf obb(8, 3);
|
||||||
CGAL::Optimal_bounding_box::post_processing(points, R, obb);
|
CGAL::Optimal_bounding_box::post_processing(points, R, obb);
|
||||||
CGAL::Optimal_bounding_box::matrix_to_mesh_and_draw(obb, "data/inverse_rotated.off");
|
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<K::Point_3> 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<K::Point_3> sm_points;
|
||||||
|
gather_mesh_points(mesh, sm_points);
|
||||||
|
|
||||||
|
std::vector<K::Point_3> 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<K::Point_3> 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_nelder_mead();
|
||||||
test_genetic_algorithm();
|
test_genetic_algorithm();
|
||||||
test_random_unit_tetra();
|
test_random_unit_tetra();
|
||||||
|
|
||||||
test_reference_tetrahedron("data/reference_tetrahedron.off");
|
test_reference_tetrahedron("data/reference_tetrahedron.off");
|
||||||
test_long_tetrahedron("data/long_tetrahedron.off");
|
test_long_tetrahedron("data/long_tetrahedron.off");
|
||||||
rotate_tetrahedron("data/random_unit_tetra.off", "data/rotation.dat");
|
rotate_tetrahedron("data/random_unit_tetra.off", "data/rotation.dat");
|
||||||
|
test_find_obb("data/random_unit_tetra.off");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ void Create_obb_mesh_plugin::obb()
|
||||||
|
|
||||||
// find obb
|
// find obb
|
||||||
std::vector<Point_3> obb_points(8);
|
std::vector<Point_3> 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;
|
Scene_item* item;
|
||||||
if(mw->property("is_polyhedorn_mode").toBool()){
|
if(mw->property("is_polyhedorn_mode").toBool()){
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue