279 lines
10 KiB
C++

/*
* Software License Agreement (BSD License)
*
* Point Cloud Library (PCL) - www.pointclouds.org
* Copyright (c) 2010-2012, Willow Garage, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Willow Garage, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
*
*/
#pragma once
#include <pcl/memory.h>
#include <pcl/pcl_macros.h>
#include <pcl/pcl_config.h>
#ifdef HAVE_QHULL
// PCL includes
#include <pcl/surface/reconstruction.h>
#include <pcl/PolygonMesh.h>
namespace pcl
{
/** \brief Sort 2D points in a vector structure
* \param p1 the first point
* \param p2 the second point
* \ingroup surface
*/
inline bool
comparePoints2D (const std::pair<int, Eigen::Vector4f> & p1, const std::pair<int, Eigen::Vector4f> & p2)
{
double angle1 = std::atan2 (p1.second[1], p1.second[0]) + M_PI;
double angle2 = std::atan2 (p2.second[1], p2.second[0]) + M_PI;
return (angle1 > angle2);
}
////////////////////////////////////////////////////////////////////////////////////////////
/** \brief @b ConvexHull using libqhull library.
* \author Aitor Aldoma, Alex Trevor
* \ingroup surface
*/
template<typename PointInT>
class ConvexHull : public MeshConstruction<PointInT>
{
protected:
using PCLBase<PointInT>::input_;
using PCLBase<PointInT>::indices_;
using PCLBase<PointInT>::initCompute;
using PCLBase<PointInT>::deinitCompute;
public:
using Ptr = shared_ptr<ConvexHull<PointInT> >;
using ConstPtr = shared_ptr<const ConvexHull<PointInT> >;
using MeshConstruction<PointInT>::reconstruct;
using PointCloud = pcl::PointCloud<PointInT>;
using PointCloudPtr = typename PointCloud::Ptr;
using PointCloudConstPtr = typename PointCloud::ConstPtr;
/** \brief Empty constructor. */
ConvexHull () : compute_area_ (false), total_area_ (0), total_volume_ (0), dimension_ (0),
projection_angle_thresh_ (std::cos (0.174532925) ), qhull_flags ("qhull "),
x_axis_ (1.0, 0.0, 0.0), y_axis_ (0.0, 1.0, 0.0), z_axis_ (0.0, 0.0, 1.0)
{
}
/** \brief Empty destructor */
~ConvexHull () {}
/** \brief Compute a convex hull for all points given.
*
* \note In 2D case (i.e. if the input points belong to one plane)
* the \a polygons vector will have a single item, whereas in 3D
* case it will contain one item for each hull facet.
*
* \param[out] points the resultant points lying on the convex hull.
* \param[out] polygons the resultant convex hull polygons, as a set of
* vertices. The Vertices structure contains an array of point indices.
*/
void
reconstruct (PointCloud &points,
std::vector<pcl::Vertices> &polygons);
/** \brief Compute a convex hull for all points given.
* \param[out] points the resultant points lying on the convex hull.
*/
void
reconstruct (PointCloud &points);
/** \brief If set to true, the qhull library is called to compute the total area and volume of the convex hull.
* NOTE: When this option is activated, the qhull library produces output to the console.
* \param[in] value whether to compute the area and the volume, default is false
*/
void
setComputeAreaVolume (bool value)
{
compute_area_ = value;
if (compute_area_)
qhull_flags = std::string ("qhull FA");
else
qhull_flags = std::string ("qhull ");
}
/** \brief Returns the total area of the convex hull. */
double
getTotalArea () const
{
return (total_area_);
}
/** \brief Returns the total volume of the convex hull. Only valid for 3-dimensional sets.
* For 2D-sets volume is zero.
*/
double
getTotalVolume () const
{
return (total_volume_);
}
/** \brief Sets the dimension on the input data, 2D or 3D.
* \param[in] dimension The dimension of the input data. If not set, this will be determined automatically.
*/
void
setDimension (int dimension)
{
if ((dimension == 2) || (dimension == 3))
dimension_ = dimension;
else
PCL_ERROR ("[pcl::%s::setDimension] Invalid input dimension specified!\n", getClassName ().c_str ());
}
/** \brief Returns the dimensionality (2 or 3) of the calculated hull. */
inline int
getDimension () const
{
return (dimension_);
}
/** \brief Retrieve the indices of the input point cloud that for the convex hull.
*
* \note Should only be called after reconstruction was performed.
* \param[out] hull_point_indices The indices of the points forming the point cloud
*/
void
getHullPointIndices (pcl::PointIndices &hull_point_indices) const;
protected:
/** \brief The actual reconstruction method.
*
* \param[out] points the resultant points lying on the convex hull
* \param[out] polygons the resultant convex hull polygons, as a set of
* vertices. The Vertices structure contains an array of point indices.
* \param[in] fill_polygon_data true if polygons should be filled, false otherwise
*/
void
performReconstruction (PointCloud &points,
std::vector<pcl::Vertices> &polygons,
bool fill_polygon_data = false);
/** \brief The reconstruction method for 2D data. Does not require dimension to be set.
*
* \param[out] points the resultant points lying on the convex hull
* \param[out] polygons the resultant convex hull polygons, as a set of
* vertices. The Vertices structure contains an array of point indices.
* \param[in] fill_polygon_data true if polygons should be filled, false otherwise
*/
void
performReconstruction2D (PointCloud &points,
std::vector<pcl::Vertices> &polygons,
bool fill_polygon_data = false);
/** \brief The reconstruction method for 3D data. Does not require dimension to be set.
*
* \param[out] points the resultant points lying on the convex hull
* \param[out] polygons the resultant convex hull polygons, as a set of
* vertices. The Vertices structure contains an array of point indices.
* \param[in] fill_polygon_data true if polygons should be filled, false otherwise
*/
void
performReconstruction3D (PointCloud &points,
std::vector<pcl::Vertices> &polygons,
bool fill_polygon_data = false);
/** \brief A reconstruction method that returns a polygonmesh.
*
* \param[out] output a PolygonMesh representing the convex hull of the input data.
*/
void
performReconstruction (PolygonMesh &output) override;
/** \brief A reconstruction method that returns the polygon of the convex hull.
*
* \param[out] polygons the polygon(s) representing the convex hull of the input data.
*/
void
performReconstruction (std::vector<pcl::Vertices> &polygons) override;
/** \brief Automatically determines the dimension of input data - 2D or 3D. */
void
calculateInputDimension ();
/** \brief Class get name method. */
std::string
getClassName () const override
{
return ("ConvexHull");
}
/* \brief True if we should compute the area and volume of the convex hull. */
bool compute_area_;
/* \brief The area of the convex hull. */
double total_area_;
/* \brief The volume of the convex hull (only for 3D hulls, zero for 2D). */
double total_volume_;
/** \brief The dimensionality of the concave hull (2D or 3D). */
int dimension_;
/** \brief How close can a 2D plane's normal be to an axis to make projection problematic. */
double projection_angle_thresh_;
/** \brief Option flag string to be used calling qhull. */
std::string qhull_flags;
/* \brief x-axis - for checking valid projections. */
const Eigen::Vector3d x_axis_;
/* \brief y-axis - for checking valid projections. */
const Eigen::Vector3d y_axis_;
/* \brief z-axis - for checking valid projections. */
const Eigen::Vector3d z_axis_;
/* \brief vector containing the point cloud indices of the convex hull points. */
pcl::PointIndices hull_indices_;
public:
PCL_MAKE_ALIGNED_OPERATOR_NEW
};
}
#ifdef PCL_NO_PRECOMPILE
#include <pcl/surface/impl/convex_hull.hpp>
#endif
#endif