geometry/triangulation.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // SPDX-License-Identifier: BSD-3-Clause | ||
| 2 | /// @file triangulation.cpp | ||
| 3 | /// @brief Fan triangulation of USD polygons. | ||
| 4 | #include "ernie/geometry/triangulation.h" | ||
| 5 | |||
| 6 | #include <algorithm> | ||
| 7 | #include <stdexcept> | ||
| 8 | |||
| 9 | namespace ernie { | ||
| 10 | |||
| 11 | 14 | std::vector<std::uint32_t> TriangulateFaces(std::span<const std::int64_t> faceVertexCounts, | |
| 12 | std::span<const std::int64_t> faceVertexIndices, | ||
| 13 | std::size_t points) { | ||
| 14 | 14 | std::vector<std::uint32_t> triangles; | |
| 15 | 14 | std::size_t next = 0; | |
| 16 | 27 | for (const std::int64_t count : faceVertexCounts) { | |
| 17 | 17 | if (count < 3) { | |
| 18 | 1 | throw std::invalid_argument("Every face needs at least 3 vertices"); | |
| 19 | } | ||
| 20 | 16 | const auto size = static_cast<std::size_t>(count); | |
| 21 | 16 | if (next + size > faceVertexIndices.size()) { | |
| 22 | 1 | throw std::invalid_argument("faceVertexCounts add up to more than faceVertexIndices"); | |
| 23 | } | ||
| 24 | 15 | const std::span<const std::int64_t> face = faceVertexIndices.subspan(next, size); | |
| 25 | 15 | if (std::ranges::any_of(face, [&](std::int64_t index) { | |
| 26 | 52 | return index < 0 || static_cast<std::size_t>(index) >= points; | |
| 27 | })) { | ||
| 28 | 2 | throw std::invalid_argument("faceVertexIndices has an index out of range"); | |
| 29 | } | ||
| 30 | 34 | for (std::size_t k = 1; k + 1 < size; ++k) { | |
| 31 | 84 | for (const std::int64_t corner : {face[0], face[k], face[k + 1]}) { | |
| 32 | 63 | triangles.push_back(static_cast<std::uint32_t>(corner)); | |
| 33 | } | ||
| 34 | } | ||
| 35 | 13 | next += size; | |
| 36 | } | ||
| 37 | 10 | if (next != faceVertexIndices.size()) { | |
| 38 | 1 | throw std::invalid_argument("faceVertexCounts add up to fewer than faceVertexIndices"); | |
| 39 | } | ||
| 40 | 9 | return triangles; | |
| 41 | 5 | } | |
| 42 | |||
| 43 | } // namespace ernie | ||
| 44 |