Visual Computing Library  devel
Loading...
Searching...
No Matches
ear_cut.h
1/*****************************************************************************
2 * VCLib *
3 * Visual Computing Library *
4 * *
5 * Copyright(C) 2021-2025 *
6 * Visual Computing Lab *
7 * ISTI - Italian National Research Council *
8 * *
9 * All rights reserved. *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the Mozilla Public License Version 2.0 as published *
13 * by the Mozilla Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * Mozilla Public License Version 2.0 *
20 * (https://www.mozilla.org/en-US/MPL/2.0/) for more details. *
21 ****************************************************************************/
22
23#ifndef VCL_ALGORITHMS_CORE_POLYGON_EAR_CUT_H
24#define VCL_ALGORITHMS_CORE_POLYGON_EAR_CUT_H
25
26#include "projection.h"
27
28#include <vclib/space/core.h>
29
30#if __has_include(<mapbox/earcut.hpp>)
31#include <mapbox/earcut.hpp>
32#else
33// inclusion for usage of vclib without CMake - not ideal but necessary for
34// header only
35#include "../../../../../external/earcut.hpp-2.2.3/include/mapbox/earcut.hpp"
36#endif
37
38/* Structs to make working the mapbox earcut algorithm on vcl::Point2 */
39
40namespace mapbox::util {
41
42template<typename Scalar>
43struct nth<0, vcl::Point2<Scalar>>
44{
45 inline static auto get(const vcl::Point2<Scalar>& t) { return t.x(); };
46};
47
48template<typename Scalar>
49struct nth<1, vcl::Point2<Scalar>>
50{
51 inline static auto get(const vcl::Point2<Scalar>& t) { return t.y(); };
52};
53
54} // namespace mapbox::util
55
56namespace vcl {
57
89template<Point2IteratorConcept Iterator>
90std::vector<uint> earCut(Iterator begin, Iterator end)
91{
92 using PointT = Iterator::value_type;
93 using Scalar = PointT::ScalarType;
94
95 // Convert the polygon represented as a sequence of vertices to a vector
96 // of vectors of points. This is necessary because the earcut library
97 // expects the polygon to be represented as a vector of contours, where
98 // each contour is a vector of points. In this case, there is only one
99 // contour, which is represented as a vector of points.
100 std::vector<std::vector<Point2<Scalar>>> poly;
101 poly.emplace_back(begin, end);
102
103 // Use the earcut library to triangulate the polygon and return the
104 // result.
105 return mapbox::earcut<uint>(poly);
106}
107
143template<Point3IteratorConcept Iterator>
144std::vector<uint> earCut(Iterator begin, Iterator end)
145{
146 // Project the 3D polygon onto a 2D plane defined by its normal.
147 auto poly2D = project(begin, end);
148
149 // Use the ear-cut algorithm to triangulate the polygon in the 2D plane
150 // and return the result.
151 return earCut(poly2D.begin(), poly2D.end());
152}
153
164template<Range R>
165std::vector<uint> earCut(R&& range)
166{
167 return earCut(std::ranges::begin(range), std::ranges::end(range));
168}
169
170} // namespace vcl
171
172#endif // VCL_ALGORITHMS_CORE_POLYGON_EAR_CUT_H
A class representing a box in N-dimensional space.
Definition box.h:46
auto project(Iterator begin, Iterator end)
Project a 3D polygon onto a plane, and return the 2D polygon.
Definition projection.h:41
std::vector< uint > earCut(Iterator begin, Iterator end)
Triangulates a simple polygon with no holes using the ear-cutting algorithm.
Definition ear_cut.h:90
Point< Scalar, 2 > Point2
A convenience alias for a 2-dimensional Point.
Definition point.h:695