mirror of https://github.com/CGAL/cgal
Update API of Classification + reference manual
This commit is contained in:
parent
38b0aedebe
commit
bfb89cca73
|
|
@ -23,9 +23,6 @@
|
|||
|
||||
#include <CGAL/license/Classification.h>
|
||||
|
||||
#define DO_NOT_USE_EIGEN_FEATURES
|
||||
#define DO_NOT_USE_HSV_FEATURES
|
||||
|
||||
#include <CGAL/Classification/classify.h>
|
||||
#include <CGAL/Classification/Sum_of_weighted_features_classifier.h>
|
||||
#include <CGAL/Classification/ETHZ_random_forest_classifier.h>
|
||||
|
|
@ -47,6 +44,7 @@
|
|||
#include <CGAL/Classification/Point_set_neighborhood.h>
|
||||
#include <CGAL/Classification/Mesh_feature_generator.h>
|
||||
#include <CGAL/Classification/Mesh_neighborhood.h>
|
||||
#include <CGAL/Classification/property_maps.h>
|
||||
|
||||
#include <CGAL/Classification/Feature/Cluster_mean_of_feature.h>
|
||||
#include <CGAL/Classification/Feature/Cluster_size.h>
|
||||
|
|
|
|||
|
|
@ -28,13 +28,31 @@ namespace CGAL {
|
|||
namespace Classification {
|
||||
|
||||
|
||||
/*!
|
||||
\ingroup PkgClassificationCluster
|
||||
|
||||
\brief Class that represent a cluster of items to be classified as
|
||||
a single atomic object.
|
||||
|
||||
A cluster is a set of indices of items inside an input range with
|
||||
random access.
|
||||
|
||||
\tparam ItemRange model of `ConstRange`. Its iterator type is
|
||||
`RandomAccessIterator`. Its value type depends on the data that is
|
||||
classified (for example, `CGAL::Point_3` or `CGAL::Triangle_3`).
|
||||
|
||||
\tparam ItemMap model of `ReadablePropertyMap` whose key
|
||||
type is the value type of the iterator of `ItemRange` and value type
|
||||
is the type of item to classify (for example, `CGAL::Point_3`).
|
||||
*/
|
||||
template <typename ItemRange, typename ItemMap>
|
||||
class Cluster
|
||||
{
|
||||
public:
|
||||
|
||||
typedef typename ItemMap::value_type Item;
|
||||
|
||||
|
||||
/// \cond SKIP_IN_MANUAL
|
||||
struct Neighbor_query
|
||||
{
|
||||
template <typename OutputIterator>
|
||||
|
|
@ -43,6 +61,8 @@ public:
|
|||
return std::copy (cluster.neighbors.begin(), cluster.neighbors.end(), output);
|
||||
}
|
||||
};
|
||||
std::vector<std::size_t> neighbors;
|
||||
/// \endcond
|
||||
|
||||
private:
|
||||
const ItemRange* m_range;
|
||||
|
|
@ -54,21 +74,62 @@ private:
|
|||
int m_label;
|
||||
|
||||
public:
|
||||
std::vector<std::size_t> neighbors;
|
||||
|
||||
|
||||
/// \name Constructor
|
||||
/// @{
|
||||
|
||||
/*!
|
||||
\brief Constructs an empty cluster of items.
|
||||
|
||||
Items in the clusters will be subsets of `range`.
|
||||
|
||||
\param range input range.
|
||||
\param item_map property map to access the input items.
|
||||
*/
|
||||
Cluster (const ItemRange& range, ItemMap item_map)
|
||||
: m_range (&range), m_item_map (item_map)
|
||||
, m_training(-1), m_label(-1)
|
||||
{ }
|
||||
|
||||
void insert (std::size_t idx) { m_inliers.push_back (idx); }
|
||||
/// @}
|
||||
|
||||
/// \name Modifications
|
||||
/// @{
|
||||
|
||||
/*!
|
||||
\brief Clears the cluster.
|
||||
*/
|
||||
void clear () { m_inliers.clear(); }
|
||||
|
||||
/*!
|
||||
\brief Inserts element of index `idx` in the cluster.
|
||||
*/
|
||||
void insert (std::size_t idx) { m_inliers.push_back (idx); }
|
||||
|
||||
/// @}
|
||||
|
||||
/// \name Access
|
||||
/// @{
|
||||
|
||||
/*!
|
||||
\brief Returns the number of items in the cluster.
|
||||
*/
|
||||
std::size_t size() const { return m_inliers.size(); }
|
||||
|
||||
/*!
|
||||
\brief Returns the index (in the input range) of the i^{th} element of the cluster.
|
||||
*/
|
||||
std::size_t index (std::size_t i) const { return m_inliers[i]; }
|
||||
|
||||
/*!
|
||||
\brief Returns the i^{th} item of the cluster.
|
||||
*/
|
||||
const Item& operator[] (std::size_t i) const
|
||||
{ return get (m_item_map, *(m_range->begin() + m_inliers[i])); }
|
||||
|
||||
/*!
|
||||
\brief Returns the bounding box of the cluster.
|
||||
*/
|
||||
CGAL::Bbox_3 bbox() const
|
||||
{
|
||||
if (m_bounding_box == CGAL::Bbox_3())
|
||||
|
|
@ -85,14 +146,61 @@ public:
|
|||
return m_bounding_box;
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// \name Classification
|
||||
/// @{
|
||||
|
||||
/*!
|
||||
\brief Returns the input classification value used for training.
|
||||
*/
|
||||
int training() const { return m_training; }
|
||||
|
||||
/*!
|
||||
\brief Returns a reference to the input classification value used for training.
|
||||
*/
|
||||
int& training() { return m_training; }
|
||||
|
||||
/*!
|
||||
\brief Returns the output classification value.
|
||||
*/
|
||||
int label() const { return m_label; }
|
||||
|
||||
int& training() { return m_training; }
|
||||
/*!
|
||||
\brief Returns a reference to the output classification value.
|
||||
*/
|
||||
int& label() { return m_label; }
|
||||
|
||||
// @}
|
||||
};
|
||||
|
||||
/*!
|
||||
\ingroup PkgClassificationCluster
|
||||
|
||||
\brief Given a set of cluster indices, segments the input `range`
|
||||
into `Cluster` objects.
|
||||
|
||||
All items whose index value `idx` (accessed through `index_map`)
|
||||
is the same are stored in the same cluster at position `idx` in
|
||||
the `clusters` vector.
|
||||
|
||||
\tparam ItemRange model of `ConstRange`. Its iterator type is
|
||||
`RandomAccessIterator`. Its value type depends on the data that is
|
||||
classified (for example, `CGAL::Point_3` or `CGAL::Triangle_3`).
|
||||
|
||||
\tparam ItemMap model of `ReadablePropertyMap` whose key
|
||||
type is the value type of the iterator of `ItemRange` and value type
|
||||
is the type of item to classify (for example, `CGAL::Point_3`).
|
||||
|
||||
\tparam IndexMap is a model of `ReadablePropertyMap` with value type `int`.
|
||||
|
||||
\param range input range.
|
||||
\param item_map property map to access the input items.
|
||||
\param index_map property map that associates the index of an item
|
||||
in the input range to the index of a cluster (-1 if item is not
|
||||
assigned to a cluster).
|
||||
\param clusters container where generated `Cluster` objects are stored.
|
||||
*/
|
||||
template <typename ItemRange, typename ItemMap, typename IndexMap>
|
||||
std::size_t create_clusters_from_indices (const ItemRange& range,
|
||||
ItemMap item_map,
|
||||
|
|
@ -102,7 +210,7 @@ std::size_t create_clusters_from_indices (const ItemRange& range,
|
|||
std::size_t idx = 0;
|
||||
for (typename ItemRange::const_iterator it = range.begin(); it != range.end(); ++ it, ++ idx)
|
||||
{
|
||||
int c = int(get (index_map, *it));
|
||||
int c = int(get (index_map, idx));
|
||||
if (c == -1)
|
||||
continue;
|
||||
if (std::size_t(c) >= clusters.size())
|
||||
|
|
|
|||
|
|
@ -32,12 +32,31 @@ namespace Classification {
|
|||
|
||||
namespace Feature {
|
||||
|
||||
/*!
|
||||
\ingroup PkgClassificationCluster
|
||||
|
||||
\brief %Feature that computes the mean values of an itemwise
|
||||
feature over the respective items of clusters.
|
||||
|
||||
Its default name is "mean_" + the name of the itemwise feature.
|
||||
*/
|
||||
class Cluster_mean_of_feature : public CGAL::Classification::Feature_base
|
||||
{
|
||||
std::vector<float> m_values;
|
||||
|
||||
public:
|
||||
|
||||
/*!
|
||||
\brief Constructs the feature.
|
||||
|
||||
\tparam PointRange model of `ConstRange`. Its iterator type
|
||||
is `RandomAccessIterator` and its value type is the key type of
|
||||
`Cluster`.
|
||||
|
||||
\param clusters input range.
|
||||
\param itemwise_feature feature that takes values on the range of
|
||||
items from which `clusters` is a subset.
|
||||
*/
|
||||
template <typename ClusterRange>
|
||||
Cluster_mean_of_feature (ClusterRange& clusters,
|
||||
Feature_handle itemwise_feature)
|
||||
|
|
@ -58,11 +77,12 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
/// \cond SKIP_IN_MANUAL
|
||||
virtual float value (std::size_t cluster_index)
|
||||
{
|
||||
return m_values[cluster_index];
|
||||
}
|
||||
|
||||
/// \endcond
|
||||
};
|
||||
|
||||
} // namespace Feature
|
||||
|
|
|
|||
|
|
@ -32,12 +32,28 @@ namespace Classification {
|
|||
|
||||
namespace Feature {
|
||||
|
||||
/*!
|
||||
\ingroup PkgClassificationCluster
|
||||
|
||||
\brief %Feature that returns the size of each cluster.
|
||||
|
||||
Its default name is "cluster_size".
|
||||
*/
|
||||
class Cluster_size : public CGAL::Classification::Feature_base
|
||||
{
|
||||
std::vector<float> m_values;
|
||||
|
||||
public:
|
||||
|
||||
/*!
|
||||
\brief Constructs the feature.
|
||||
|
||||
\tparam PointRange model of `ConstRange`. Its iterator type
|
||||
is `RandomAccessIterator` and its value type is the key type of
|
||||
`Cluster`.
|
||||
|
||||
\param clusters input range.
|
||||
*/
|
||||
template <typename ClusterRange>
|
||||
Cluster_size (ClusterRange& clusters)
|
||||
{
|
||||
|
|
@ -48,11 +64,12 @@ public:
|
|||
m_values.push_back (float(clusters[i].size()));
|
||||
}
|
||||
|
||||
/// \cond SKIP_IN_MANUAL
|
||||
virtual float value (std::size_t cluster_index)
|
||||
{
|
||||
return m_values[cluster_index];
|
||||
}
|
||||
|
||||
/// \endcond
|
||||
};
|
||||
|
||||
} // namespace Feature
|
||||
|
|
|
|||
|
|
@ -32,12 +32,33 @@ namespace Classification {
|
|||
|
||||
namespace Feature {
|
||||
|
||||
/*!
|
||||
\ingroup PkgClassificationCluster
|
||||
|
||||
\brief %Feature that computes the variance values of an itemwise
|
||||
feature over the respective items of clusters.
|
||||
|
||||
Its default name is "variance_" + the name of the itemwise feature.
|
||||
*/
|
||||
class Cluster_variance_of_feature : public CGAL::Classification::Feature_base
|
||||
{
|
||||
std::vector<float> m_values;
|
||||
|
||||
public:
|
||||
|
||||
/*!
|
||||
\brief Constructs the feature.
|
||||
|
||||
\tparam PointRange model of `ConstRange`. Its iterator type
|
||||
is `RandomAccessIterator` and its value type is the key type of
|
||||
`Cluster`.
|
||||
|
||||
\param clusters input range.
|
||||
\param itemwise_feature feature that takes values on the range of
|
||||
items from which `clusters` is a subset.
|
||||
\param mean_feature `Cluster_mean_of_feature` computed on
|
||||
`itemwise_feature`.
|
||||
*/
|
||||
template <typename ClusterRange>
|
||||
Cluster_variance_of_feature (ClusterRange& clusters,
|
||||
Feature_handle itemwise_feature,
|
||||
|
|
@ -63,10 +84,12 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
/// \cond SKIP_IN_MANUAL
|
||||
virtual float value (std::size_t cluster_index)
|
||||
{
|
||||
return m_values[cluster_index];
|
||||
}
|
||||
/// \endcond
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -32,12 +32,29 @@ namespace Classification {
|
|||
|
||||
namespace Feature {
|
||||
|
||||
/*!
|
||||
\ingroup PkgClassificationCluster
|
||||
|
||||
\brief %Feature that returns the length of the smallest interval
|
||||
on the `Z` axis that contains all the items of a cluster.
|
||||
|
||||
Its default name is "cluster_vertical_extent".
|
||||
*/
|
||||
class Cluster_vertical_extent : public CGAL::Classification::Feature_base
|
||||
{
|
||||
std::vector<float> m_values;
|
||||
|
||||
public:
|
||||
|
||||
/*!
|
||||
\brief Constructs the feature.
|
||||
|
||||
\tparam PointRange model of `ConstRange`. Its iterator type
|
||||
is `RandomAccessIterator` and its value type is the key type of
|
||||
`Cluster`.
|
||||
|
||||
\param clusters input range.
|
||||
*/
|
||||
template <typename ClusterRange>
|
||||
Cluster_vertical_extent (const ClusterRange& clusters)
|
||||
{
|
||||
|
|
@ -62,7 +79,9 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
/// \cond SKIP_IN_MANUAL
|
||||
virtual float value (std::size_t cluster_index) { return m_values[cluster_index]; }
|
||||
/// \endcond
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ protected:
|
|||
public:
|
||||
|
||||
template <typename InputRange>
|
||||
Eigenvalue (const InputRange& r,
|
||||
Eigenvalue (const InputRange&,
|
||||
const Classification::Local_eigen_analysis& eigen,
|
||||
std::size_t idx)
|
||||
: eigen (eigen), m_idx (idx)
|
||||
|
|
|
|||
|
|
@ -59,14 +59,15 @@ public:
|
|||
|
||||
\tparam InputRange model of `ConstRange`. Its iterator type
|
||||
is `RandomAccessIterator`.
|
||||
\param input point range.
|
||||
\param input input range.
|
||||
\param eigen class with precomputed eigenvectors and eigenvalues.
|
||||
*/
|
||||
template <typename InputRange>
|
||||
Verticality (const InputRange&,
|
||||
Verticality (const InputRange& input,
|
||||
const Local_eigen_analysis& eigen)
|
||||
: vertical (0., 0., 1.), eigen (&eigen)
|
||||
{
|
||||
CGAL_USE(input);
|
||||
this->set_name ("verticality");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -408,9 +408,7 @@ public:
|
|||
using `Eigen_diagonalize_traits` is provided. Otherwise, the
|
||||
internal implementation `Diagonalize_traits` is used.
|
||||
|
||||
\param input point range.
|
||||
\param point_map property map to access the input points.
|
||||
\param neighbor_query object used to access neighborhoods of points.
|
||||
\param input cluster range.
|
||||
*/
|
||||
template <typename ClusterRange,
|
||||
#if defined(DOXYGEN_RUNNING)
|
||||
|
|
|
|||
|
|
@ -57,10 +57,37 @@ namespace CGAL {
|
|||
namespace Classification {
|
||||
|
||||
/*!
|
||||
\ingroup PkgClassificationDataStructures
|
||||
\ingroup PkgClassificationMesh
|
||||
|
||||
\brief Generates a set of generic features for surface mesh
|
||||
classification.
|
||||
|
||||
This class takes care of computing all necessary data structures and
|
||||
of generating a set of generic features at multiple scales to
|
||||
increase the reliability of the classification.
|
||||
|
||||
A `PointMap` is required: this map should associate each face of the
|
||||
mesh to a representative point (for example, the center of mass of
|
||||
the face). It is used to generate point set features by considering
|
||||
the mesh as a point set.
|
||||
|
||||
\tparam GeomTraits model of \cgal Kernel.
|
||||
\tparam FaceListGraph model of `FaceListGraph`.
|
||||
\tparam PointMap model of `ReadablePropertyMap` whose key type is
|
||||
`boost::graph_traits<FaceListGraph>::%face_descriptor` and value type
|
||||
is `GeomTraits::Point_3`.
|
||||
\tparam ConcurrencyTag enables sequential versus parallel
|
||||
computation of `CGAL::Classification::Local_eigen_analysis`
|
||||
objects. Possible values are `Parallel_tag` (default value is %CGAL
|
||||
is linked with TBB) or `Sequential_tag` (default value otherwise).
|
||||
\tparam DiagonalizeTraits model of `DiagonalizeTraits` used for
|
||||
matrix diagonalization. It can be omitted: if Eigen 3 (or greater)
|
||||
is available and `CGAL_EIGEN3_ENABLED` is defined then an overload
|
||||
using `Eigen_diagonalize_traits` is provided. Otherwise, the
|
||||
internal implementation `Diagonalize_traits` is used.
|
||||
|
||||
*/
|
||||
template <typename Geom_traits,
|
||||
template <typename GeomTraits,
|
||||
typename FaceListGraph,
|
||||
typename PointMap,
|
||||
#if defined(DOXYGEN_RUNNING)
|
||||
|
|
@ -75,7 +102,7 @@ class Mesh_feature_generator
|
|||
{
|
||||
|
||||
public:
|
||||
typedef typename Geom_traits::Iso_cuboid_3 Iso_cuboid_3;
|
||||
typedef typename GeomTraits::Iso_cuboid_3 Iso_cuboid_3;
|
||||
|
||||
/// \cond SKIP_IN_MANUAL
|
||||
typedef typename boost::graph_traits<FaceListGraph>::face_descriptor face_descriptor;
|
||||
|
|
@ -92,7 +119,7 @@ public:
|
|||
public:
|
||||
|
||||
typedef Classification::Planimetric_grid
|
||||
<Geom_traits, Face_range, PointMap> Planimetric_grid;
|
||||
<GeomTraits, Face_range, PointMap> Planimetric_grid;
|
||||
typedef Classification::Mesh_neighborhood
|
||||
<FaceListGraph> Neighborhood;
|
||||
typedef Classification::Local_eigen_analysis Local_eigen_analysis;
|
||||
|
|
@ -103,11 +130,11 @@ public:
|
|||
typedef Classification::Feature::Distance_to_plane
|
||||
<Face_range, PointMap> Distance_to_plane;
|
||||
typedef Classification::Feature::Elevation
|
||||
<Geom_traits, Face_range, PointMap> Elevation;
|
||||
<GeomTraits, Face_range, PointMap> Elevation;
|
||||
typedef Classification::Feature::Vertical_dispersion
|
||||
<Geom_traits, Face_range, PointMap> Dispersion;
|
||||
<GeomTraits, Face_range, PointMap> Dispersion;
|
||||
typedef Classification::Feature::Verticality
|
||||
<Geom_traits> Verticality;
|
||||
<GeomTraits> Verticality;
|
||||
typedef Classification::Feature::Eigenvalue Eigenvalue;
|
||||
|
||||
typedef typename Classification::RGB_Color RGB_Color;
|
||||
|
|
@ -193,21 +220,36 @@ private:
|
|||
const FaceListGraph& m_input;
|
||||
Face_range m_range;
|
||||
PointMap m_point_map;
|
||||
Feature_set& m_features;
|
||||
std::vector<std::pair<Feature_handle, std::size_t> > m_features_to_rename;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
/// \name Constructor
|
||||
/// @{
|
||||
|
||||
/*!
|
||||
\brief Generates all possible features from an input range.
|
||||
\brief Initializes a feature generator from an input range.
|
||||
|
||||
If not provided by the user, The size of the smallest scale is
|
||||
automatically estimated using a method equivalent to
|
||||
`CGAL::compute_average_spacing()` using 6 neighbors. The data
|
||||
structures needed (`Neighborhood`, `Planimetric_grid` and
|
||||
`Local_eigen_analysis`) are computed at `nb_scales` recursively
|
||||
larger scales.
|
||||
|
||||
\param input input mesh.
|
||||
\param point_map property map to access a representative point of
|
||||
each face.
|
||||
\param nb_scales number of scales to compute.
|
||||
\param voxel_size smallest scale used as a voxel size for the
|
||||
planimetric grid (if the default value -1 is used, its value is
|
||||
automatically estimated).
|
||||
*/
|
||||
Mesh_feature_generator(Feature_set& features,
|
||||
const FaceListGraph& input,
|
||||
Mesh_feature_generator(const FaceListGraph& input,
|
||||
PointMap point_map,
|
||||
std::size_t nb_scales,
|
||||
float voxel_size = -1.f)
|
||||
: m_input (input), m_range(faces(input)), m_point_map (point_map), m_features (features)
|
||||
: m_input (input), m_range(faces(input)), m_point_map (point_map)
|
||||
{
|
||||
|
||||
m_bbox = CGAL::bounding_box
|
||||
|
|
@ -219,7 +261,10 @@ public:
|
|||
m_scales.reserve (nb_scales);
|
||||
|
||||
m_scales.push_back (new Scale (m_input, m_range, m_point_map, m_bbox, voxel_size, 0));
|
||||
voxel_size = m_scales[0]->grid_resolution();
|
||||
|
||||
if (voxel_size == -1.f)
|
||||
voxel_size = m_scales[0]->grid_resolution();
|
||||
|
||||
for (std::size_t i = 1; i < nb_scales; ++ i)
|
||||
{
|
||||
voxel_size *= 2;
|
||||
|
|
@ -230,6 +275,7 @@ public:
|
|||
t.reset();
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// \cond SKIP_IN_MANUAL
|
||||
virtual ~Mesh_feature_generator()
|
||||
|
|
@ -247,21 +293,56 @@ public:
|
|||
/// \endcond
|
||||
|
||||
|
||||
void generate_point_based_features ()
|
||||
/// \name Feature Generation
|
||||
/// @{
|
||||
|
||||
|
||||
/*!
|
||||
\brief Generate geometric features based on face information.
|
||||
|
||||
At each scale, the following features are generated:
|
||||
|
||||
- `CGAL::Classification::Feature::Eigenvalue` with indices 0, 1 and 2
|
||||
- The version of `CGAL::Classification::Feature::Verticality` based on eigenvalues
|
||||
|
||||
\param features the feature set where the features are instantiated.
|
||||
*/
|
||||
void generate_face_based_features (Feature_set& features)
|
||||
{
|
||||
for (int j = 0; j < 3; ++ j)
|
||||
for (std::size_t i = 0; i < m_scales.size(); ++ i)
|
||||
m_features.add_with_scale_id<Eigenvalue> (i, m_range, eigen(i), std::size_t(j));
|
||||
features.add_with_scale_id<Eigenvalue> (i, m_range, eigen(i), std::size_t(j));
|
||||
for (std::size_t i = 0; i < m_scales.size(); ++ i)
|
||||
m_features.add_with_scale_id<Distance_to_plane> (i, m_range, m_point_map, eigen(i));
|
||||
for (std::size_t i = 0; i < m_scales.size(); ++ i)
|
||||
m_features.add_with_scale_id<Dispersion> (i, m_range, m_point_map, grid(i), radius_neighbors(i));
|
||||
for (std::size_t i = 0; i < m_scales.size(); ++ i)
|
||||
m_features.add_with_scale_id<Elevation> (i, m_range, m_point_map, grid(i), radius_dtm(i));
|
||||
for (std::size_t i = 0; i < m_scales.size(); ++ i)
|
||||
m_features.add_with_scale_id<Verticality> (i, m_range, eigen(i));
|
||||
features.add_with_scale_id<Verticality> (i, m_range, eigen(i));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Generate geometric features based on point position information.
|
||||
|
||||
At each scale, the following features are generated by considering
|
||||
the mesh as a point cloud through `PointMap`:
|
||||
|
||||
- `CGAL::Classification::Feature::Distance_to_plane`
|
||||
- `CGAL::Classification::Feature::Elevation`
|
||||
- `CGAL::Classification::Feature::Vertical_dispersion`
|
||||
|
||||
\param features the feature set where the features are instantiated.
|
||||
*/
|
||||
void generate_point_based_features (Feature_set& features)
|
||||
{
|
||||
for (std::size_t i = 0; i < m_scales.size(); ++ i)
|
||||
features.add_with_scale_id<Distance_to_plane> (i, m_range, m_point_map, eigen(i));
|
||||
for (std::size_t i = 0; i < m_scales.size(); ++ i)
|
||||
features.add_with_scale_id<Dispersion> (i, m_range, m_point_map, grid(i), radius_neighbors(i));
|
||||
for (std::size_t i = 0; i < m_scales.size(); ++ i)
|
||||
features.add_with_scale_id<Elevation> (i, m_range, m_point_map, grid(i), radius_dtm(i));
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// \name Data Structures Access
|
||||
/// @{
|
||||
|
||||
/*!
|
||||
\brief Returns the bounding box of the input point set.
|
||||
*/
|
||||
|
|
@ -278,6 +359,12 @@ public:
|
|||
\brief Returns the local eigen analysis structure at scale `scale`.
|
||||
*/
|
||||
const Local_eigen_analysis& eigen(std::size_t scale = 0) const { return *(m_scales[scale]->eigen); }
|
||||
|
||||
/// @}
|
||||
|
||||
/// \name Parameters
|
||||
/// @{
|
||||
|
||||
/*!
|
||||
\brief Returns the number of scales that were computed.
|
||||
*/
|
||||
|
|
@ -304,7 +391,7 @@ public:
|
|||
*/
|
||||
float radius_dtm(std::size_t scale = 0) const { return m_scales[scale]->radius_dtm(); }
|
||||
|
||||
|
||||
/// @}
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
|||
|
|
@ -29,20 +29,25 @@
|
|||
#include <CGAL/unordered.h>
|
||||
#include <CGAL/Handle_hash_function.h>
|
||||
|
||||
/// \cond SKIP_IN_MANUAL
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
namespace Classification {
|
||||
|
||||
/*!
|
||||
\ingroup PkgClassificationDataStructures
|
||||
\ingroup PkgClassificationMesh
|
||||
|
||||
\brief Class that generates models of `NeighborQuery` based on
|
||||
an input mesh.
|
||||
|
||||
\tparam FaceListGraph model of `FaceListGraph`.
|
||||
*/
|
||||
template <typename FaceListGraph>
|
||||
class Mesh_neighborhood
|
||||
{
|
||||
typedef typename boost::graph_traits<FaceListGraph>::face_descriptor face_descriptor;
|
||||
public:
|
||||
typedef typename boost::graph_traits<FaceListGraph>::face_descriptor face_descriptor; ///<
|
||||
|
||||
private:
|
||||
typedef typename boost::graph_traits<FaceListGraph>::halfedge_descriptor halfedge_descriptor;
|
||||
typedef typename boost::graph_traits<FaceListGraph>::vertex_descriptor vertex_descriptor;
|
||||
const FaceListGraph& m_mesh;
|
||||
|
|
@ -74,6 +79,11 @@ class Mesh_neighborhood
|
|||
|
||||
public:
|
||||
|
||||
/*!
|
||||
Functor that computes the 1-ring neighborhood of the face of an input mesh.
|
||||
|
||||
\cgalModels CGAL::Classification::NeighborQuery
|
||||
*/
|
||||
class One_ring_neighbor_query
|
||||
{
|
||||
public:
|
||||
|
|
@ -83,6 +93,10 @@ public:
|
|||
|
||||
public:
|
||||
|
||||
/*!
|
||||
\brief Constructs a 1-ring neighbor query object.
|
||||
\param neighborhood mesh neighborhood object.
|
||||
*/
|
||||
One_ring_neighbor_query (const Mesh_neighborhood& neighborhood)
|
||||
: neighborhood (neighborhood) { }
|
||||
|
||||
|
|
@ -96,6 +110,11 @@ public:
|
|||
/// \endcond
|
||||
};
|
||||
|
||||
/*!
|
||||
Functor that computes the N-ring neighborhood of the face of an input mesh.
|
||||
|
||||
\cgalModels CGAL::Classification::NeighborQuery
|
||||
*/
|
||||
class N_ring_neighbor_query
|
||||
{
|
||||
public:
|
||||
|
|
@ -106,6 +125,11 @@ public:
|
|||
|
||||
public:
|
||||
|
||||
/*!
|
||||
\brief Constructs a N-ring neighbor query object.
|
||||
\param neighborhood mesh neighborhood object.
|
||||
\param n size of neighborhood.
|
||||
*/
|
||||
N_ring_neighbor_query (const Mesh_neighborhood& neighborhood, const std::size_t n)
|
||||
: neighborhood (neighborhood), n(n) { }
|
||||
|
||||
|
|
@ -119,14 +143,24 @@ public:
|
|||
/// \endcond
|
||||
};
|
||||
|
||||
/// \cond SKIP_IN_MANUAL
|
||||
friend class One_ring_neighbor_query;
|
||||
friend class N_ring_neighbor_query;
|
||||
/// \endcond
|
||||
|
||||
/// \name Constructor
|
||||
/// @{
|
||||
|
||||
/*!
|
||||
\brief Constructs a neighborhood object based on the input mesh.
|
||||
|
||||
\param mesh input mesh.
|
||||
*/
|
||||
Mesh_neighborhood (const FaceListGraph& mesh) : m_mesh (mesh)
|
||||
{
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// \cond SKIP_IN_MANUAL
|
||||
~Mesh_neighborhood ()
|
||||
|
|
@ -134,16 +168,27 @@ public:
|
|||
}
|
||||
/// \endcond
|
||||
|
||||
/// \name Queries
|
||||
/// @{
|
||||
|
||||
/*!
|
||||
\brief Returns a 1-ring neighbor query object.
|
||||
*/
|
||||
One_ring_neighbor_query one_ring_neighbor_query () const
|
||||
{
|
||||
return One_ring_neighbor_query (*this);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Returns an N-ring neighbor query object.
|
||||
*/
|
||||
N_ring_neighbor_query n_ring_neighbor_query (const std::size_t n) const
|
||||
{
|
||||
return N_ring_neighbor_query (*this, n);
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
|
@ -184,6 +229,5 @@ private:
|
|||
|
||||
}
|
||||
|
||||
/// \endcond
|
||||
|
||||
#endif // CGAL_CLASSIFICATION_MESH_NEIGHBORHOOD_H
|
||||
|
|
|
|||
|
|
@ -227,13 +227,13 @@ public:
|
|||
|
||||
/// \cond SKIP_IN_MANUAL
|
||||
Planimetric_grid (Planimetric_grid* lower_scale)
|
||||
: m_resolution (lower_scale->resolution() * 2), m_lower_scale (lower_scale)
|
||||
: m_resolution (lower_scale->resolution() * 2), m_lower_scale (lower_scale)
|
||||
{
|
||||
m_current_scale = lower_scale->m_current_scale + 1;
|
||||
|
||||
m_width = (m_lower_scale->width() + 1) / 2;
|
||||
m_height = (m_lower_scale->height() + 1) / 2;
|
||||
|
||||
|
||||
m_has_points.reserve(m_width * m_height);
|
||||
for (std::size_t x = 0; x < m_width; ++ x)
|
||||
for (std::size_t y = 0; y < m_height; ++ y)
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ namespace CGAL {
|
|||
namespace Classification {
|
||||
|
||||
/*!
|
||||
\ingroup PkgClassificationDataStructures
|
||||
\ingroup PkgClassificationPointSet
|
||||
|
||||
\brief Generates a set of generic features for point set
|
||||
classification.
|
||||
|
|
@ -79,7 +79,8 @@ namespace Classification {
|
|||
type is the value type of the iterator of `PointRange` and value type
|
||||
is `GeomTraits::Point_3`.
|
||||
\tparam ConcurrencyTag enables sequential versus parallel
|
||||
algorithm. Possible values are `Parallel_tag` (default value is %CGAL
|
||||
computation of `CGAL::Classification::Local_eigen_analysis`
|
||||
objects. Possible values are `Parallel_tag` (default value is %CGAL
|
||||
is linked with TBB) or `Sequential_tag` (default value otherwise).
|
||||
\tparam DiagonalizeTraits model of `DiagonalizeTraits` used for
|
||||
matrix diagonalization. It can be omitted: if Eigen 3 (or greater)
|
||||
|
|
@ -225,84 +226,34 @@ private:
|
|||
|
||||
const PointRange& m_input;
|
||||
PointMap m_point_map;
|
||||
Feature_set& m_features;
|
||||
|
||||
public:
|
||||
|
||||
/// \name Constructor
|
||||
/// @{
|
||||
|
||||
/*!
|
||||
\brief Generates all possible features from an input range.
|
||||
\brief Initializes a feature generator from an input range.
|
||||
|
||||
The size of the smallest scale is automatically estimated using a
|
||||
method equivalent to `CGAL::compute_average_spacing()` using 6
|
||||
neighbors. The data structures needed (`Neighborhood`,
|
||||
`Planimetric_grid` and `Local_eigen_analysis`) are computed at
|
||||
`nb_scales` recursively larger scales. At each scale, the
|
||||
following features are generated:
|
||||
If not provided by the user, The size of the smallest scale is
|
||||
automatically estimated using a method equivalent to
|
||||
`CGAL::compute_average_spacing()` using 6 neighbors. The data
|
||||
structures needed (`Neighborhood`, `Planimetric_grid` and
|
||||
`Local_eigen_analysis`) are computed at `nb_scales` recursively
|
||||
larger scales.
|
||||
|
||||
- `CGAL::Classification::Feature::Anisotropy`
|
||||
- `CGAL::Classification::Feature::Distance_to_plane`
|
||||
- `CGAL::Classification::Feature::Eigentropy`
|
||||
- `CGAL::Classification::Feature::Elevation`
|
||||
- `CGAL::Classification::Feature::Linearity`
|
||||
- `CGAL::Classification::Feature::Omnivariance`
|
||||
- `CGAL::Classification::Feature::Planarity`
|
||||
- `CGAL::Classification::Feature::Sphericity`
|
||||
- `CGAL::Classification::Feature::Sum_eigenvalues`
|
||||
- `CGAL::Classification::Feature::Surface_variation`
|
||||
- `CGAL::Classification::Feature::Vertical_dispersion`
|
||||
- The version of `CGAL::Classification::Feature::Verticality` based on eigenvalues
|
||||
|
||||
If normal vectors are provided (if `VectorMap` is different from
|
||||
`CGAL::Default`), the following feature is generated at each
|
||||
scale:
|
||||
|
||||
- The version of `CGAL::Classification::Feature::Verticality` based on normal vectors
|
||||
|
||||
If colors are provided (if `ColorMap` is different from
|
||||
`CGAL::Default`), the following features are generated at each
|
||||
scale:
|
||||
|
||||
- 9 features `CGAL::Classification::Feature::Hsv` on
|
||||
channel 0 (hue) with mean ranging from 0° to 360° and standard
|
||||
deviation of 22.5.
|
||||
|
||||
- 5 features `CGAL::Classification::Feature::Hsv` on
|
||||
channel 1 (saturation) with mean ranging from 0 to 100 and standard
|
||||
deviation of 12.5.
|
||||
|
||||
- 5 features `CGAL::Classification::Feature::Hsv` on channel 2
|
||||
(value) with mean ranging from 0 to 100 and standard deviation
|
||||
of 12.5.
|
||||
|
||||
If echo numbers are provided (if `EchoMap` is different from
|
||||
`CGAL::Default`), the following feature is computed at each
|
||||
scale:
|
||||
|
||||
- `CGAL::Classification::Feature::Echo_scatter`
|
||||
|
||||
\tparam VectorMap model of `ReadablePropertyMap` whose key type is
|
||||
the value type of the iterator of `PointRange` and value type is
|
||||
`GeomTraits::Vector_3`.
|
||||
\tparam ColorMap model of `ReadablePropertyMap` whose key type is
|
||||
the value type of the iterator of `PointRange` and value type is
|
||||
`CGAL::Classification::RGB_Color`.
|
||||
\tparam EchoMap model of `ReadablePropertyMap` whose key type is
|
||||
the value type of the iterator of `PointRange` and value type is
|
||||
`std::size_t`.
|
||||
\param features the feature set where the features are instantiated.
|
||||
\param input point range.
|
||||
\param point_map property map to access the input points.
|
||||
\param nb_scales number of scales to compute.
|
||||
\param normal_map property map to access the normal vectors of the input points (if any).
|
||||
\param color_map property map to access the colors of the input points (if any).
|
||||
\param echo_map property map to access the echo values of the input points (if any).
|
||||
\param voxel_size smallest scale used as a voxel size for the
|
||||
planimetric grid (if the default value -1 is used, its value is
|
||||
automatically estimated).
|
||||
*/
|
||||
Point_set_feature_generator(Feature_set& features,
|
||||
const PointRange& input,
|
||||
Point_set_feature_generator(const PointRange& input,
|
||||
PointMap point_map,
|
||||
std::size_t nb_scales,
|
||||
float voxel_size = -1.f)
|
||||
: m_input (input), m_point_map (point_map), m_features (features)
|
||||
: m_input (input), m_point_map (point_map)
|
||||
{
|
||||
m_bbox = CGAL::bounding_box
|
||||
(boost::make_transform_iterator (m_input.begin(), CGAL::Property_map_to_unary_function<PointMap>(m_point_map)),
|
||||
|
|
@ -327,6 +278,7 @@ public:
|
|||
t.reset();
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// \cond SKIP_IN_MANUAL
|
||||
virtual ~Point_set_feature_generator()
|
||||
|
|
@ -343,44 +295,103 @@ public:
|
|||
}
|
||||
/// \endcond
|
||||
|
||||
/// \name Feature Generation
|
||||
/// @{
|
||||
|
||||
void generate_point_based_features ()
|
||||
|
||||
/*!
|
||||
\brief Generate geometric features based on point position information.
|
||||
|
||||
At each scale, the following features are generated:
|
||||
|
||||
- `CGAL::Classification::Feature::Eigenvalue` with indices 0, 1 and 2
|
||||
- `CGAL::Classification::Feature::Distance_to_plane`
|
||||
- `CGAL::Classification::Feature::Elevation`
|
||||
- `CGAL::Classification::Feature::Vertical_dispersion`
|
||||
- The version of `CGAL::Classification::Feature::Verticality` based on eigenvalues
|
||||
|
||||
\param features the feature set where the features are instantiated.
|
||||
*/
|
||||
void generate_point_based_features (Feature_set& features)
|
||||
{
|
||||
for (int j = 0; j < 3; ++ j)
|
||||
for (std::size_t i = 0; i < m_scales.size(); ++ i)
|
||||
m_features.add_with_scale_id<Eigenvalue> (i, m_input, eigen(i), std::size_t(j));
|
||||
features.add_with_scale_id<Eigenvalue> (i, m_input, eigen(i), std::size_t(j));
|
||||
for (std::size_t i = 0; i < m_scales.size(); ++ i)
|
||||
m_features.add_with_scale_id<Distance_to_plane> (i, m_input, m_point_map, eigen(i));
|
||||
features.add_with_scale_id<Distance_to_plane> (i, m_input, m_point_map, eigen(i));
|
||||
for (std::size_t i = 0; i < m_scales.size(); ++ i)
|
||||
m_features.add_with_scale_id<Dispersion> (i, m_input, m_point_map, grid(i), radius_neighbors(i));
|
||||
features.add_with_scale_id<Dispersion> (i, m_input, m_point_map, grid(i), radius_neighbors(i));
|
||||
for (std::size_t i = 0; i < m_scales.size(); ++ i)
|
||||
m_features.add_with_scale_id<Elevation> (i, m_input, m_point_map, grid(i), radius_dtm(i));
|
||||
features.add_with_scale_id<Elevation> (i, m_input, m_point_map, grid(i), radius_dtm(i));
|
||||
for (std::size_t i = 0; i < m_scales.size(); ++ i)
|
||||
m_features.add_with_scale_id<Verticality> (i, m_input, eigen(i));
|
||||
features.add_with_scale_id<Verticality> (i, m_input, eigen(i));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Generate geometric features based on normal vector information.
|
||||
|
||||
Generates the version of `CGAL::Classification::Feature::Verticality` based on normal vectors.
|
||||
|
||||
\tparam VectorMap model of `ReadablePropertyMap` whose key type is
|
||||
the value type of the iterator of `PointRange` and value type is
|
||||
`GeomTraits::Vector_3`.
|
||||
|
||||
\param features the feature set where the features are instantiated.
|
||||
\param normal_map property map to access the normal vectors of the input points (if any).
|
||||
|
||||
*/
|
||||
template <typename VectorMap>
|
||||
void generate_normal_based_features(const VectorMap& normal_map)
|
||||
void generate_normal_based_features(Feature_set& features, const VectorMap& normal_map)
|
||||
{
|
||||
m_features.add<Verticality> (m_input, normal_map);
|
||||
features.add<Verticality> (m_input, normal_map);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Generate geometric features based on point color information.
|
||||
|
||||
Generates `CGAL::Classification::Feature::Color_channel` with
|
||||
channels `HUE`, `SATURATION` and `VALUE`.
|
||||
|
||||
\tparam ColorMap model of `ReadablePropertyMap` whose key type is
|
||||
the value type of the iterator of `PointRange` and value type is
|
||||
`CGAL::Classification::RGB_Color`.
|
||||
|
||||
\param features the feature set where the features are instantiated.
|
||||
\param color_map property map to access the colors of the input points (if any).
|
||||
*/
|
||||
template <typename ColorMap>
|
||||
void generate_color_based_features(const ColorMap& color_map)
|
||||
void generate_color_based_features(Feature_set& features, const ColorMap& color_map)
|
||||
{
|
||||
typedef Feature::Color_channel<GeomTraits, PointRange, ColorMap> Color_channel;
|
||||
for (std::size_t i = 0; i < 3; ++ i)
|
||||
m_features.add<Color_channel> (m_input, color_map, typename Color_channel::Channel(i));
|
||||
features.add<Color_channel> (m_input, color_map, typename Color_channel::Channel(i));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Generate geometric features based on echo information.
|
||||
|
||||
At each scale, generates `CGAL::Classification::Feature::Echo_scatter`.
|
||||
|
||||
\tparam EchoMap model of `ReadablePropertyMap` whose key type is
|
||||
the value type of the iterator of `PointRange` and value type is
|
||||
`std::size_t`.
|
||||
|
||||
\param features the feature set where the features are instantiated.
|
||||
\param echo_map property map to access the echo values of the input points (if any).
|
||||
*/
|
||||
template <typename EchoMap>
|
||||
void generate_echo_based_features(const EchoMap& echo_map)
|
||||
void generate_echo_based_features(Feature_set& features, const EchoMap& echo_map)
|
||||
{
|
||||
typedef Feature::Echo_scatter<GeomTraits, PointRange, PointMap, EchoMap> Echo_scatter;
|
||||
for (std::size_t i = 0; i < m_scales.size(); ++ i)
|
||||
m_features.add_with_scale_id<Echo_scatter> (i, m_input, echo_map, grid(i), radius_neighbors(i));
|
||||
features.add_with_scale_id<Echo_scatter> (i, m_input, echo_map, grid(i), radius_neighbors(i));
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// \name Data Structures Access
|
||||
/// @{
|
||||
|
||||
/*!
|
||||
\brief Returns the bounding box of the input point set.
|
||||
*/
|
||||
|
|
@ -397,6 +408,12 @@ public:
|
|||
\brief Returns the local eigen analysis structure at scale `scale`.
|
||||
*/
|
||||
const Local_eigen_analysis& eigen(std::size_t scale = 0) const { return *(m_scales[scale]->eigen); }
|
||||
|
||||
/// @}
|
||||
|
||||
/// \name Parameters
|
||||
/// @{
|
||||
|
||||
/*!
|
||||
\brief Returns the number of scales that were computed.
|
||||
*/
|
||||
|
|
@ -423,6 +440,7 @@ public:
|
|||
*/
|
||||
float radius_dtm(std::size_t scale = 0) const { return m_scales[scale]->radius_dtm(); }
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
private:
|
||||
|
|
@ -434,10 +452,10 @@ private:
|
|||
m_scales.clear();
|
||||
}
|
||||
|
||||
void generate_gradient_features()
|
||||
{
|
||||
#ifdef CGAL_CLASSIFICATION_USE_GRADIENT_OF_FEATURE
|
||||
std::size_t size = m_features->size();
|
||||
void generate_gradient_features(Feature_set& features)
|
||||
{
|
||||
std::size_t size = features->size();
|
||||
|
||||
for (std::size_t i = 0; i < size; ++ i)
|
||||
{
|
||||
|
|
@ -445,16 +463,16 @@ private:
|
|||
{
|
||||
std::ostringstream oss;
|
||||
oss << "_" << j;
|
||||
if ((*m_features)[i]->name().find (oss.str()))
|
||||
if ((*features)[i]->name().find (oss.str()))
|
||||
{
|
||||
const Neighbor_query& neighbor_query = neighborhood(std::size_t(j)).k_neighbor_query(6);
|
||||
m_features->template add<Gradient_of_feature> (m_input, m_point_map, (*m_features)[i], neighbor_query);
|
||||
features->template add<Gradient_of_feature> (m_input, m_point_map, (*features)[i], neighbor_query);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
const T& get_parameter (const T& t)
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ namespace CGAL {
|
|||
namespace Classification {
|
||||
|
||||
/*!
|
||||
\ingroup PkgClassificationDataStructures
|
||||
\ingroup PkgClassificationPointSet
|
||||
|
||||
\brief Class that precomputes spatial searching structures for an
|
||||
input point set and gives access to the local neighborhood of a
|
||||
|
|
@ -165,13 +165,16 @@ public:
|
|||
/// \endcond
|
||||
};
|
||||
|
||||
/// \cond SKIP_IN_MANUAL
|
||||
friend class K_neighbor_query;
|
||||
friend class Sphere_neighbor_query;
|
||||
|
||||
/// \cond SKIP_IN_MANUAL
|
||||
Point_set_neighborhood () : m_tree (NULL) { }
|
||||
/// \endcond
|
||||
|
||||
/// \name Constructors
|
||||
/// @{
|
||||
|
||||
/*!
|
||||
\brief Constructs a neighborhood object based on the input range.
|
||||
|
||||
|
|
@ -220,6 +223,8 @@ public:
|
|||
m_tree->build();
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// \cond SKIP_IN_MANUAL
|
||||
~Point_set_neighborhood ()
|
||||
{
|
||||
|
|
@ -228,6 +233,9 @@ public:
|
|||
}
|
||||
/// \endcond
|
||||
|
||||
/// \name Queries
|
||||
/// @{
|
||||
|
||||
/*!
|
||||
\brief Returns a neighbor query object with fixed number of neighbors `k`.
|
||||
*/
|
||||
|
|
@ -244,6 +252,8 @@ public:
|
|||
return Sphere_neighbor_query (*this, radius);
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
private:
|
||||
|
||||
template <typename OutputIterator>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,162 @@
|
|||
// Copyright (c) 2018 GeometryFactory Sarl (France).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org).
|
||||
// You can redistribute it and/or modify it under the terms of the GNU
|
||||
// General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
//
|
||||
// Author(s) : Simon Giraudot
|
||||
|
||||
#ifndef CGAL_CLASSIFICATION_PROPERTY_MAPS_H
|
||||
#define CGAL_CLASSIFICATION_PROPERTY_MAPS_H
|
||||
|
||||
#include <CGAL/license/Classification.h>
|
||||
|
||||
namespace CGAL
|
||||
{
|
||||
|
||||
namespace Classification
|
||||
{
|
||||
|
||||
/*!
|
||||
\ingroup PkgClassificationMesh
|
||||
|
||||
\brief Property map that constructs the center of mass of the face
|
||||
of a mesh on-the-fly.
|
||||
|
||||
\cgalModels `ReadablePropertyMap`
|
||||
|
||||
\tparam FaceGraph model of `FaceGraph`.
|
||||
|
||||
\tparam VertexPointMap model of `ReadablePropertyMap` with with
|
||||
`boost::graph_traits<FaceGraph>::%vertex_descriptor` as key type
|
||||
and `CGAL::Point_3` as value type.
|
||||
*/
|
||||
template <typename FaceGraph,
|
||||
typename VertexPointMap = typename boost::property_map<FaceGraph,vertex_point_t>::type >
|
||||
class Face_descriptor_to_center_of_mass_map
|
||||
{
|
||||
public:
|
||||
typedef typename boost::property_traits<VertexPointMap>::value_type Point_3;
|
||||
typedef typename boost::graph_traits<FaceGraph>::face_descriptor key_type;
|
||||
typedef Point_3 value_type;
|
||||
typedef Point_3 reference;
|
||||
typedef boost::readable_property_map_tag category;
|
||||
|
||||
private:
|
||||
typedef typename boost::graph_traits<FaceGraph>::vertex_descriptor vertex_descriptor;
|
||||
|
||||
const FaceGraph* m_mesh;
|
||||
VertexPointMap m_vpm;
|
||||
|
||||
public:
|
||||
|
||||
Face_descriptor_to_center_of_mass_map ()
|
||||
: m_mesh (NULL) { }
|
||||
Face_descriptor_to_center_of_mass_map (const FaceGraph* mesh)
|
||||
: m_mesh (mesh), m_vpm (get (vertex_point, *m_mesh)) { }
|
||||
Face_descriptor_to_center_of_mass_map (const FaceGraph* mesh, VertexPointMap vpm)
|
||||
: m_mesh (mesh), m_vpm (vpm) { }
|
||||
|
||||
/// \cond SKIP_IN_MANUAL
|
||||
inline friend reference get (const Face_descriptor_to_center_of_mass_map& map, key_type f)
|
||||
{
|
||||
std::vector<Point_3> points;
|
||||
|
||||
BOOST_FOREACH(vertex_descriptor v, vertices_around_face(halfedge(f, *(map.m_mesh)), *(map.m_mesh)))
|
||||
points.push_back (get (map.m_vpm, v));
|
||||
|
||||
return CGAL::centroid (points.begin(), points.end());
|
||||
}
|
||||
/// \endcond
|
||||
};
|
||||
|
||||
/*!
|
||||
\ingroup PkgClassificationMesh
|
||||
|
||||
\brief Property map that constructs a face descriptor with a
|
||||
`bbox()` method from a face descriptor.
|
||||
|
||||
\cgalModels `ReadablePropertyMap`
|
||||
|
||||
\tparam FaceGraph model of `FaceGraph`.
|
||||
|
||||
\tparam VertexPointMap model of `ReadablePropertyMap` with with
|
||||
`boost::graph_traits<FaceGraph>::%vertex_descriptor` as key type
|
||||
and `CGAL::Point_3` as value type.
|
||||
*/
|
||||
template <typename FaceGraph,
|
||||
typename VertexPointMap = typename boost::property_map<FaceGraph,vertex_point_t>::type >
|
||||
class Face_descriptor_to_face_descriptor_with_bbox_map
|
||||
{
|
||||
public:
|
||||
typedef typename boost::graph_traits<FaceGraph>::face_descriptor face_descriptor;
|
||||
|
||||
/*!
|
||||
\brief Face descriptor with a precomputed bounding box.
|
||||
*/
|
||||
class face_descriptor_with_bbox
|
||||
{
|
||||
face_descriptor m_descriptor;
|
||||
CGAL::Bbox_3 m_bbox;
|
||||
|
||||
public:
|
||||
face_descriptor_with_bbox (const face_descriptor& descriptor,
|
||||
const CGAL::Bbox_3& bbox)
|
||||
: m_descriptor (descriptor), m_bbox (bbox)
|
||||
{ }
|
||||
|
||||
const CGAL::Bbox_3 bbox() const { return m_bbox; }
|
||||
operator face_descriptor() const { return m_descriptor; }
|
||||
};
|
||||
|
||||
typedef face_descriptor key_type;
|
||||
typedef face_descriptor_with_bbox value_type;
|
||||
typedef face_descriptor_with_bbox reference;
|
||||
typedef boost::readable_property_map_tag category;
|
||||
|
||||
private:
|
||||
typedef typename boost::graph_traits<FaceGraph>::vertex_descriptor vertex_descriptor;
|
||||
|
||||
const FaceGraph* m_mesh;
|
||||
VertexPointMap m_vpm;
|
||||
|
||||
public:
|
||||
|
||||
Face_descriptor_to_face_descriptor_with_bbox_map ()
|
||||
: m_mesh (NULL) { }
|
||||
Face_descriptor_to_face_descriptor_with_bbox_map (const FaceGraph* mesh)
|
||||
: m_mesh (mesh), m_vpm (get (vertex_point, *m_mesh)) { }
|
||||
Face_descriptor_to_face_descriptor_with_bbox_map (const FaceGraph* mesh, VertexPointMap vpm)
|
||||
: m_mesh (mesh), m_vpm (vpm) { }
|
||||
|
||||
/// \cond SKIP_IN_MANUAL
|
||||
inline friend reference get (const Face_descriptor_to_face_descriptor_with_bbox_map& map, key_type f)
|
||||
{
|
||||
CGAL::Bbox_3 bbox;
|
||||
|
||||
BOOST_FOREACH(vertex_descriptor v, vertices_around_face(halfedge(f, *(map.m_mesh)), *(map.m_mesh)))
|
||||
bbox = bbox + get(map.m_vpm, v).bbox();
|
||||
|
||||
return value_type (f, bbox);
|
||||
}
|
||||
/// \endcond
|
||||
};
|
||||
|
||||
|
||||
} // namespace Classification
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_CLASSIFICATION_PROPERTY_MAPS_H
|
||||
Loading…
Reference in New Issue