Blender V4.3
attribute_access_intern.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
6#include "BLI_map.hh"
7#include "BLI_span.hh"
8#include "BLI_string_ref.hh"
9#include "BLI_vector.hh"
10#include "BLI_vector_set.hh"
11
12#include "BKE_geometry_set.hh"
13
14namespace blender::bke {
15
21 using CustomDataGetter = CustomData *(*)(void *owner);
22 using ConstCustomDataGetter = const CustomData *(*)(const void *owner);
23 using GetElementNum = int (*)(const void *owner);
24 using UpdateCustomDataPointers = void (*)(void *owner);
25
29};
30
38 public:
43
44 protected:
45 const std::string name_;
51
52 public:
53 BuiltinAttributeProvider(std::string name,
54 const AttrDomain domain,
56 const DeletableEnum deletable,
58 const GPointer default_value = {})
59 : name_(std::move(name)),
60 domain_(domain),
62 deletable_(deletable),
64 default_value_(default_value)
65 {
66 }
67
68 virtual GAttributeReader try_get_for_read(const void *owner) const = 0;
69 virtual GAttributeWriter try_get_for_write(void *owner) const = 0;
70 virtual bool try_delete(void *owner) const = 0;
71 virtual bool try_create(void *onwer, const AttributeInit &initializer) const = 0;
72 virtual bool exists(const void *owner) const = 0;
73
75 {
76 return name_;
77 }
78
80 {
81 return domain_;
82 }
83
85 {
86 return data_type_;
87 }
88
90 {
91 return validator_;
92 }
93};
94
100 public:
101 virtual GAttributeReader try_get_for_read(const void *owner, StringRef attribute_id) const = 0;
102 virtual GAttributeWriter try_get_for_write(void *owner, StringRef attribute_id) const = 0;
103 virtual bool try_delete(void *owner, StringRef attribute_id) const = 0;
104 virtual bool try_create(void *owner,
105 const StringRef attribute_id,
106 const AttrDomain domain,
107 const eCustomDataType data_type,
108 const AttributeInit &initializer) const
109 {
110 UNUSED_VARS(owner, attribute_id, domain, data_type, initializer);
111 /* Some providers should not create new attributes. */
112 return false;
113 };
114
118 virtual bool foreach_attribute(const void *owner,
119 FunctionRef<void(const AttributeIter &)> fn) const = 0;
120 virtual void foreach_domain(const FunctionRef<void(AttrDomain)> callback) const = 0;
121};
122
127 private:
128 static constexpr uint64_t supported_types_mask = CD_MASK_PROP_ALL;
129 AttrDomain domain_;
130 CustomDataAccessInfo custom_data_access_;
131
132 public:
134 const CustomDataAccessInfo custom_data_access)
135 : domain_(domain), custom_data_access_(custom_data_access)
136 {
137 }
138
139 GAttributeReader try_get_for_read(const void *owner, StringRef attribute_id) const final;
140
141 GAttributeWriter try_get_for_write(void *owner, StringRef attribute_id) const final;
142
143 bool try_delete(void *owner, StringRef attribute_id) const final;
144
145 bool try_create(void *owner,
146 StringRef attribute_id,
147 AttrDomain domain,
148 const eCustomDataType data_type,
149 const AttributeInit &initializer) const final;
150
151 bool foreach_attribute(const void *owner,
152 FunctionRef<void(const AttributeIter &)> fn) const final;
153
154 void foreach_domain(const FunctionRef<void(AttrDomain)> callback) const final
155 {
156 callback(domain_);
157 }
158
159 private:
160 bool type_is_supported(eCustomDataType data_type) const
161 {
162 return ((1ULL << data_type) & supported_types_mask) != 0;
163 }
164};
165
174 using UpdateOnChange = void (*)(void *owner);
175 const CustomDataAccessInfo custom_data_access_;
176 const UpdateOnChange update_on_change_;
177
178 public:
179 BuiltinCustomDataLayerProvider(std::string attribute_name,
180 const AttrDomain domain,
182 const DeletableEnum deletable,
183 const CustomDataAccessInfo custom_data_access,
184 const UpdateOnChange update_on_change,
185 const AttributeValidator validator = {},
186 const GPointer default_value = {})
188 std::move(attribute_name), domain, data_type, deletable, validator, default_value),
189 custom_data_access_(custom_data_access),
190 update_on_change_(update_on_change)
191 {
192 }
193
194 GAttributeReader try_get_for_read(const void *owner) const final;
195 GAttributeWriter try_get_for_write(void *owner) const final;
196 bool try_delete(void *owner) const final;
197 bool try_create(void *owner, const AttributeInit &initializer) const final;
198 bool exists(const void *owner) const final;
199
200 private:
201 bool layer_exists(const CustomData &custom_data) const;
202};
203
209 private:
216 Map<std::string, const BuiltinAttributeProvider *> builtin_attribute_providers_;
221 Vector<const DynamicAttributesProvider *> dynamic_attribute_providers_;
225 VectorSet<AttrDomain> supported_domains_;
226
227 public:
230 : dynamic_attribute_providers_(dynamic_attribute_providers)
231 {
233 /* Use #add_new to make sure that no two builtin attributes have the same name. */
234 builtin_attribute_providers_.add_new(provider->name(), provider);
235 supported_domains_.add(provider->domain());
236 }
238 provider->foreach_domain([&](AttrDomain domain) { supported_domains_.add(domain); });
239 }
240 }
241
243 {
244 return builtin_attribute_providers_;
245 }
246
248 {
249 return dynamic_attribute_providers_;
250 }
251
253 {
254 return supported_domains_;
255 }
256};
257
258namespace attribute_accessor_functions {
259
260template<const ComponentAttributeProviders &providers>
261inline bool is_builtin(const void * /*owner*/, const StringRef attribute_id)
262{
263 if (bke::attribute_name_is_anonymous(attribute_id)) {
264 return false;
265 }
266 const StringRef name = attribute_id;
267 return providers.builtin_attribute_providers().contains_as(name);
268}
269
270template<const ComponentAttributeProviders &providers>
271inline GAttributeReader lookup(const void *owner, const StringRef attribute_id)
272{
273 if (!bke::attribute_name_is_anonymous(attribute_id)) {
274 const StringRef name = attribute_id;
275 if (const BuiltinAttributeProvider *provider =
276 providers.builtin_attribute_providers().lookup_default_as(name, nullptr))
277 {
278 return provider->try_get_for_read(owner);
279 }
280 }
281 for (const DynamicAttributesProvider *provider : providers.dynamic_attribute_providers()) {
282 GAttributeReader attribute = provider->try_get_for_read(owner, attribute_id);
283 if (attribute) {
284 return attribute;
285 }
286 }
287 return {};
288}
289
290template<const ComponentAttributeProviders &providers>
291inline void foreach_attribute(const void *owner,
292 const FunctionRef<void(const AttributeIter &)> fn,
293 const AttributeAccessor &accessor)
294{
295 Set<StringRef, 16> handled_attribute_ids;
296 for (const BuiltinAttributeProvider *provider : providers.builtin_attribute_providers().values())
297 {
298 if (provider->exists(owner)) {
299 const auto get_fn = [&]() { return provider->try_get_for_read(owner); };
300 AttributeIter iter{provider->name(), provider->domain(), provider->data_type(), get_fn};
301 iter.is_builtin = true;
302 iter.accessor = &accessor;
303 fn(iter);
304 if (iter.is_stopped()) {
305 return;
306 }
307 handled_attribute_ids.add(iter.name);
308 }
309 }
310 for (const DynamicAttributesProvider *provider : providers.dynamic_attribute_providers()) {
311 const bool continue_loop = provider->foreach_attribute(owner, [&](const AttributeIter &iter) {
312 if (handled_attribute_ids.add(iter.name)) {
313 iter.accessor = &accessor;
314 fn(iter);
315 }
316 });
317 if (!continue_loop) {
318 return;
319 }
320 }
321}
322
323template<const ComponentAttributeProviders &providers>
324inline AttributeValidator lookup_validator(const void * /*owner*/,
325 const blender::StringRef attribute_id)
326{
327 if (bke::attribute_name_is_anonymous(attribute_id)) {
328 return {};
329 }
330 const BuiltinAttributeProvider *provider =
331 providers.builtin_attribute_providers().lookup_default_as(attribute_id, nullptr);
332 if (!provider) {
333 return {};
334 }
335 return provider->validator();
336}
337
338template<const ComponentAttributeProviders &providers>
339inline GAttributeWriter lookup_for_write(void *owner, const StringRef attribute_id)
340{
341 if (!bke::attribute_name_is_anonymous(attribute_id)) {
342 const StringRef name = attribute_id;
343 if (const BuiltinAttributeProvider *provider =
344 providers.builtin_attribute_providers().lookup_default_as(name, nullptr))
345 {
346 return provider->try_get_for_write(owner);
347 }
348 }
349 for (const DynamicAttributesProvider *provider : providers.dynamic_attribute_providers()) {
350 GAttributeWriter attribute = provider->try_get_for_write(owner, attribute_id);
351 if (attribute) {
352 return attribute;
353 }
354 }
355 return {};
356}
357
358template<const ComponentAttributeProviders &providers>
359inline bool remove(void *owner, const StringRef attribute_id)
360{
361 if (!bke::attribute_name_is_anonymous(attribute_id)) {
362 const StringRef name = attribute_id;
363 if (const BuiltinAttributeProvider *provider =
364 providers.builtin_attribute_providers().lookup_default_as(name, nullptr))
365 {
366 return provider->try_delete(owner);
367 }
368 }
369 for (const DynamicAttributesProvider *provider : providers.dynamic_attribute_providers()) {
370 if (provider->try_delete(owner, attribute_id)) {
371 return true;
372 }
373 }
374 return false;
375}
376
377template<const ComponentAttributeProviders &providers>
378inline bool add(void *owner,
379 const StringRef attribute_id,
380 AttrDomain domain,
381 eCustomDataType data_type,
382 const AttributeInit &initializer)
383{
384 if (!bke::attribute_name_is_anonymous(attribute_id)) {
385 const StringRef name = attribute_id;
386 if (const BuiltinAttributeProvider *provider =
387 providers.builtin_attribute_providers().lookup_default_as(name, nullptr))
388 {
389 if (provider->domain() != domain) {
390 return false;
391 }
392 if (provider->data_type() != data_type) {
393 return false;
394 }
395 return provider->try_create(owner, initializer);
396 }
397 }
398 for (const DynamicAttributesProvider *provider : providers.dynamic_attribute_providers()) {
399 if (provider->try_create(owner, attribute_id, domain, data_type, initializer)) {
400 return true;
401 }
402 }
403 return false;
404}
405
406template<const ComponentAttributeProviders &providers>
408{
409 return AttributeAccessorFunctions{nullptr,
410 nullptr,
413 nullptr,
417 remove<providers>,
418 add<providers>};
419}
420
421} // namespace attribute_accessor_functions
422
423} // namespace blender::bke
#define UNUSED_VARS(...)
#define CD_MASK_PROP_ALL
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between and object coordinate space Combine Create a color from its and value channels Color Retrieve a color attribute
void add_new(const Key &key, const Value &value)
Definition BLI_map.hh:241
bool add(const Key &key)
Definition BLI_set.hh:248
bool add(const Key &key)
const AttributeAccessor * accessor
virtual bool try_delete(void *owner) const =0
virtual bool try_create(void *onwer, const AttributeInit &initializer) const =0
virtual GAttributeReader try_get_for_read(const void *owner) const =0
virtual GAttributeWriter try_get_for_write(void *owner) const =0
virtual bool exists(const void *owner) const =0
BuiltinAttributeProvider(std::string name, const AttrDomain domain, const eCustomDataType data_type, const DeletableEnum deletable, AttributeValidator validator={}, const GPointer default_value={})
GAttributeWriter try_get_for_write(void *owner) const final
bool try_create(void *owner, const AttributeInit &initializer) const final
BuiltinCustomDataLayerProvider(std::string attribute_name, const AttrDomain domain, const eCustomDataType data_type, const DeletableEnum deletable, const CustomDataAccessInfo custom_data_access, const UpdateOnChange update_on_change, const AttributeValidator validator={}, const GPointer default_value={})
bool exists(const void *owner) const final
GAttributeReader try_get_for_read(const void *owner) const final
Span< const DynamicAttributesProvider * > dynamic_attribute_providers() const
const Map< std::string, const BuiltinAttributeProvider * > & builtin_attribute_providers() const
ComponentAttributeProviders(Span< const BuiltinAttributeProvider * > builtin_attribute_providers, Span< const DynamicAttributesProvider * > dynamic_attribute_providers)
GAttributeWriter try_get_for_write(void *owner, StringRef attribute_id) const final
CustomDataAttributeProvider(const AttrDomain domain, const CustomDataAccessInfo custom_data_access)
bool try_delete(void *owner, StringRef attribute_id) const final
GAttributeReader try_get_for_read(const void *owner, StringRef attribute_id) const final
bool foreach_attribute(const void *owner, FunctionRef< void(const AttributeIter &)> fn) const final
bool try_create(void *owner, StringRef attribute_id, AttrDomain domain, const eCustomDataType data_type, const AttributeInit &initializer) const final
void foreach_domain(const FunctionRef< void(AttrDomain)> callback) const final
virtual bool try_create(void *owner, const StringRef attribute_id, const AttrDomain domain, const eCustomDataType data_type, const AttributeInit &initializer) const
virtual GAttributeReader try_get_for_read(const void *owner, StringRef attribute_id) const =0
virtual GAttributeWriter try_get_for_write(void *owner, StringRef attribute_id) const =0
virtual bool try_delete(void *owner, StringRef attribute_id) const =0
virtual void foreach_domain(const FunctionRef< void(AttrDomain)> callback) const =0
virtual bool foreach_attribute(const void *owner, FunctionRef< void(const AttributeIter &)> fn) const =0
DEGForeachIDComponentCallback callback
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
AttributeAccessorFunctions accessor_functions_for_providers()
bool is_builtin(const void *, const StringRef attribute_id)
AttributeValidator lookup_validator(const void *, const blender::StringRef attribute_id)
bool remove(void *owner, const StringRef attribute_id)
GAttributeReader lookup(const void *owner, const StringRef attribute_id)
void foreach_attribute(const void *owner, const FunctionRef< void(const AttributeIter &)> fn, const AttributeAccessor &accessor)
GAttributeWriter lookup_for_write(void *owner, const StringRef attribute_id)
bool add(void *owner, const StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const AttributeInit &initializer)
bool attribute_name_is_anonymous(const StringRef name)
unsigned __int64 uint64_t
Definition stdint.h:90
CustomData *(*)(void *owner) CustomDataGetter
const CustomData *(*)(const void *owner) ConstCustomDataGetter