mirror of https://github.com/CGAL/cgal
finally get rid of conditional_deref
This commit is contained in:
parent
2541f7c22c
commit
f693471647
|
|
@ -80,7 +80,7 @@ int main(int argc, char** argv) {
|
|||
|
||||
// Create an instance of the region growing class.
|
||||
Region_growing region_growing(
|
||||
point_set_2, neighbor_query, region_type, sorting.ordered());
|
||||
point_set_2, sorting.ordered(), neighbor_query, region_type);
|
||||
|
||||
// Add maps to get a colored output.
|
||||
Point_set_2::Property_map<unsigned char>
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ int main(int argc, char *argv[]) {
|
|||
line_sorting.sort();
|
||||
|
||||
RG_lines rg_lines(
|
||||
segment_range, pgraph, line_region, line_sorting.ordered());
|
||||
segment_range, line_sorting.ordered(), pgraph, line_region);
|
||||
|
||||
std::vector<typename RG_lines::Primitive_and_region> subregions;
|
||||
rg_lines.detect(std::back_inserter(subregions));
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
// Create an instance of the region growing class.
|
||||
Region_growing region_growing(
|
||||
point_set, neighbor_query, region_type, sorting.ordered());
|
||||
point_set, sorting.ordered(), neighbor_query, region_type);
|
||||
|
||||
// Run the algorithm.
|
||||
Output_range output_range;
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
// Create an instance of the region growing class.
|
||||
Region_growing region_growing(
|
||||
face_range, neighbor_query, region_type, sorting.ordered());
|
||||
face_range, sorting.ordered(), neighbor_query, region_type);
|
||||
|
||||
// Run the algorithm.
|
||||
std::vector<typename Region_growing::Primitive_and_region> regions;
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ namespace Point_set {
|
|||
\cgalNamedParamsBegin
|
||||
\cgalParamNBegin{item_map}
|
||||
\cgalParamDescription{an instance of a model of `ReadablePropertyMap` with `InputRange::const_iterator`
|
||||
as key type and `Item` as value type.`}
|
||||
as key type and `Item` as value type.}
|
||||
\cgalParamDefault{A default is provided when `Item` is `InputRange::const_iterator` or its value type.}
|
||||
\cgalParamNEnd
|
||||
\cgalParamNBegin{k_neighbors}
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ namespace Point_set {
|
|||
\cgalNamedParamsBegin
|
||||
\cgalParamNBegin{item_map}
|
||||
\cgalParamDescription{an instance of a model of `ReadablePropertyMap` with `InputRange::const_iterator`
|
||||
as key type and `Item` as value type.`}
|
||||
as key type and `Item` as value type.}
|
||||
\cgalParamDefault{A default is provided when `Item` is `InputRange::const_iterator` or its value type.}
|
||||
\cgalParamNEnd
|
||||
\cgalParamNBegin{point_map}
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ namespace Point_set {
|
|||
\cgalNamedParamsBegin
|
||||
\cgalParamNBegin{item_map}
|
||||
\cgalParamDescription{an instance of a model of `ReadablePropertyMap` with `InputRange::const_iterator`
|
||||
as key type and `Item` as value type.`}
|
||||
as key type and `Item` as value type.}
|
||||
\cgalParamDefault{A default is provided when `Item` is `InputRange::const_iterator` or its value type.}
|
||||
\cgalParamNEnd
|
||||
\cgalParamNBegin{point_map}
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ namespace Point_set {
|
|||
\cgalNamedParamsBegin
|
||||
\cgalParamNBegin{item_map}
|
||||
\cgalParamDescription{an instance of a model of `ReadablePropertyMap` with `InputRange::const_iterator`
|
||||
as key type and `Item` as value type.`}
|
||||
as key type and `Item` as value type.}
|
||||
\cgalParamDefault{A default is provided when `Item` is `InputRange::const_iterator` or its value type.}
|
||||
\cgalParamNEnd
|
||||
\cgalParamNBegin{point_map}
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ namespace Point_set {
|
|||
\cgalNamedParamsBegin
|
||||
\cgalParamNBegin{item_map}
|
||||
\cgalParamDescription{an instance of a model of `ReadablePropertyMap` with `InputRange::const_iterator`
|
||||
as key type and `Item` as value type.`}
|
||||
as key type and `Item` as value type.}
|
||||
\cgalParamDefault{A default is provided when `Item` is `InputRange::const_iterator` or its value type.}
|
||||
\cgalParamNEnd
|
||||
\cgalParamNBegin{point_map}
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ namespace Point_set {
|
|||
\cgalNamedParamsBegin
|
||||
\cgalParamNBegin{item_map}
|
||||
\cgalParamDescription{an instance of a model of `ReadablePropertyMap` with `InputRange::const_iterator`
|
||||
as key type and `Item` as value type.`}
|
||||
as key type and `Item` as value type.}
|
||||
\cgalParamDefault{A default is provided when `Item` is `InputRange::const_iterator` or its value type.}
|
||||
\cgalParamNEnd
|
||||
\cgalParamNBegin{point_map}
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ public:
|
|||
\cgalNamedParamsBegin
|
||||
\cgalParamNBegin{item_map}
|
||||
\cgalParamDescription{an instance of a model of `ReadablePropertyMap` with `InputRange::const_iterator`
|
||||
as key type and `Item` as value type.`}
|
||||
as key type and `Item` as value type.}
|
||||
\cgalParamDefault{A default is provided when `Item` is `InputRange::const_iterator` or its value type.}
|
||||
\cgalParamNEnd
|
||||
\cgalParamNBegin{sphere_radius}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include <CGAL/property_map.h>
|
||||
#include <CGAL/boost/graph/properties.h>
|
||||
#include <CGAL/Shape_detection/Region_growing/internal/utils.h>
|
||||
#include <CGAL/Shape_detection/Region_growing/internal/property_map.h>
|
||||
|
||||
namespace CGAL {
|
||||
namespace Shape_detection {
|
||||
|
|
@ -85,6 +86,11 @@ namespace Shape_detection {
|
|||
\tparam InputRange
|
||||
a model of `ConstRange`
|
||||
|
||||
\tparam ItemMap
|
||||
a model of `ReadablePropertyMap` with `InputRange::const_iterator` as key type and `Item` as value type.
|
||||
A default can be deduced using the value type of `InputRange` and `Item` to be
|
||||
either `CGAL::Dereference_property_map` or `CGAL::Identity_property_map`.
|
||||
|
||||
\param input_range
|
||||
a range of input items for region growing
|
||||
|
||||
|
|
@ -96,33 +102,49 @@ namespace Shape_detection {
|
|||
an instance of `RegionType` that is used internally to
|
||||
control if items form a valid region type
|
||||
|
||||
\param item_map
|
||||
an instance of the property map to retrieve items from input values
|
||||
|
||||
\pre `input_range.size() > 0`
|
||||
*/
|
||||
template<typename InputRange>
|
||||
template<typename InputRange, typename ItemMap = Default>
|
||||
Region_growing(
|
||||
const InputRange& input_range,
|
||||
NeighborQuery& neighbor_query,
|
||||
RegionType& region_type) :
|
||||
RegionType& region_type,
|
||||
ItemMap item_map = ItemMap()) :
|
||||
m_neighbor_query(neighbor_query),
|
||||
m_region_type(region_type),
|
||||
m_region_map(region_type.region_index_map()),
|
||||
m_visited(m_visited_map) {
|
||||
|
||||
m_visited(m_visited_map)
|
||||
{
|
||||
CGAL_precondition(input_range.size() > 0);
|
||||
m_seed_range.resize(input_range.size());
|
||||
|
||||
using Item_helper = internal::Item_map_helper<ItemMap, Item, typename InputRange::const_iterator>;
|
||||
using Item_map = typename Item_helper::type;
|
||||
Item_map item_map_ = Item_helper::get(item_map);
|
||||
|
||||
std::size_t idx = 0;
|
||||
for (auto it = input_range.begin(); it != input_range.end(); it++)
|
||||
m_seed_range[idx++] = internal::conditional_deref<typename InputRange::const_iterator, Item>()(it);
|
||||
m_seed_range[idx++] = get(item_map_, it);
|
||||
|
||||
clear(input_range);
|
||||
clear(input_range, item_map_);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initializes the region growing algorithm.
|
||||
|
||||
\tparam InputRange
|
||||
a model of `ConstRange
|
||||
a model of `ConstRange`
|
||||
|
||||
\tparam SeedRange
|
||||
a model of `ConstRange` with `Item` as value type
|
||||
|
||||
\tparam ItemMap
|
||||
a model of `ReadablePropertyMap` with `InputRange::const_iterator` as key type and `Item` as value type.
|
||||
A default can be deduced using the value type of `InputRange` and `Item` to be
|
||||
either `CGAL::Dereference_property_map` or `CGAL::Identity_property_map`.
|
||||
|
||||
\param input_range
|
||||
a range of input items for region growing
|
||||
|
|
@ -139,14 +161,18 @@ namespace Shape_detection {
|
|||
a vector of `Item` that is used as seeds for the region growing.
|
||||
Defaults to the full input_range.
|
||||
|
||||
\param item_map
|
||||
an instance of the property map to retrieve items from input values
|
||||
|
||||
\pre `input_range.size() > 0`
|
||||
*/
|
||||
template<typename InputRange, typename SeedRange>
|
||||
template<typename InputRange, typename SeedRange, typename ItemMap = Default>
|
||||
Region_growing(
|
||||
const InputRange& input_range,
|
||||
SeedRange& seed_range,
|
||||
NeighborQuery& neighbor_query,
|
||||
RegionType& region_type,
|
||||
SeedRange& seed_range) :
|
||||
ItemMap item_map = ItemMap()) :
|
||||
m_neighbor_query(neighbor_query),
|
||||
m_region_type(region_type),
|
||||
m_region_map(region_type.region_index_map()),
|
||||
|
|
@ -154,14 +180,17 @@ namespace Shape_detection {
|
|||
|
||||
CGAL_precondition(input_range.size() > 0);
|
||||
CGAL_precondition(seed_range.size() > 0);
|
||||
|
||||
m_seed_range.resize(seed_range.size());
|
||||
|
||||
using Item_helper = internal::Item_map_helper<ItemMap, Item, typename InputRange::const_iterator>;
|
||||
using Item_map = typename Item_helper::type;
|
||||
Item_map item_map_ = Item_helper::get(item_map);
|
||||
|
||||
std::size_t idx = 0;
|
||||
for (auto it = seed_range.begin(); it != seed_range.end(); it++)
|
||||
m_seed_range[idx++] = internal::conditional_deref<typename SeedRange::const_iterator, Item>()(it);
|
||||
m_seed_range[idx++] = *it;
|
||||
|
||||
clear(input_range);
|
||||
clear(input_range, item_map_);
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
|
@ -235,18 +264,31 @@ namespace Shape_detection {
|
|||
\tparam InputRange
|
||||
a model of `ConstRange
|
||||
|
||||
\tparam ItemMap
|
||||
a model of `ReadablePropertyMap` with `InputRange::const_iterator` as key type and `Item` as value type.
|
||||
A default can be deduced using the value type of `InputRange` and `Item` to be
|
||||
either `CGAL::Dereference_property_map` or `CGAL::Identity_property_map`.
|
||||
|
||||
\param input_range
|
||||
a range of input items for region growing
|
||||
|
||||
\param output
|
||||
an iterator of type `PrimitiveAndRegionOutputIterator`.
|
||||
|
||||
\param item_map
|
||||
an instance of the property map to retrieve items from input values
|
||||
|
||||
\return past-the-end position in the output sequence
|
||||
*/
|
||||
template<typename InputRange, typename ItemOutputIterator>
|
||||
ItemOutputIterator unassigned_items(const InputRange& input_range, ItemOutputIterator output) const {
|
||||
template<typename InputRange, typename ItemOutputIterator, typename ItemMap = Default>
|
||||
ItemOutputIterator unassigned_items(const InputRange& input_range, ItemOutputIterator output, ItemMap item_map = ItemMap()) const
|
||||
{
|
||||
using Item_helper = internal::Item_map_helper<ItemMap, Item, typename InputRange::const_iterator>;
|
||||
using Item_map = typename Item_helper::type;
|
||||
Item_map item_map_ = Item_helper::get(item_map);
|
||||
|
||||
for (auto it = input_range.begin(); it != input_range.end(); it++) {
|
||||
Item i = internal::conditional_deref<typename InputRange::const_iterator, Item>()(it);
|
||||
Item i = get(item_map_,it);
|
||||
if (!get(m_visited, i))
|
||||
*(output++) = i;
|
||||
}
|
||||
|
|
@ -256,10 +298,10 @@ namespace Shape_detection {
|
|||
/// @}
|
||||
|
||||
/// \cond SKIP_IN_MANUAL
|
||||
template <class InputRange>
|
||||
void clear(const InputRange& input_range) {
|
||||
template <class InputRange, class ItemMap>
|
||||
void clear(const InputRange& input_range, ItemMap item_map) {
|
||||
for (auto it = input_range.begin(); it != input_range.end(); it++) {
|
||||
Item item = internal::conditional_deref<typename InputRange::const_iterator, typename Region_map::key_type>()(it);
|
||||
Item item = get(item_map, it);
|
||||
put(m_region_map, item, std::size_t(-1));
|
||||
}
|
||||
// TODO if we want to allow subranges while NeighborQuery operates on the full range
|
||||
|
|
|
|||
|
|
@ -56,6 +56,26 @@ struct Default_property_map_helper<NP, Item, Iterator, Tag, false>
|
|||
}
|
||||
};
|
||||
|
||||
template <class ItemMap, class Item, class Iterator>
|
||||
struct Item_map_helper
|
||||
{
|
||||
using type = ItemMap;
|
||||
static const ItemMap& get(const ItemMap& m)
|
||||
{
|
||||
return m;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Item, class Iterator>
|
||||
struct Item_map_helper<Default, Item, Iterator>
|
||||
{
|
||||
using type = typename Default_property_map_helper<Default, Item, Iterator, int, false>::type;
|
||||
static type get(Default)
|
||||
{
|
||||
return type();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace Shape_detection
|
||||
} // namespace CGAL
|
||||
|
|
|
|||
|
|
@ -61,24 +61,6 @@ namespace internal {
|
|||
mutable T it;
|
||||
};
|
||||
|
||||
template<typename Input, typename Result, bool = std::is_same<Input, Result>::value >
|
||||
struct conditional_deref;
|
||||
|
||||
template<typename Input, typename Result>
|
||||
struct conditional_deref<Input, Result, true> {
|
||||
const Result& operator()(const Input& it) {
|
||||
return it;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Input, typename Result>
|
||||
struct conditional_deref<Input, Result, false> {
|
||||
typename std::iterator_traits<Input>::reference
|
||||
operator()(Input it) {
|
||||
return *it;
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: this should be customisable in named function parameters
|
||||
template<class T, bool = CGAL::is_iterator<T>::value>
|
||||
struct hash_item {};
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ bool test_region_growing_on_cube(int argc, char *argv[]) {
|
|||
|
||||
// Run region growing.
|
||||
Region_growing region_growing(
|
||||
face_range, neighbor_query, region_type, sorting.ordered());
|
||||
face_range, sorting.ordered(), neighbor_query, region_type);
|
||||
|
||||
std::vector<typename Region_growing::Primitive_and_region> regions;
|
||||
region_growing.detect(std::back_inserter(regions));
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ bool test(int argc, char** argv, const std::string name, const std::size_t minr,
|
|||
|
||||
// Run region growing.
|
||||
Region_growing region_growing(
|
||||
input_range, neighbor_query, region_type, sorting.ordered());
|
||||
input_range, sorting.ordered(), neighbor_query, region_type);
|
||||
|
||||
std::vector<typename Region_growing::Primitive_and_region> regions;
|
||||
region_growing.detect(std::back_inserter(regions));
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ bool test(
|
|||
// Run region growing.
|
||||
Region_type region_type = lambda_region(input_range);
|
||||
Region_growing region_growing(
|
||||
input_range, neighbor_query, region_type, sorting.ordered());
|
||||
input_range, sorting.ordered(), neighbor_query, region_type);
|
||||
|
||||
std::vector<typename Region_growing::Primitive_and_region> regions;
|
||||
region_growing.detect(std::back_inserter(regions));
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
// Run region growing.
|
||||
Region_growing region_growing(
|
||||
face_range, neighbor_query, region_type, sorting.ordered());
|
||||
face_range, sorting.ordered(), neighbor_query, region_type);
|
||||
|
||||
std::vector<Region_growing::Primitive_and_region> regions;
|
||||
region_growing.detect(std::back_inserter(regions));
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ bool test_lines_segment_set_2_sorting() {
|
|||
|
||||
std::vector<typename Region_growing::Primitive_and_region> regions;
|
||||
Region_growing region_growing(
|
||||
segments, neighbor_query, region_type, sorting.ordered());
|
||||
segments, sorting.ordered(), neighbor_query, region_type);
|
||||
region_growing.detect(std::back_inserter(regions));
|
||||
assert(regions.size() == 2);
|
||||
assert(regions[0].second.size() == 2);
|
||||
|
|
@ -227,7 +227,7 @@ bool test_lines_segment_set_3() {
|
|||
|
||||
// Create an instance of the region growing class.
|
||||
RG_planes rg_planes(
|
||||
face_range, one_ring_query, plane_type, plane_sorting.ordered());
|
||||
face_range, plane_sorting.ordered(), one_ring_query, plane_type);
|
||||
|
||||
assert(surface_mesh.number_of_faces() == 7320);
|
||||
std::vector<typename RG_planes::Primitive_and_region> regions;
|
||||
|
|
@ -246,7 +246,7 @@ bool test_lines_segment_set_3() {
|
|||
|
||||
std::vector<typename RG_lines::Primitive_and_region> regions2;
|
||||
RG_lines region_growing(
|
||||
segment_range, pgraph, region_type, sorting.ordered());
|
||||
segment_range, sorting.ordered(), pgraph, region_type);
|
||||
region_growing.detect(std::back_inserter(regions2));
|
||||
assert(regions2.size() == 21);
|
||||
return true;
|
||||
|
|
|
|||
Loading…
Reference in New Issue