7 #include <range/v3/view/enumerate.hpp>
8 #include <range/v3/view/sliding.hpp>
16 inputFeatures(
std::move(features)), chainApproximationParams(chainApproximationParams)
22 inputFeatures(features), chainApproximationParams(chainApproximationParams)
29 ARMARX_DEBUG <<
"Starting merge of " << inputFeatures.size() <<
" features";
32 for (
const auto [i, f] : ranges::views::enumerate(inputFeatures))
34 std::optional<std::size_t> lastFeature = std::nullopt;
35 for (
const auto& p : f.points)
37 if (
auto res = checkPoint(p, i, lastFeature); res)
39 uf.unite(i, res.value());
40 lastFeature = res.value();
45 for (
const auto [i, f] : ranges::views::enumerate(inputFeatures))
47 std::size_t representative = uf.find(i);
48 if (i != representative)
50 ARMARX_DEBUG <<
"add feature " << i <<
" to feature " << representative;
51 addToFeature(inputFeatures[representative], f);
55 std::vector<Features> merged;
56 for (
const auto [i, f] : ranges::views::enumerate(inputFeatures))
65 recalculateFeatures(merged);
67 ARMARX_DEBUG <<
"Merged " << inputFeatures.size() <<
" features into " << merged.size();
73 const std::vector<Eigen::Vector2f>& vertices)
78 const auto signum = [](
float x)
82 return x > 0 ? 1 : -1;
85 const auto checkSide = [&](
const Eigen::Vector2f&
a,
const Eigen::Vector2f& b)
86 {
return signum((p.x() -
a.x()) * (b.y() -
a.y()) - (p.y() -
a.y()) * (b.x() -
a.x())); };
88 float previousSide = 0;
89 for (
const auto edge : vertices | ranges::views::sliding(2))
91 int d = checkSide(edge[0], edge[1]);
95 if (previousSide != 0 && d != previousSide)
101 int d = checkSide(vertices.back(), vertices.front());
104 return d == previousSide;
107 std::optional<std::size_t>
108 FeatureMerger::checkPoint(
const Eigen::Vector2f p,
110 const std::optional<std::size_t> checkFirst)
115 if (
insideConvexPoly(p, inputFeatures[checkFirst.value()].convexHull->vertices))
117 return checkFirst.value();
121 for (
const auto [i, f] : ranges::views::enumerate(inputFeatures))
123 if (i == ignore || (checkFirst && i == checkFirst.value()))
137 f.points.insert(f.points.end(), toAdd.points.begin(), toAdd.points.end());
139 f.convexHull = std::nullopt;
140 f.circle = std::nullopt;
141 f.ellipsoid = std::nullopt;
142 f.chain = std::nullopt;
146 FeatureMerger::recalculateFeatures(std::vector<Features>& features)
148 for (
auto& f : features)
168 f.points, f.convexHull, chainApproximationParams);