3#include "../utils/Common.hpp"
15class ContourTraceComputation;
16namespace contours::detail {
17class ContourTraceTraversal;
23enum class ContourSide : uint8_t { North = 0, West = 1, East = 2, South = 3 };
28enum class ContourBoundaryKind : uint8_t { External, Internal };
37 ContourSide
side = ContourSide::North;
48 ContourBoundaryKind
kind = ContourBoundaryKind::External;
57namespace contours::detail {
61 return (4 * pixel) +
static_cast<int>(side);
65[[nodiscard]]
inline ContourEdge unpackContourEdge(
int packedEdge) {
69 return ContourEdge{packedEdge / 4,
static_cast<ContourSide
>(packedEdge & 3)};
133 const int* packedEdge_ =
nullptr;
149 return packedEdges_.empty() ?
begin() :
iterator(packedEdges_.data() + packedEdges_.size());
159 std::span<const int> packedEdges_;
263 if (
boundary.kind != ContourBoundaryKind::External) {
267 throw std::logic_error(
"ContourTraceView::externalBoundary requires exactly one external boundary.");
272 throw std::logic_error(
"ContourTraceView::externalBoundary requires exactly one external boundary.");
301 friend class contours::detail::ContourTraceTraversal;
316 [[nodiscard]] std::span<const int> boundarySpan(
const ContourBoundary& boundary)
const {
317 const std::size_t offset = boundary.edgeOffset;
318 const std::size_t count = boundary.edgeCount;
319 if (offset > packedEdges_.size() || count > packedEdges_.size() - offset) {
320 throw std::invalid_argument(
"ContourBoundary does not belong to this contour trace.");
322 return packedEdges_.subspan(offset, count);
325 std::span<const int> packedEdges_;
326 std::span<const ContourBoundary> boundaries_;
345 : packedEdges_(trace.packedEdges_.begin(), trace.packedEdges_.end()),
346 boundaries_(trace.boundaries_.begin(), trace.boundaries_.end()) {}
393 std::vector<int> packedEdges_;
394 std::vector<ContourBoundary> boundaries_;
constexpr PixelId InvalidPixel
Sentinel value used to denote an invalid pixel identifier.
Forward iterator that unpacks contour edges on dereference.
std::ptrdiff_t difference_type
Signed iterator-distance type.
iterator & operator++()
Advances to the next packed edge.
ContourEdge value_type
Unpacked edge value yielded by dereference.
value_type operator*() const
Returns the unpacked current edge.
iterator operator++(int)
Advances while retaining the previous iterator position.
friend bool operator==(const iterator &, const iterator &)=default
Compares packed-edge positions.
iterator(const int *packedEdge)
Creates an iterator at one packed-edge position.
std::forward_iterator_tag iterator_category
Standard category for a multi-pass forward iterator.
Immutable range over unpacked contour edges.
iterator end() const
Returns the exclusive end iterator.
ContourEdgeRange(std::span< const int > packedEdges)
Creates a view over packed contour edges.
bool empty() const noexcept
Returns whether the range contains no edges.
iterator begin() const
Returns an iterator to the first contour edge.
std::size_t size() const noexcept
Returns the number of contour edges.
Forward iterator that returns the support pixel of each edge.
std::ptrdiff_t difference_type
Signed iterator-distance type.
std::forward_iterator_tag iterator_category
Standard category for a multi-pass forward iterator.
value_type operator*() const
Returns the support pixel of the current edge.
iterator operator++(int)
Advances while retaining the previous iterator position.
iterator & operator++()
Advances to the next edge pixel.
friend bool operator==(const iterator &, const iterator &)=default
Compares the underlying edge positions.
iterator(ContourEdgeRange::iterator edgeIterator)
Creates a projection over an edge iterator.
PixelId value_type
Pixel identifier yielded by dereference.
Immutable projection of ordered contour edges onto support pixels.
iterator begin() const
Returns an iterator to the first edge pixel.
iterator end() const
Returns the exclusive end iterator.
ContourPixelRange(ContourEdgeRange edges)
Creates a support-pixel projection of an edge range.
std::size_t size() const noexcept
Returns the number of projected edge pixels, including repetitions.
bool empty() const noexcept
Returns whether the range contains no pixels.
Incremental ordered contour traces on the image domain.
Borrowed ordered contour trace for one tree node.
ContourEdgeRange edges() const noexcept
Returns every contour edge in boundary order.
std::span< const ContourBoundary > boundaries() const noexcept
Returns all ordered boundary descriptors.
ContourPixelRange boundaryPixels(const ContourBoundary &boundary) const
Returns one support pixel for each ordered boundary edge.
ContourBoundary externalBoundary() const
Returns the unique external boundary.
ContourEdgeRange boundaryEdges(const ContourBoundary &boundary) const
Returns the ordered edges of one boundary.
Independently owned ordered contour trace for one tree node.
ContourPixelRange boundaryPixels(const ContourBoundary &boundary) const
Returns one support pixel for each ordered boundary edge.
ContourEdgeRange edges() const noexcept
Returns every contour edge in boundary order.
ContourTraceView view() const noexcept
Returns a borrowed view over this owned trace.
ContourEdgeRange boundaryEdges(const ContourBoundary &boundary) const
Returns the ordered edges of one boundary.
ContourTrace(ContourTraceView trace)
Copies a borrowed trace so it can outlive its source traversal.
ContourBoundary externalBoundary() const
Returns the unique external boundary.
std::span< const ContourBoundary > boundaries() const noexcept
Returns all ordered boundary descriptors.
Owning result for one computed scalar attribute layout and buffer.
Metadata for one ordered external or internal contour boundary.
uint32_t edgeCount
Number of consecutive edges in the boundary.
ContourBoundaryKind kind
Whether this boundary is external or surrounds a hole.
int doubledSignedArea
Doubled signed area under the contour orientation convention.
uint32_t edgeOffset
First edge in the trace edge buffer.
One contour edge represented by its support pixel and side.
PixelId pixel
Row-major support-pixel index incident to the boundary edge.
ContourSide side
Side of the support pixel occupied by the boundary edge.
friend bool operator==(const ContourEdge &, const ContourEdge &)=default
Compares the support pixel and side.