mmcfilters
Public API documentation
Loading...
Searching...
No Matches
ValuedMorphologicalTreeView.hpp
1#pragma once
2
3#include "MorphologicalTree.hpp"
4#include "TreeAltitudeAlgorithms.hpp"
5#include "../utils/Altitude.hpp"
6#include "../utils/Contract.hpp"
7
8#include <cstddef>
9#include <span>
10#include <stdexcept>
11
12namespace mmcfilters {
13
14template <AltitudeValue T> class ValuedMorphologicalTree;
15
30template <AltitudeValue T> class ValuedMorphologicalTreeView {
31 friend class ValuedMorphologicalTree<T>;
32
33 private:
35 const MorphologicalTree* topology_ = nullptr;
37 NodeAltitudeSpan<T> nodeAltitudes_;
39 std::size_t topologyMutationVersion_ = 0;
40
44 void validateNodeAltitudeBufferShape() const {
45 MMCFILTERS_CONTRACT_REQUIRE(nodeAltitudes_.size() == static_cast<std::size_t>(topology_->numInternalNodeSlots()),
46 throw std::runtime_error("ValuedMorphologicalTreeView altitude size must match the dense internal-node domain."));
47 }
48
54 : topology_(&owner.topology()), nodeAltitudes_(owner.nodeAltitudeSpan()), topologyMutationVersion_(owner.topology().getMutationVersion()) {}
55
56 public:
58 using AltitudeType = T;
59
71 : topology_(&topology), nodeAltitudes_(altitude), topologyMutationVersion_(topology.getMutationVersion()) {
72 validateNodeAltitudeBufferShape();
73 TreeAltitudeAlgorithms::validateFiniteAltitudeValues(altitude, "ValuedMorphologicalTreeView");
75 }
76
88
93
99 [[nodiscard]] const MorphologicalTree& topology() const noexcept { return *topology_; }
100
107
113 void requireTopologyUnchanged(const char* context) const { topology().requireMutationVersion(topologyMutationVersion_, context); }
114
121 [[nodiscard]] T nodeAltitude(NodeId nodeId) const {
122 MMCFILTERS_CONTRACT_REQUIRE(nodeId >= 0 && static_cast<std::size_t>(nodeId) < nodeAltitudes_.size(),
123 throw std::invalid_argument("ValuedMorphologicalTreeView::nodeAltitude requires a valid internal NodeId."));
124 return nodeAltitudes_[static_cast<std::size_t>(nodeId)];
125 }
126
138 const MorphologicalTree& tree = topology();
139 MMCFILTERS_CONTRACT_REQUIRE(tree.isAlive(nodeId), throw std::invalid_argument("ValuedMorphologicalTreeView::nodeResidue requires a live internal NodeId."));
140 const NodeId parentNodeId = tree.parent(nodeId);
141 if (parentNodeId == InvalidNode || parentNodeId == nodeId) {
142 return static_cast<AltitudeDifference<T>>(nodeAltitude(nodeId));
143 }
144 return static_cast<AltitudeDifference<T>>(nodeAltitude(nodeId)) - static_cast<AltitudeDifference<T>>(nodeAltitude(parentNodeId));
145 }
146};
147
148} // namespace mmcfilters
constexpr NodeId InvalidNode
Sentinel value used to denote an invalid node identifier.
Definition Common.hpp:34
#define MMCFILTERS_CONTRACT_REQUIRE(condition,...)
Evaluates a caller precondition and its failure action only in checked builds.
Definition Contract.hpp:53
Mutable connected-subset tree on a finite pixel domain.
int numInternalNodeSlots() const
Returns the size of the dense internal-node id domain.
bool isAlive(NodeId nodeId) const
Tests whether a node slot currently represents a live node.
NodeId parent(NodeId nodeId) const
Returns the direct parent of nodeId.
static void validateMonotoneNodeAltitudes(const MorphologicalTree &tree, std::span< const T > altitude)
Validates the hierarchy's declared global altitude order.
static void validateFiniteAltitudeValues(std::span< const T > altitude, const char *context)
Rejects non-finite floating-point altitudes in a contiguous input range.
Non-owning view pairing a topology with an external altitude span.
AltitudeDifference< T > nodeResidue(NodeId nodeId) const
Returns the altitude difference between a live node and its parent.
const MorphologicalTree & topology() const noexcept
Returns the borrowed tree topology.
T nodeAltitude(NodeId nodeId) const
Returns the altitude associated with an internal node id.
ValuedMorphologicalTreeView(const MorphologicalTree &topology, const NodeAltitudeBuffer< T > &altitude)
Builds a view over a caller-owned altitude buffer.
NodeAltitudeSpan< T > nodeAltitudes() const noexcept
Returns the borrowed altitude span indexed by internal NodeId.
T AltitudeType
Altitude scalar type borrowed by this view.
ValuedMorphologicalTreeView(const MorphologicalTree &, NodeAltitudeBuffer< T > &&)=delete
Rejects temporary altitude buffers that would leave a dangling span.
void requireTopologyUnchanged(const char *context) const
Throws if the borrowed topology changed since view construction.
ValuedMorphologicalTreeView(const MorphologicalTree &topology, NodeAltitudeSpan< T > altitude)
Builds a view over caller-owned topology and altitude storage.
Wrapper pairing MorphologicalTree topology with an external altitude buffer.
Owning result for one computed scalar attribute layout and buffer.