mmcfilters
Public API documentation
Loading...
Searching...
No Matches
AttributeNames.hpp
1#pragma once
2
3#include "AttributeRegistry.hpp"
4#include "AttributeTypes.hpp"
5#include "../utils/Contract.hpp"
6
7#include <optional>
8#include <stdexcept>
9#include <string>
10#include <unordered_map>
11#include <vector>
12
13namespace mmcfilters {
22inline const std::unordered_map<AttributeGroup, std::vector<Attribute>>& ATTRIBUTE_GROUPS = attributes::registry::attributeGroups();
23
33 public:
35 std::unordered_map<NodeAttributeSampleKey, int> indexMap;
36
38 const int NUM_ATTRIBUTES;
39
48 NodeAttributeSampleLayout(std::unordered_map<NodeAttributeSampleKey, int>&& map)
50
58 [[nodiscard]] static NodeAttributeSampleLayout create(int samplingRadius, const std::vector<Attribute>& attributes) {
59 std::unordered_map<NodeAttributeSampleKey, int> map;
60 int offset = 0;
61 for (int sampleOffset = -samplingRadius; sampleOffset <= samplingRadius; ++sampleOffset) {
62 for (std::size_t i = 0; i < attributes.size(); ++i) {
63 const NodeAttributeSampleKey key{attributes[i], sampleOffset};
64 const auto [_, inserted] = map.emplace(key, offset++);
66 inserted, throw std::invalid_argument("NodeAttributeSampleLayout::create received duplicate attribute " + toString(key)));
67 }
68 }
69 return NodeAttributeSampleLayout(std::move(map));
70 }
71
79 [[nodiscard]] int getIndex(Attribute attribute, int sampleOffset) const {
80 return getIndex(NodeAttributeSampleKey{attribute, sampleOffset});
81 }
82
90
100 [[nodiscard]] int linearIndex(int nodeIndex, Attribute attribute, int sampleOffset) const {
101 return nodeIndex * NUM_ATTRIBUTES + getIndex(attribute, sampleOffset);
102 }
103
112 return linearIndex(nodeIndex, sampleKey.attribute, sampleKey.sampleOffset);
113 }
114
122 return toString(sampleKey.attribute, sampleKey.sampleOffset);
123 }
124
132 [[nodiscard]] static std::string toString(Attribute attribute, int sampleOffset) {
133 std::string name(attributes::registry::name(attribute));
134
135 if (sampleOffset < 0) {
136 name += "_ANCESTOR_" + std::to_string(-sampleOffset);
137 } else if (sampleOffset > 0) {
138 name += "_DESCENDANT_" + std::to_string(sampleOffset);
139 }
140
141 return name;
142 }
143};
144
163 public:
165 std::unordered_map<Attribute, int> indexMap;
166
168 const int NUM_ATTRIBUTES;
169
178 AttributeNames(std::unordered_map<Attribute, int>&& map) : indexMap(std::move(map)), NUM_ATTRIBUTES(static_cast<int>(indexMap.size())) {}
179
189 [[nodiscard]] static AttributeNames fromList(const std::vector<Attribute>& attributes) {
190 std::unordered_map<Attribute, int> map;
191 int i = 0;
192 for (auto attr : attributes) {
193 const auto [_, inserted] = map.emplace(attr, i++);
195 throw std::invalid_argument("AttributeNames::fromList received duplicate attribute " + toString(attr)));
196 }
197 return AttributeNames(std::move(map));
198 }
199
206 [[nodiscard]] static AttributeNames fromGroup(AttributeGroup group) {
207 auto it = ATTRIBUTE_GROUPS.find(group);
208 MMCFILTERS_CONTRACT_REQUIRE(it != ATTRIBUTE_GROUPS.end(), throw std::invalid_argument("Unknown attribute group."));
209 return fromList(it->second);
210 }
211
218 [[nodiscard]] int getIndex(Attribute attr) const { return indexMap.at(attr); }
219
226 [[nodiscard]] bool contains(Attribute attr) const noexcept { return indexMap.contains(attr); }
227
234 [[nodiscard]] int offset(Attribute attr) const { return getIndex(attr); }
235
243 [[nodiscard]] int linearIndex(int nodeIndex, Attribute attr) const { return nodeIndex * NUM_ATTRIBUTES + getIndex(attr); }
244
251 [[nodiscard]] static std::string toString(Attribute attr) { return std::string(attributes::registry::name(attr)); }
252
263 static std::string describe(Attribute attr) { return std::string(attributes::registry::description(attr)); }
264
273 [[nodiscard]] static std::optional<Attribute> parse(const std::string& str) { return attributes::registry::parse(str); }
274};
275
276} // namespace mmcfilters
#define MMCFILTERS_CONTRACT_REQUIRE(condition,...)
Evaluates a caller precondition and its failure action only in checked builds.
Definition Contract.hpp:53
Layout object that maps scalar attributes to flat-buffer offsets.
static std::string describe(Attribute attr)
Returns a user-facing description of an attribute.
static std::string toString(Attribute attr)
Returns the stable symbolic name associated with attr.
static AttributeNames fromList(const std::vector< Attribute > &attributes)
Builds a dense layout from an explicit attribute list.
static AttributeNames fromGroup(AttributeGroup group)
Builds a layout from a public attribute group.
int getIndex(Attribute attr) const
Returns the per-node offset associated with attr.
static std::optional< Attribute > parse(const std::string &str)
Parses a stable symbolic attribute name.
int linearIndex(int nodeIndex, Attribute attr) const
Returns the linear index in the flat buffer for (node, attr).
const int NUM_ATTRIBUTES
Number of scalar attributes stored for each node.
int offset(Attribute attr) const
Returns the per-node offset associated with attr.
AttributeNames(std::unordered_map< Attribute, int > &&map)
Constructs a layout from an already validated offset map.
std::unordered_map< Attribute, int > indexMap
Maps each requested attribute to its per-node offset.
bool contains(Attribute attr) const noexcept
Returns whether this layout contains attr.
Layout for node attributes sampled at signed ancestor/current/descendant offsets.
const int NUM_ATTRIBUTES
Number of sampled entries stored for each node.
static NodeAttributeSampleLayout create(int samplingRadius, const std::vector< Attribute > &attributes)
Builds the canonical dense layout for offsets in [-samplingRadius, samplingRadius].
int getIndex(NodeAttributeSampleKey sampleKey) const
Returns the per-node offset associated with a composite sample key.
std::unordered_map< NodeAttributeSampleKey, int > indexMap
Maps each (attribute, sampleOffset) key to its per-node offset.
int getIndex(Attribute attribute, int sampleOffset) const
Returns the per-node offset associated with (attribute, sampleOffset).
NodeAttributeSampleLayout(std::unordered_map< NodeAttributeSampleKey, int > &&map)
Constructs a layout from an already validated offset map.
static std::string toString(Attribute attribute, int sampleOffset)
Returns a serialized label for an attribute at a sample offset.
static std::string toString(NodeAttributeSampleKey sampleKey)
Returns a human-readable label for a composite key.
int linearIndex(int nodeIndex, NodeAttributeSampleKey sampleKey) const
Convenience overload taking a NodeAttributeSampleKey.
int linearIndex(int nodeIndex, Attribute attribute, int sampleOffset) const
Returns the linear index in the flat buffer for a given node and sampled attribute.
Owning result for one computed scalar attribute layout and buffer.
std::vector< Real > second
Flat per-node attribute buffer indexed through first.
Composite key used to index sampled node-attribute layouts.