3#include "AttributeComputerDomain.hpp"
4#include "AttributeComputerFamily.hpp"
5#include "../detail/AttributeKernelSupport.hpp"
6#include "detail/BitquadAttributeProjection.hpp"
7#include "detail/BitquadFiniteWindowComputation.hpp"
8#include "../../trees/TreeAltitudeAlgorithms.hpp"
9#include "../../trees/detail/MorphologicalTreeConstructionContextQueries.hpp"
10#include "../../utils/Contract.hpp"
19namespace mmcfilters::attributes::computers {
23inline void validateBitquadAdjacency(
const MorphologicalTree& tree,
bool altitudeAvailable) {
24 static_cast<void>(makeBitquadConnectivityPolicy(tree, altitudeAvailable));
27template <std::
floating_po
int Real>
inline void validateBitquadContext(
const AttributeComputeContext<Real>& context) {
28 requireAttributeBufferShape(context.tree, context.buffer, context.attrNames);
29 requireRequestedAttributeColumns(context);
30 local_attributes::detail::validateFiniteWindowLocalAttributeInput(context.tree);
31 validateBitquadAdjacency(context.tree,
false);
34template <std::
floating_po
int Real, AltitudeValue T>
inline void validateBitquadContext(
const AltitudeAttributeComputeContext<Real, T>& context) {
35 requireAttributeBufferShape(context.tree, context.buffer, context.attrNames);
36 requireRequestedAttributeColumns(context);
37 local_attributes::detail::validateFiniteWindowLocalAttributeInput(context.tree);
38 validateBitquadAdjacency(context.tree,
true);
41 const BitquadConnectivityPolicy connectivityPolicy = makeBitquadConnectivityPolicy(context.tree,
true);
42 if (!connectivityPolicy.requiresShapePolarity()) {
45 for (NodeId node : context.tree.aliveNodeIds()) {
46 static_cast<void>(shapePolarity(context.tree, context.altitude, node));
71 static constexpr std::string_view
familyName =
"bitquad";
74 static constexpr AttributeComputerFamily
family = AttributeComputerFamily::Bitquad;
77 static constexpr AttributeComputerDomain
domain = AttributeComputerDomain::Topology;
83 BitquadArea, BitquadNumberEuler, BitquadNumberHoles, BitquadPerimeter, BitquadPerimeterContinuous,
84 BitquadCircularity, BitquadPerimeterAverage, BitquadLengthAverage, BitquadWidthAverage};
99 const detail::BitquadRequest
request = detail::BitquadRequest::from(
context.requestedAttributes);
104 const std::vector<detail::BitquadFamilyCounts>
familyCounts = detail::kernel::computeBitquadFamilyCounts(
context.tree);
106 detail::BitquadAttributeProjection::materializeBitquadAttributes(
context.tree, std::span<const detail::BitquadFamilyCounts>(
familyCounts),
121 const detail::BitquadRequest
request = detail::BitquadRequest::from(
context.requestedAttributes);
126 const std::vector<detail::BitquadFamilyCounts>
familyCounts = detail::kernel::computeBitquadFamilyCounts(
context.tree);
128 detail::BitquadAttributeProjection::materializeBitquadAttributes(
context.tree,
context.altitude,
149 if (adjacency ==
nullptr) {
150 throw std::invalid_argument(
"Bitquad attributes require an adjacency relation.");
153 throw std::invalid_argument(
"Bitquad attributes require canonical 4- or 8-connectivity.");
157 auto unitValue = [&](Attribute attribute) -> Real {
162 case BitquadNumberEuler:
164 case BitquadNumberHoles:
166 case BitquadPerimeter:
168 case BitquadPerimeterContinuous:
170 case BitquadCircularity:
172 case BitquadPerimeterAverage:
174 case BitquadLengthAverage:
176 case BitquadWidthAverage:
186 case BitquadNumberEuler:
188 case BitquadNumberHoles:
190 case BitquadPerimeter:
192 case BitquadPerimeterContinuous:
193 return Real{8} / Real{3};
194 case BitquadCircularity:
195 return Real{9} * std::numbers::pi_v<Real> / Real{16};
196 case BitquadPerimeterAverage:
198 case BitquadLengthAverage:
200 case BitquadWidthAverage:
201 return static_cast<Real
>(0.75);
205 throw std::runtime_error(
"Unsupported finite-window Bitquad unit attribute.");
209 BitquadArea, BitquadNumberEuler, BitquadNumberHoles, BitquadPerimeter, BitquadPerimeterContinuous,
210 BitquadCircularity, BitquadPerimeterAverage, BitquadLengthAverage, BitquadWidthAverage};
#define MMCFILTERS_CONTRACT_CHECKED_ONLY(...)
Executes validation statements only when defensive checks are enabled.
Immutable regular-grid 2D adjacency with allocation-free traversal.
bool isCanonical4Or8Connectivity() const noexcept
Tests whether grid-topology formulas may interpret this as 4/8 connectivity.
bool is4connectivity() const noexcept
Returns true when the stencil represents canonical 4-connectivity.
static void validateNodeAltitudeBufferShape(const MorphologicalTree &tree, std::span< const T > altitude)
Validates that an altitude buffer covers the dense internal-node domain.
Bitquad scalar computer backed by finite-window computation.
static constexpr std::array< Attribute, 9 > producedAttributes
Canonical list of scalar bitquad attributes materialized by this computer.
static void computeUnitRows(const UnitAttributeComputeContext< Real > &context)
Materializes bitquad attributes for unit proper-part supports.
static constexpr AttributeComputerDomain domain
Execution domain required by the computer.
static constexpr AttributeComputerFamily family
Stable family id used by the scheduler.
static constexpr std::string_view familyName
Family name used in dependency-plan diagnostics.
static void compute(const AttributeComputeContext< Real > &context)
Computes requested scalar bitquad attributes for every live node.
static void compute(const AltitudeAttributeComputeContext< Real, T > &context)
Computes requested bitquad attributes using a generic altitude span.
Owning result for one computed scalar attribute layout and buffer.