mirror of https://github.com/CGAL/cgal
adding np to sphere classes
This commit is contained in:
parent
0fbc3ea1bb
commit
2c16e6f9bf
|
|
@ -42,22 +42,24 @@ int main (int argc, char** argv)
|
||||||
|
|
||||||
// Default parameters for data/spheres.ply
|
// Default parameters for data/spheres.ply
|
||||||
const std::size_t k = 12;
|
const std::size_t k = 12;
|
||||||
const double tolerance = 0.01;
|
const double max_distance = 0.01;
|
||||||
const double max_angle = 10.;
|
const double max_angle = 10.;
|
||||||
const std::size_t min_region_size = 50;
|
const std::size_t min_region_size = 50;
|
||||||
|
|
||||||
// No constraint on radius
|
|
||||||
const double min_radius = 0.;
|
|
||||||
const double max_radius = std::numeric_limits<double>::infinity();
|
|
||||||
|
|
||||||
Neighbor_query neighbor_query(
|
Neighbor_query neighbor_query(
|
||||||
points, CGAL::parameters::
|
points, CGAL::parameters::
|
||||||
k_neighbors(k).
|
k_neighbors(k).
|
||||||
point_map(points.point_map()));
|
point_map(points.point_map()));
|
||||||
Region_type region_type(points, tolerance, max_angle, min_region_size,
|
Region_type region_type(
|
||||||
min_radius, max_radius,
|
points, CGAL::parameters::
|
||||||
points.point_map(), points.normal_map());
|
maximum_distance(max_distance).
|
||||||
Region_growing region_growing(points, neighbor_query, region_type);
|
maximum_angle(max_angle).
|
||||||
|
minimum_region_size(min_region_size).
|
||||||
|
point_map(points.point_map()).
|
||||||
|
normal_map(points.normal_map()));
|
||||||
|
|
||||||
|
Region_growing region_growing(
|
||||||
|
points, neighbor_query, region_type);
|
||||||
|
|
||||||
// Add maps to get colored output
|
// Add maps to get colored output
|
||||||
Point_set::Property_map<unsigned char>
|
Point_set::Property_map<unsigned char>
|
||||||
|
|
|
||||||
|
|
@ -83,9 +83,6 @@ namespace Point_set {
|
||||||
using Sqrt = typename Get_sqrt::Sqrt;
|
using Sqrt = typename Get_sqrt::Sqrt;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// @}
|
|
||||||
|
|
||||||
/// \name Initialization
|
/// \name Initialization
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
|
|
@ -202,7 +199,8 @@ namespace Point_set {
|
||||||
CGAL_precondition(m_min_radius >= FT(0));
|
CGAL_precondition(m_min_radius >= FT(0));
|
||||||
|
|
||||||
const FT m_max_radius = parameters::choose_parameter(
|
const FT m_max_radius = parameters::choose_parameter(
|
||||||
parameters::get_parameter(np, internal_np::maximum_radius), FT(std::numeric_limits<double>::max()));
|
parameters::get_parameter(np, internal_np::maximum_radius),
|
||||||
|
FT(std::numeric_limits<double>::max()));
|
||||||
CGAL_precondition(m_max_radius >= m_min_radius);
|
CGAL_precondition(m_max_radius >= m_min_radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -288,7 +286,8 @@ namespace Point_set {
|
||||||
\param query_index
|
\param query_index
|
||||||
index of the query point
|
index of the query point
|
||||||
|
|
||||||
\param indices indices of the inliers of the region
|
\param indices
|
||||||
|
indices of the inliers of the region
|
||||||
|
|
||||||
The first parameter is not used in this implementation.
|
The first parameter is not used in this implementation.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,7 @@
|
||||||
|
|
||||||
#include <CGAL/license/Shape_detection.h>
|
#include <CGAL/license/Shape_detection.h>
|
||||||
|
|
||||||
#include <cmath>
|
// Internal includes.
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <CGAL/assertions.h>
|
|
||||||
#include <CGAL/number_utils.h>
|
|
||||||
#include <CGAL/Cartesian_converter.h>
|
|
||||||
|
|
||||||
#include <CGAL/Shape_detection/Region_growing/internal/utils.h>
|
#include <CGAL/Shape_detection/Region_growing/internal/utils.h>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
@ -41,30 +35,29 @@ namespace Point_set {
|
||||||
rejected.
|
rejected.
|
||||||
|
|
||||||
\tparam GeomTraits
|
\tparam GeomTraits
|
||||||
must be a model of `Kernel`.
|
a model of `Kernel`
|
||||||
|
|
||||||
\tparam InputRange
|
\tparam InputRange
|
||||||
must be a model of `ConstRange` whose iterator type is `RandomAccessIterator`.
|
a model of `ConstRange` whose iterator type is `RandomAccessIterator`
|
||||||
|
|
||||||
\tparam PointMap
|
\tparam PointMap
|
||||||
must be an `LvaluePropertyMap` whose key type is the value type of the input
|
a model of `ReadablePropertyMap` whose key type is the value type of the input
|
||||||
range and value type is `Kernel::Point_3`.
|
range and value type is `Kernel::Point_3`
|
||||||
|
|
||||||
\tparam NormalMap
|
\tparam NormalMap
|
||||||
must be an `LvaluePropertyMap` whose key type is the value type of the input
|
a model of `ReadablePropertyMap` whose key type is the value type of the input
|
||||||
range and value type is `Kernel::Vector_3`.
|
range and value type is `Kernel::Vector_3`
|
||||||
|
|
||||||
\cgalModels `RegionType`
|
\cgalModels `RegionType`
|
||||||
*/
|
*/
|
||||||
template<typename GeomTraits,
|
template<
|
||||||
|
typename GeomTraits,
|
||||||
typename InputRange,
|
typename InputRange,
|
||||||
typename PointMap,
|
typename PointMap,
|
||||||
typename NormalMap>
|
typename NormalMap>
|
||||||
class Least_squares_sphere_fit_region
|
class Least_squares_sphere_fit_region {
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// \name Types
|
/// \name Types
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
|
|
@ -78,7 +71,9 @@ public:
|
||||||
/// Number type.
|
/// Number type.
|
||||||
typedef typename GeomTraits::FT FT;
|
typedef typename GeomTraits::FT FT;
|
||||||
|
|
||||||
/// \cond SKIP_IN_MANUAL
|
/// @}
|
||||||
|
|
||||||
|
private:
|
||||||
using Point_3 = typename Traits::Point_3;
|
using Point_3 = typename Traits::Point_3;
|
||||||
using Vector_3 = typename Traits::Vector_3;
|
using Vector_3 = typename Traits::Vector_3;
|
||||||
using Plane_3 = typename Traits::Plane_3;
|
using Plane_3 = typename Traits::Plane_3;
|
||||||
|
|
@ -90,104 +85,195 @@ public:
|
||||||
using Get_sqrt = internal::Get_sqrt<Traits>;
|
using Get_sqrt = internal::Get_sqrt<Traits>;
|
||||||
using Sqrt = typename Get_sqrt::Sqrt;
|
using Sqrt = typename Get_sqrt::Sqrt;
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
const Input_range& m_input_range;
|
|
||||||
|
|
||||||
const FT m_distance_threshold;
|
|
||||||
const FT m_normal_threshold;
|
|
||||||
const std::size_t m_min_region_size;
|
|
||||||
const FT m_min_radius;
|
|
||||||
const FT m_max_radius;
|
|
||||||
|
|
||||||
const Point_map m_point_map;
|
|
||||||
const Normal_map m_normal_map;
|
|
||||||
|
|
||||||
const Squared_length_3 m_squared_length_3;
|
|
||||||
const Squared_distance_3 m_squared_distance_3;
|
|
||||||
const Scalar_product_3 m_scalar_product_3;
|
|
||||||
const Sqrt m_sqrt;
|
|
||||||
|
|
||||||
Point_3 m_center;
|
|
||||||
FT m_radius;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// \endcond
|
|
||||||
|
|
||||||
/// @}
|
|
||||||
|
|
||||||
/// \name Initialization
|
/// \name Initialization
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief initializes all internal data structures.
|
\brief initializes all internal data structures.
|
||||||
|
|
||||||
\param input_range an instance of `InputRange` with 3D points and
|
\tparam NamedParameters
|
||||||
|
a sequence of \ref bgl_namedparameters "Named Parameters"
|
||||||
|
|
||||||
|
\param input_range
|
||||||
|
an instance of `InputRange` with 3D points and
|
||||||
corresponding 3D normal vectors
|
corresponding 3D normal vectors
|
||||||
|
|
||||||
\param distance_threshold the maximum distance from a point to a
|
\param np
|
||||||
sphere. %Default is 1.
|
a sequence of \ref bgl_namedparameters "Named Parameters"
|
||||||
|
among the ones listed below
|
||||||
|
|
||||||
\param angle_threshold the maximum accepted angle in degrees
|
\cgalNamedParamsBegin
|
||||||
between the normal of a point and the radius of a sphere. %Default
|
\cgalParamNBegin{maximum_distance}
|
||||||
is 25 degrees.
|
\cgalParamDescription{the maximum distance from a point to a sphere}
|
||||||
|
\cgalParamType{`GeomTraits::FT`}
|
||||||
|
\cgalParamDefault{1}
|
||||||
|
\cgalParamNEnd
|
||||||
|
\cgalParamNBegin{maximum_angle}
|
||||||
|
\cgalParamDescription{the maximum angle in degrees between
|
||||||
|
the normal of a point and the radius of a sphere}
|
||||||
|
\cgalParamType{`GeomTraits::FT`}
|
||||||
|
\cgalParamDefault{25 degrees}
|
||||||
|
\cgalParamNEnd
|
||||||
|
\cgalParamNBegin{cosine_value}
|
||||||
|
\cgalParamDescription{the cos value computed as `cos(maximum_angle * PI / 180)`,
|
||||||
|
this parameter can be used instead of the `maximum_angle`}
|
||||||
|
\cgalParamType{`GeomTraits::FT`}
|
||||||
|
\cgalParamDefault{`cos(25 * PI / 180)`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
\cgalParamNBegin{minimum_region_size}
|
||||||
|
\cgalParamDescription{the minimum number of 3D points a region must have}
|
||||||
|
\cgalParamType{`std::size_t`}
|
||||||
|
\cgalParamDefault{3}
|
||||||
|
\cgalParamNEnd
|
||||||
|
\cgalParamNBegin{minimum_radius}
|
||||||
|
\cgalParamDescription{the radius below which an estimated sphere
|
||||||
|
is considered as invalid and discarded}
|
||||||
|
\cgalParamType{`GeomTraits::FT`}
|
||||||
|
\cgalParamDefault{0, no limit}
|
||||||
|
\cgalParamNEnd
|
||||||
|
\cgalParamNBegin{maximum_radius}
|
||||||
|
\cgalParamDescription{the radius above which an estimated sphere
|
||||||
|
is considered as invalid and discarded.}
|
||||||
|
\cgalParamType{`GeomTraits::FT`}
|
||||||
|
\cgalParamDefault{+infinity, no limit}
|
||||||
|
\cgalParamNEnd
|
||||||
|
\cgalParamNBegin{point_map}
|
||||||
|
\cgalParamDescription{an instance of `PointMap` that maps an item from `input_range`
|
||||||
|
to `Kernel::Point_3`}
|
||||||
|
\cgalParamDefault{`PointMap()`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
\cgalParamNBegin{normal_map}
|
||||||
|
\cgalParamDescription{ an instance of `NormalMap` that maps an item from `input_range`
|
||||||
|
to `Kernel::Vector_3`}
|
||||||
|
\cgalParamDefault{`NormalMap()`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
\cgalParamNBegin{geom_traits}
|
||||||
|
\cgalParamDescription{an instance of `GeomTraits`}
|
||||||
|
\cgalParamDefault{`GeomTraits()`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
\cgalNamedParamsEnd
|
||||||
|
|
||||||
\param min_region_size the minimum number of 3D points a region
|
\pre `input_range.size() > 0`
|
||||||
must have. %Default is 3.
|
\pre `maximum_distance >= 0`
|
||||||
|
\pre `maximum_angle >= 0 && maximum_angle <= 90`
|
||||||
|
\pre `cosine_value >= 0 && cosine_value <= 1`
|
||||||
|
\pre `minimum_region_size > 0`
|
||||||
|
\pre `minimum_radius >= 0`
|
||||||
|
\pre `maximum_radius >= minimum_radius`
|
||||||
|
*/
|
||||||
|
template<typename NamedParameters>
|
||||||
|
Least_squares_sphere_fit_region(
|
||||||
|
const InputRange& input_range,
|
||||||
|
const NamedParameters& np) :
|
||||||
|
m_input_range(input_range),
|
||||||
|
m_point_map(parameters::choose_parameter(parameters::get_parameter(
|
||||||
|
np, internal_np::point_map), PointMap())),
|
||||||
|
m_normal_map(parameters::choose_parameter(parameters::get_parameter(
|
||||||
|
np, internal_np::normal_map), NormalMap())),
|
||||||
|
m_traits(parameters::choose_parameter(parameters::get_parameter(
|
||||||
|
np, internal_np::geom_traits), GeomTraits())),
|
||||||
|
m_squared_length_3(m_traits.compute_squared_length_3_object()),
|
||||||
|
m_squared_distance_3(m_traits.compute_squared_distance_3_object()),
|
||||||
|
m_scalar_product_3(m_traits.compute_scalar_product_3_object()),
|
||||||
|
m_sqrt(Get_sqrt::sqrt_object(m_traits)) {
|
||||||
|
|
||||||
\param minimum_radius the radius below which an estimated sphere
|
CGAL_precondition(input_range.size() > 0);
|
||||||
is considered as invalid and discarded. %Default is 0 (no limit).
|
const FT max_distance = parameters::choose_parameter(
|
||||||
|
parameters::get_parameter(np, internal_np::maximum_distance), FT(1));
|
||||||
|
CGAL_precondition(max_distance >= FT(0));
|
||||||
|
m_distance_threshold = max_distance;
|
||||||
|
|
||||||
\param maximum_radius the radius above which an estimated sphere
|
const FT max_angle = parameters::choose_parameter(
|
||||||
is considered as invalid and discarded. %Default is infinity (no
|
parameters::get_parameter(np, internal_np::maximum_angle), FT(25));
|
||||||
limit).
|
CGAL_precondition(max_angle >= FT(0) && max_angle <= FT(90));
|
||||||
|
|
||||||
\param point_map an instance of `PointMap` that maps an item from
|
m_min_region_size = parameters::choose_parameter(
|
||||||
`input_range` to `Kernel::Point_3`
|
parameters::get_parameter(np, internal_np::minimum_region_size), 3);
|
||||||
|
CGAL_precondition(m_min_region_size > 0);
|
||||||
|
|
||||||
\param normal_map an instance of `NormalMap` that maps an item
|
const FT default_cos_value = static_cast<FT>(std::cos(CGAL::to_double(
|
||||||
from `input_range` to `Kernel::Vector_3`
|
(max_angle * static_cast<FT>(CGAL_PI)) / FT(180))));
|
||||||
|
const FT cos_value = parameters::choose_parameter(
|
||||||
|
parameters::get_parameter(np, internal_np::cosine_value), default_cos_value);
|
||||||
|
CGAL_precondition(cos_value >= FT(0) && cos_value <= FT(1));
|
||||||
|
m_cos_value_threshold = cos_value;
|
||||||
|
|
||||||
\param traits an instance of `GeomTraits`.
|
const FT m_min_radius = parameters::choose_parameter(
|
||||||
|
parameters::get_parameter(np, internal_np::minimum_radius), FT(0));
|
||||||
|
CGAL_precondition(m_min_radius >= FT(0));
|
||||||
|
|
||||||
|
const FT m_max_radius = parameters::choose_parameter(
|
||||||
|
parameters::get_parameter(np, internal_np::maximum_radius),
|
||||||
|
FT(std::numeric_limits<double>::max()));
|
||||||
|
CGAL_precondition(m_max_radius >= m_min_radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief initializes all internal data structures.
|
||||||
|
|
||||||
|
\deprecated This constructor is deprecated since the version 5.5 of \cgal.
|
||||||
|
|
||||||
|
\param input_range
|
||||||
|
an instance of `InputRange` with 3D points and
|
||||||
|
corresponding 3D normal vectors
|
||||||
|
|
||||||
|
\param distance_threshold
|
||||||
|
the maximum distance from a point to a sphere. %Default is 1.
|
||||||
|
|
||||||
|
\param angle_threshold
|
||||||
|
the maximum accepted angle in degrees between the normal of a point
|
||||||
|
and the radius of a sphere. %Default is 25 degrees.
|
||||||
|
|
||||||
|
\param min_region_size
|
||||||
|
the minimum number of 3D points a region must have. %Default is 3.
|
||||||
|
|
||||||
|
\param minimum_radius
|
||||||
|
the radius below which an estimated sphere is considered as invalid
|
||||||
|
and discarded. %Default is 0 (no limit).
|
||||||
|
|
||||||
|
\param maximum_radius
|
||||||
|
the radius above which an estimated sphere is considered as invalid
|
||||||
|
and discarded. %Default is infinity (no limit).
|
||||||
|
|
||||||
|
\param point_map
|
||||||
|
an instance of `PointMap` that maps an item from `input_range` to `Kernel::Point_3`
|
||||||
|
|
||||||
|
\param normal_map
|
||||||
|
an instance of `NormalMap` that maps an item from `input_range` to `Kernel::Vector_3`
|
||||||
|
|
||||||
|
\param traits
|
||||||
|
an instance of `GeomTraits`
|
||||||
|
|
||||||
\pre `input_range.size() > 0`
|
\pre `input_range.size() > 0`
|
||||||
\pre `distance_threshold >= 0`
|
\pre `distance_threshold >= 0`
|
||||||
\pre `angle_threshold >= 0 && angle_threshold <= 90`
|
\pre `angle_threshold >= 0 && angle_threshold <= 90`
|
||||||
\pre `min_region_size > 0`
|
\pre `min_region_size > 0`
|
||||||
|
\pre `minimum_radius >= 0`
|
||||||
|
\pre `maximum_radius >= minimum_radius`
|
||||||
*/
|
*/
|
||||||
Least_squares_sphere_fit_region (const InputRange& input_range,
|
CGAL_DEPRECATED_MSG("This constructor is deprecated since the version 5.5 of CGAL!")
|
||||||
|
Least_squares_sphere_fit_region(
|
||||||
|
const InputRange& input_range,
|
||||||
const FT distance_threshold = FT(1),
|
const FT distance_threshold = FT(1),
|
||||||
const FT angle_threshold = FT(25),
|
const FT angle_threshold = FT(25),
|
||||||
const std::size_t min_region_size = 3,
|
const std::size_t min_region_size = 3,
|
||||||
const FT minimum_radius = FT(0),
|
const FT minimum_radius = FT(0),
|
||||||
const FT maximum_radius = std::numeric_limits<FT>::infinity(),
|
const FT maximum_radius = FT(std::numeric_limits<double>::max()),
|
||||||
const PointMap point_map = PointMap(),
|
const PointMap point_map = PointMap(),
|
||||||
const NormalMap normal_map = NormalMap(),
|
const NormalMap normal_map = NormalMap(),
|
||||||
const GeomTraits traits = GeomTraits())
|
const GeomTraits traits = GeomTraits()) :
|
||||||
: m_input_range(input_range)
|
Least_squares_sphere_fit_region(
|
||||||
, m_distance_threshold(distance_threshold)
|
input_range, CGAL::parameters::
|
||||||
, m_normal_threshold(static_cast<FT>(
|
maximum_distance(distance_threshold).
|
||||||
std::cos(
|
maximum_angle(angle_threshold).
|
||||||
CGAL::to_double(
|
minimum_region_size(min_region_size).
|
||||||
(angle_threshold * static_cast<FT>(CGAL_PI)) / FT(180)))))
|
minimum_radius(minimum_radius).
|
||||||
, m_min_region_size(min_region_size)
|
maximum_radius(maximum_radius).
|
||||||
, m_min_radius (minimum_radius)
|
point_map(point_map).
|
||||||
, m_max_radius (maximum_radius)
|
normal_map(normal_map).
|
||||||
, m_point_map(point_map)
|
geom_traits(traits))
|
||||||
, m_normal_map(normal_map)
|
{ }
|
||||||
, m_squared_length_3(traits.compute_squared_length_3_object())
|
|
||||||
, m_squared_distance_3(traits.compute_squared_distance_3_object())
|
|
||||||
, m_scalar_product_3(traits.compute_scalar_product_3_object())
|
|
||||||
, m_sqrt(Get_sqrt::sqrt_object(traits))
|
|
||||||
{
|
|
||||||
CGAL_precondition(input_range.size() > 0);
|
|
||||||
CGAL_precondition(distance_threshold >= FT(0));
|
|
||||||
CGAL_precondition(angle_threshold >= FT(0) && angle_threshold <= FT(90));
|
|
||||||
CGAL_precondition(min_region_size > 0);
|
|
||||||
CGAL_precondition(minimum_radius >= 0);
|
|
||||||
CGAL_precondition(maximum_radius > minimum_radius);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
|
|
@ -197,26 +283,28 @@ public:
|
||||||
/*!
|
/*!
|
||||||
\brief implements `RegionType::is_part_of_region()`.
|
\brief implements `RegionType::is_part_of_region()`.
|
||||||
|
|
||||||
This function controls if a point with the index `query_index` is
|
This function controls if a point with the index `query_index` is within
|
||||||
within the `distance_threshold` from the corresponding sphere and
|
the `maximum_distance` from the corresponding sphere and if the angle between
|
||||||
if the angle between its normal and the sphere radius is within
|
its normal and the sphere radius is within the `maximum_angle`. If both conditions
|
||||||
the `angle_threshold`. If both conditions are satisfied, it
|
are satisfied, it returns `true`, otherwise `false`.
|
||||||
returns `true`, otherwise `false`.
|
|
||||||
|
|
||||||
\param query_index index of the query point
|
\param query_index
|
||||||
|
index of the query point
|
||||||
|
|
||||||
\param indices indices of the inliers of the region
|
\param indices
|
||||||
|
indices of the inliers of the region
|
||||||
|
|
||||||
The first parameter is not used in this implementation.
|
The first parameter is not used in this implementation.
|
||||||
|
|
||||||
\return Boolean `true` or `false`
|
\return Boolean `true` or `false`
|
||||||
|
|
||||||
\pre `query_index >= 0 && query_index < input_range.size()`
|
\pre `query_index < input_range.size()`
|
||||||
*/
|
*/
|
||||||
bool is_part_of_region (const std::size_t,
|
bool is_part_of_region(
|
||||||
|
const std::size_t,
|
||||||
const std::size_t query_index,
|
const std::size_t query_index,
|
||||||
const std::vector<std::size_t>& indices) const
|
const std::vector<std::size_t>& indices) const {
|
||||||
{
|
|
||||||
CGAL_precondition(query_index < m_input_range.size());
|
CGAL_precondition(query_index < m_input_range.size());
|
||||||
|
|
||||||
// First, we need to integrate at least 6 points so that the
|
// First, we need to integrate at least 6 points so that the
|
||||||
|
|
@ -253,7 +341,7 @@ public:
|
||||||
if (std::isnan(sq_ray)) return false;
|
if (std::isnan(sq_ray)) return false;
|
||||||
ray = ray / m_sqrt (sq_ray);
|
ray = ray / m_sqrt (sq_ray);
|
||||||
|
|
||||||
if (CGAL::abs (normal * ray) < m_normal_threshold)
|
if (CGAL::abs (normal * ray) < m_cos_value_threshold)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -262,19 +350,19 @@ public:
|
||||||
/*!
|
/*!
|
||||||
\brief implements `RegionType::is_valid_region()`.
|
\brief implements `RegionType::is_valid_region()`.
|
||||||
|
|
||||||
This function controls if the estimated radius is between
|
This function controls if the estimated radius is between `minimum_radius`
|
||||||
`minimum_radius` and `maximum_radius` and if the `region` contains
|
and `maximum_radius` and if the `region` contains at least `min_region_size` points.
|
||||||
at least `min_region_size` points.
|
|
||||||
|
|
||||||
\param region
|
\param region
|
||||||
indices of points included in the region
|
indices of points included in the region
|
||||||
|
|
||||||
\return Boolean `true` or `false`
|
\return Boolean `true` or `false`
|
||||||
*/
|
*/
|
||||||
inline bool is_valid_region(const std::vector<std::size_t>& region) const
|
inline bool is_valid_region(const std::vector<std::size_t>& region) const {
|
||||||
{
|
return (
|
||||||
return ((m_min_radius <= m_radius && m_radius <= m_max_radius)
|
(m_min_radius <= m_radius && m_radius <= m_max_radius) &&
|
||||||
&& (region.size() >= m_min_region_size));
|
(region.size() >= m_min_region_size)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
@ -285,12 +373,13 @@ public:
|
||||||
\param region
|
\param region
|
||||||
indices of points included in the region
|
indices of points included in the region
|
||||||
|
|
||||||
|
\return Boolean `true` if the sphere fitting succeeded and `false` otherwise
|
||||||
|
|
||||||
\pre `region.size() > 0`
|
\pre `region.size() > 0`
|
||||||
*/
|
*/
|
||||||
bool update(const std::vector<std::size_t>& region)
|
bool update(const std::vector<std::size_t>& region) {
|
||||||
{
|
|
||||||
CGAL_precondition(region.size() > 0);
|
|
||||||
|
|
||||||
|
CGAL_precondition(region.size() > 0);
|
||||||
auto unary_function
|
auto unary_function
|
||||||
= [&](const std::size_t& idx) -> const Point_3&
|
= [&](const std::size_t& idx) -> const Point_3&
|
||||||
{
|
{
|
||||||
|
|
@ -308,6 +397,25 @@ public:
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Input_range& m_input_range;
|
||||||
|
const Point_map m_point_map;
|
||||||
|
const Normal_map m_normal_map;
|
||||||
|
const Traits m_traits;
|
||||||
|
|
||||||
|
FT m_distance_threshold;
|
||||||
|
FT m_cos_value_threshold;
|
||||||
|
std::size_t m_min_region_size;
|
||||||
|
FT m_min_radius;
|
||||||
|
FT m_max_radius;
|
||||||
|
|
||||||
|
const Squared_length_3 m_squared_length_3;
|
||||||
|
const Squared_distance_3 m_squared_distance_3;
|
||||||
|
const Scalar_product_3 m_scalar_product_3;
|
||||||
|
const Sqrt m_sqrt;
|
||||||
|
|
||||||
|
Point_3 m_center;
|
||||||
|
FT m_radius;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Point_set
|
} // namespace Point_set
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Author(s) : Simon Giraudot, Dmitry Anisimov
|
// Author(s) : Simon Giraudot
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef CGAL_SHAPE_DETECTION_REGION_GROWING_POINT_SET_LEAST_SQUARES_SPHERE_FIT_SORTING_H
|
#ifndef CGAL_SHAPE_DETECTION_REGION_GROWING_POINT_SET_LEAST_SQUARES_SPHERE_FIT_SORTING_H
|
||||||
|
|
@ -16,17 +16,7 @@
|
||||||
|
|
||||||
#include <CGAL/license/Shape_detection.h>
|
#include <CGAL/license/Shape_detection.h>
|
||||||
|
|
||||||
// STL includes.
|
|
||||||
#include <vector>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
// CGAL includes.
|
|
||||||
#include <CGAL/assertions.h>
|
|
||||||
#include <CGAL/Cartesian_converter.h>
|
|
||||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
|
||||||
|
|
||||||
// Internal includes.
|
// Internal includes.
|
||||||
#include <CGAL/Shape_detection/Region_growing/internal/utils.h>
|
|
||||||
#include <CGAL/Shape_detection/Region_growing/internal/property_map.h>
|
#include <CGAL/Shape_detection/Region_growing/internal/property_map.h>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
@ -42,24 +32,24 @@ namespace Point_set {
|
||||||
least squares sphere fit applied to the neighboring points of each point.
|
least squares sphere fit applied to the neighboring points of each point.
|
||||||
|
|
||||||
\tparam GeomTraits
|
\tparam GeomTraits
|
||||||
must be a model of `Kernel`.
|
a model of `Kernel`
|
||||||
|
|
||||||
\tparam InputRange
|
\tparam InputRange
|
||||||
must be a model of `ConstRange` whose iterator type is `RandomAccessIterator`.
|
a model of `ConstRange` whose iterator type is `RandomAccessIterator`
|
||||||
|
|
||||||
\tparam NeighborQuery
|
\tparam NeighborQuery
|
||||||
must be a model of `NeighborQuery`.
|
a model of `NeighborQuery`
|
||||||
|
|
||||||
\tparam PointMap
|
\tparam PointMap
|
||||||
must be an `LvaluePropertyMap` whose key type is the value type of the input
|
a model of `ReadablePropertyMap` whose key type is the value type of the input
|
||||||
range and value type is `Kernel::Point_3`.
|
range and value type is `Kernel::Point_3`
|
||||||
*/
|
*/
|
||||||
template<typename GeomTraits,
|
template<
|
||||||
|
typename GeomTraits,
|
||||||
typename InputRange,
|
typename InputRange,
|
||||||
typename NeighborQuery,
|
typename NeighborQuery,
|
||||||
typename PointMap>
|
typename PointMap>
|
||||||
class Least_squares_sphere_fit_sorting
|
class Least_squares_sphere_fit_sorting {
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
@ -76,7 +66,7 @@ public:
|
||||||
|
|
||||||
#ifdef DOXYGEN_RUNNING
|
#ifdef DOXYGEN_RUNNING
|
||||||
/*!
|
/*!
|
||||||
an `LvaluePropertyMap` whose key and value type is `std::size_t`.
|
a model of `ReadablePropertyMap` whose key and value type is `std::size_t`.
|
||||||
This map provides an access to the ordered indices of input points.
|
This map provides an access to the ordered indices of input points.
|
||||||
*/
|
*/
|
||||||
typedef unspecified_type Seed_map;
|
typedef unspecified_type Seed_map;
|
||||||
|
|
@ -84,12 +74,75 @@ public:
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// using FT = typename Traits::FT;
|
||||||
|
// using Compare_scores = internal::Compare_scores<FT>;
|
||||||
|
|
||||||
|
using Local_traits = Exact_predicates_inexact_constructions_kernel;
|
||||||
|
using Local_FT = typename Local_traits::FT;
|
||||||
|
using Local_point_3 = typename Local_traits::Point_3;
|
||||||
|
using To_local_converter = Cartesian_converter<Traits, Local_traits>;
|
||||||
|
using Compare_scores = internal::Compare_scores<Local_FT>;
|
||||||
|
|
||||||
|
public:
|
||||||
/// \name Initialization
|
/// \name Initialization
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief initializes all internal data structures.
|
\brief initializes all internal data structures.
|
||||||
|
|
||||||
|
\tparam NamedParameters
|
||||||
|
a sequence of \ref bgl_namedparameters "Named Parameters"
|
||||||
|
|
||||||
|
\param input_range
|
||||||
|
an instance of `InputRange` with 3D points
|
||||||
|
|
||||||
|
\param neighbor_query
|
||||||
|
an instance of `NeighborQuery` that is used internally to
|
||||||
|
access point's neighbors
|
||||||
|
|
||||||
|
\param np
|
||||||
|
a sequence of \ref bgl_namedparameters "Named Parameters"
|
||||||
|
among the ones listed below
|
||||||
|
|
||||||
|
\cgalNamedParamsBegin
|
||||||
|
\cgalParamNBegin{point_map}
|
||||||
|
\cgalParamDescription{an instance of `PointMap` that maps an item from `input_range`
|
||||||
|
to `Kernel::Point_3`}
|
||||||
|
\cgalParamDefault{`PointMap()`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
\cgalParamNBegin{geom_traits}
|
||||||
|
\cgalParamDescription{an instance of `GeomTraits`}
|
||||||
|
\cgalParamDefault{`GeomTraits()`}
|
||||||
|
\cgalParamNEnd
|
||||||
|
\cgalNamedParamsEnd
|
||||||
|
|
||||||
|
\pre `input_range.size() > 0`
|
||||||
|
*/
|
||||||
|
template<typename NamedParameters>
|
||||||
|
Least_squares_sphere_fit_sorting(
|
||||||
|
const InputRange& input_range,
|
||||||
|
NeighborQuery& neighbor_query,
|
||||||
|
const NamedParameters& np) :
|
||||||
|
m_input_range(input_range),
|
||||||
|
m_neighbor_query(neighbor_query),
|
||||||
|
m_point_map(parameters::choose_parameter(parameters::get_parameter(
|
||||||
|
np, internal_np::point_map), PointMap())),
|
||||||
|
m_traits(parameters::choose_parameter(parameters::get_parameter(
|
||||||
|
np, internal_np::geom_traits), GeomTraits())),
|
||||||
|
m_to_local_converter() {
|
||||||
|
|
||||||
|
CGAL_precondition(input_range.size() > 0);
|
||||||
|
m_order.resize(m_input_range.size());
|
||||||
|
std::iota(m_order.begin(), m_order.end(), 0);
|
||||||
|
m_scores.resize(m_input_range.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief initializes all internal data structures.
|
||||||
|
|
||||||
|
\deprecated This constructor is deprecated since the version 5.5 of \cgal.
|
||||||
|
|
||||||
\param input_range
|
\param input_range
|
||||||
an instance of `InputRange` with 3D points
|
an instance of `InputRange` with 3D points
|
||||||
|
|
||||||
|
|
@ -103,21 +156,15 @@ public:
|
||||||
|
|
||||||
\pre `input_range.size() > 0`
|
\pre `input_range.size() > 0`
|
||||||
*/
|
*/
|
||||||
Least_squares_sphere_fit_sorting (const InputRange& input_range,
|
CGAL_DEPRECATED_MSG("This constructor is deprecated since the version 5.5 of CGAL!")
|
||||||
|
Least_squares_sphere_fit_sorting(
|
||||||
|
const InputRange& input_range,
|
||||||
NeighborQuery& neighbor_query,
|
NeighborQuery& neighbor_query,
|
||||||
const PointMap point_map = PointMap())
|
const PointMap point_map = PointMap()) :
|
||||||
: m_input_range(input_range)
|
Least_squares_sphere_fit_sorting(
|
||||||
, m_neighbor_query(neighbor_query)
|
input_range, neighbor_query, CGAL::parameters::
|
||||||
, m_point_map(point_map)
|
point_map(point_map))
|
||||||
, m_to_local_converter()
|
{ }
|
||||||
{
|
|
||||||
CGAL_precondition(input_range.size() > 0);
|
|
||||||
|
|
||||||
m_order.resize(m_input_range.size());
|
|
||||||
for (std::size_t i = 0; i < m_input_range.size(); ++i)
|
|
||||||
m_order[i] = i;
|
|
||||||
m_scores.resize(m_input_range.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
|
|
@ -127,11 +174,10 @@ public:
|
||||||
/*!
|
/*!
|
||||||
\brief sorts indices of input points.
|
\brief sorts indices of input points.
|
||||||
*/
|
*/
|
||||||
void sort()
|
void sort() {
|
||||||
{
|
|
||||||
compute_scores();
|
compute_scores();
|
||||||
CGAL_postcondition(m_scores.size() > 0);
|
CGAL_postcondition(m_scores.size() > 0);
|
||||||
|
|
||||||
Compare_scores cmp(m_scores);
|
Compare_scores cmp(m_scores);
|
||||||
std::sort(m_order.begin(), m_order.end(), cmp);
|
std::sort(m_order.begin(), m_order.end(), cmp);
|
||||||
}
|
}
|
||||||
|
|
@ -145,25 +191,22 @@ public:
|
||||||
\brief returns an instance of `Seed_map` to access the ordered indices
|
\brief returns an instance of `Seed_map` to access the ordered indices
|
||||||
of input points.
|
of input points.
|
||||||
*/
|
*/
|
||||||
Seed_map seed_map()
|
Seed_map seed_map() {
|
||||||
{
|
|
||||||
return Seed_map(m_order);
|
return Seed_map(m_order);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
const Input_range& m_input_range;
|
||||||
|
Neighbor_query& m_neighbor_query;
|
||||||
|
const Point_map m_point_map;
|
||||||
|
const Traits m_traits;
|
||||||
|
std::vector<std::size_t> m_order;
|
||||||
|
std::vector<Local_FT> m_scores;
|
||||||
|
const To_local_converter m_to_local_converter;
|
||||||
|
|
||||||
// Types.
|
void compute_scores() {
|
||||||
using Local_traits = Exact_predicates_inexact_constructions_kernel;
|
|
||||||
using Local_FT = typename Local_traits::FT;
|
|
||||||
using Local_point_3 = typename Local_traits::Point_3;
|
|
||||||
using To_local_converter = Cartesian_converter<Traits, Local_traits>;
|
|
||||||
using Compare_scores = internal::Compare_scores<Local_FT>;
|
|
||||||
|
|
||||||
// Functions.
|
|
||||||
void compute_scores()
|
|
||||||
{
|
|
||||||
std::vector<std::size_t> neighbors;
|
std::vector<std::size_t> neighbors;
|
||||||
std::vector<Local_point_3> points;
|
std::vector<Local_point_3> points;
|
||||||
|
|
||||||
|
|
@ -201,16 +244,6 @@ private:
|
||||||
m_scores[i] = Local_FT(std::numeric_limits<double>::infinity());
|
m_scores[i] = Local_FT(std::numeric_limits<double>::infinity());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fields.
|
|
||||||
const Input_range& m_input_range;
|
|
||||||
Neighbor_query& m_neighbor_query;
|
|
||||||
const Point_map m_point_map;
|
|
||||||
|
|
||||||
std::vector<std::size_t> m_order;
|
|
||||||
std::vector<Local_FT> m_scores;
|
|
||||||
|
|
||||||
const To_local_converter m_to_local_converter;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Point_set
|
} // namespace Point_set
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue