Skip to content

Commit

Permalink
[geometry] Enhance Half_plane object based interface. openMVG#517
Browse files Browse the repository at this point in the history
- Add a Box construction in order to build Rectangular parallelepiped
- Add viewing debugging functions to export as PLY the Bounding Box & Frustum (Infinite or truncated)

- Add a contains function to test if a point is inside the volume build by the HalfPlanes
  - Add it's corresponding unit test
  • Loading branch information
pmoulon committed Apr 18, 2016
1 parent 5f75e14 commit 380a750
Show file tree
Hide file tree
Showing 5 changed files with 490 additions and 392 deletions.
118 changes: 103 additions & 15 deletions src/openMVG/geometry/box.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#define OPENMVG_GEOMETRY_BOX_HPP_

#include "openMVG/geometry/half_space_intersection.hpp"
#include <fstream>

namespace openMVG
{
Expand All @@ -29,7 +30,8 @@ struct Box : public HalfPlaneObject
{
/// Points that define the bounding box
Vec3 points[8];


/// Define a Square bounding box from a center position and radius (center to corner distance)
Box
(
const Vec3 & center,
Expand All @@ -41,25 +43,111 @@ struct Box : public HalfPlaneObject
{
// Top face
(R * Vec3(-1,-1,1).normalized()) * radius + center,
(R * Vec3(-1,1,1).normalized()) * radius + center,
(R * Vec3(1,1,1).normalized()) * radius + center,
(R * Vec3(1,-1,1).normalized()) * radius + center,
(R * Vec3(-1, 1,1).normalized()) * radius + center,
(R * Vec3( 1, 1,1).normalized()) * radius + center,
(R * Vec3( 1,-1,1).normalized()) * radius + center,
// Bottom face
(R * Vec3(-1,-1,-1).normalized()) * radius + center,
(R * Vec3(-1,1,-1).normalized()) * radius + center,
(R * Vec3(1,1,-1).normalized()) * radius + center,
(R * Vec3(1,-1,-1).normalized()) * radius + center
(R * Vec3(-1, 1,-1).normalized()) * radius + center,
(R * Vec3( 1, 1,-1).normalized()) * radius + center,
(R * Vec3( 1,-1,-1).normalized()) * radius + center
};
std::copy(directions, directions + 8, points);

// Defines the 6 half_planes that defines the supporting volume
planes.push_back( Half_plane_p( directions[0], directions[1], directions[3] ) ); // Top
planes.push_back( Half_plane_p( directions[4], directions[7], directions[5] ) ); // Bottom

// Defines the supporting volume thanks to 6 half_planes
planes.push_back( Half_plane_p( points[0], points[1], points[3] ) ); // Top
planes.push_back( Half_plane_p( points[4], points[7], points[5] ) ); // Bottom
// Define remaining supporting planes (box borders)
planes.push_back( Half_plane_p( points[0], points[4], points[1] ) );
planes.push_back( Half_plane_p( points[0], points[3], points[4] ) );
planes.push_back( Half_plane_p( points[3], points[2], points[7] ) );
planes.push_back( Half_plane_p( points[1], points[5], points[2] ) );
}

/// Define a Rectangular parallelepiped bounding box from min/max axis aligned positions
Box
(
const double x_min,
const double y_min,
const double z_min,
const double x_max,
const double y_max,
const double z_max
)
{
const Vec3 points_[8] =
{
// Top face
Vec3(x_min, y_min, z_max),
Vec3(x_min, y_max, z_max),
Vec3(x_max, y_max, z_max),
Vec3(x_max, y_min, z_max),
// Bottom face
Vec3(x_min, y_min, z_min),
Vec3(x_min, y_max, z_min),
Vec3(x_max, y_max, z_min),
Vec3(x_max, y_min, z_min),
};
std::copy(points_, points_ + 8, points);

// Defines the supporting volume thanks to 6 half_planes
planes.push_back( Half_plane_p( points[0], points[1], points[3] ) ); // Top
planes.push_back( Half_plane_p( points[4], points[7], points[5] ) ); // Bottom
// Define remaining supporting planes (box borders)
planes.push_back( Half_plane_p( directions[0], directions[4], directions[1] ) );
planes.push_back( Half_plane_p( directions[0], directions[3], directions[4] ) );
planes.push_back( Half_plane_p( directions[3], directions[2], directions[7] ) );
planes.push_back( Half_plane_p( directions[1], directions[5], directions[2] ) );
planes.push_back( Half_plane_p( points[0], points[4], points[1] ) );
planes.push_back( Half_plane_p( points[0], points[3], points[4] ) );
planes.push_back( Half_plane_p( points[3], points[2], points[7] ) );
planes.push_back( Half_plane_p( points[1], points[5], points[2] ) );
}

/**
* @brief Export the Box as a PLY file
* @return true if the file can be saved on disk
*/
static bool export_Ply
(
const Box & box,
const std::string & filename,
const Vec3 color = Vec3(0, 255, 0)
)
{
std::ofstream of(filename.c_str());
if (!of.is_open())
return false;

of << "ply" << '\n'
<< "format ascii 1.0" << '\n'
<< "element vertex 8\n"
<< "property float x" << '\n'
<< "property float y" << '\n'
<< "property float z" << '\n'
<< "property uchar red" << '\n'
<< "property uchar green" << '\n'
<< "property uchar blue" << '\n'
<< "element face 6 \n"
<< "property list uchar int vertex_index" << '\n'
<< "end_header" << '\n';

// Export box points
{
for (int i = 0; i < 8; ++i)
of << box.points[i].transpose() << " " << color.cast<int>() << '\n';
}

of
// top & bottom planes
<< "3 0 1 3\n"
<< "3 4 7 5\n"
// remaining planes
<< "3 0 4 1\n"
<< "3 0 3 4\n"
<< "3 3 2 7\n"
<< "3 1 5 2\n";

of.flush();
const bool bOk = of.good();
of.close();
return bOk;
}
};

Expand Down
Loading

0 comments on commit 380a750

Please sign in to comment.