1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
|
// Copyright (c) 2020 GeometryFactory SARL (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL: https://github.com/CGAL/cgal/blob/v6.1/Shape_regularization/include/CGAL/Shape_regularization/internal/Parallel_groups_2.h $
// $Id: include/CGAL/Shape_regularization/internal/Parallel_groups_2.h b26b07a1242 $
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Dmitry Anisimov, Gennadii Sytov
//
#ifndef CGAL_SHAPE_REGULARIZATION_PARALLEL_GROUPS_2_H
#define CGAL_SHAPE_REGULARIZATION_PARALLEL_GROUPS_2_H
#include <CGAL/license/Shape_regularization.h>
// Boost includes.
#include <CGAL/boost/graph/named_params_helper.h>
#include <CGAL/Named_function_parameters.h>
// Internal includes.
#include <CGAL/Shape_regularization/internal/utils.h>
namespace CGAL {
namespace Shape_regularization {
namespace internal {
template<
typename GeomTraits,
typename InputRange,
typename SegmentMap>
class Parallel_groups_2 {
public:
using Traits = GeomTraits;
using Input_range = InputRange;
using Segment_map = SegmentMap;
using FT = typename Traits::FT;
using Segment_2 = typename Traits::Segment_2;
using Indices = std::vector<std::size_t>;
template<typename NamedParameters>
Parallel_groups_2(
const InputRange& input_range,
const NamedParameters& np,
const SegmentMap segment_map,
const GeomTraits&) :
m_input_range(input_range),
m_segment_map(segment_map) {
const FT max_angle = parameters::choose_parameter(
parameters::get_parameter(np, internal_np::maximum_angle), FT(5));
const bool preserve_order = parameters::choose_parameter(
parameters::get_parameter(np, internal_np::preserve_order), false);
CGAL_precondition(max_angle >= FT(0) && max_angle <= FT(90));
m_max_angle = max_angle;
make_parallel_groups(preserve_order);
}
template<typename OutputIterator>
OutputIterator groups(OutputIterator groups) const {
for (const auto& parallel_group : m_parallel_groups) {
const auto& group = parallel_group;
*(groups++) = group;
}
return groups;
}
private:
const Input_range& m_input_range;
const Segment_map m_segment_map;
FT m_max_angle;
std::vector<Indices> m_parallel_groups;
void make_parallel_groups(const bool preserve_order) {
m_parallel_groups.clear();
std::vector<bool> states(m_input_range.size(), false);
Indices parallel_group;
for (std::size_t i = 0; i < m_input_range.size(); ++i) {
if (states[i]) continue;
const auto& si = get(
m_segment_map, *(m_input_range.begin() + i));
states[i] = true;
parallel_group.clear();
parallel_group.push_back(i);
traverse_group(preserve_order, i, si, states, parallel_group);
m_parallel_groups.push_back(parallel_group);
}
}
void traverse_group(
const bool preserve_order,
const std::size_t i,
const Segment_2& si,
std::vector<bool>& states,
Indices& parallel_group) const {
for (std::size_t j = i + 1; j < m_input_range.size(); ++j) {
if (states[j]) continue;
const auto& sj = get(
m_segment_map, *(m_input_range.begin() + j));
const FT angle_2 = internal::angle_2(si, sj);
if (angle_2 <= m_max_angle) {
states[j] = true;
parallel_group.push_back(j);
} else if (preserve_order) return;
}
}
};
} // namespace internal
} // namespace Shape_regularization
} // namespace CGAL
#endif // CGAL_SHAPE_REGULARIZATION_PARALLEL_GROUPS_2_H
|