Blender  V2.93
attribute_access_intern.hh
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
17 #include "BLI_map.hh"
18 #include "BLI_span.hh"
19 #include "BLI_string_ref.hh"
20 #include "BLI_vector.hh"
21 #include "BLI_vector_set.hh"
22 
23 #include "BKE_geometry_set.hh"
24 
25 namespace blender::bke {
26 
28  private:
29  void *value_;
30 
31  public:
33  const int64_t size,
34  const CPPType &type,
35  const void *value)
37  {
38  value_ = MEM_mallocN_aligned(type.size(), type.alignment(), __func__);
39  type.copy_to_uninitialized(value, value_);
40  }
41 
43  {
44  this->cpp_type_.destruct(value_);
45  MEM_freeN(value_);
46  }
47 
48  void get_internal(const int64_t UNUSED(index), void *r_value) const override
49  {
50  this->cpp_type_.copy_to_uninitialized(value_, r_value);
51  }
52 
53  void initialize_span() const override
54  {
55  const int element_size = cpp_type_.size();
56  array_buffer_ = MEM_mallocN_aligned(size_ * element_size, cpp_type_.alignment(), __func__);
57  array_is_temporary_ = true;
59  }
60 };
61 
62 template<typename T> class ArrayReadAttribute final : public ReadAttribute {
63  private:
64  Span<T> data_;
65 
66  public:
69  {
70  }
71 
72  void get_internal(const int64_t index, void *r_value) const override
73  {
74  new (r_value) T(data_[index]);
75  }
76 
77  void initialize_span() const override
78  {
79  /* The data will not be modified, so this const_cast is fine. */
80  array_buffer_ = const_cast<T *>(data_.data());
81  array_is_temporary_ = false;
82  }
83 };
84 
85 template<typename T> class OwnedArrayReadAttribute final : public ReadAttribute {
86  private:
87  Array<T> data_;
88 
89  public:
91  : ReadAttribute(domain, CPPType::get<T>(), data.size()), data_(std::move(data))
92  {
93  }
94 
95  void get_internal(const int64_t index, void *r_value) const override
96  {
97  new (r_value) T(data_[index]);
98  }
99 
100  void initialize_span() const override
101  {
102  /* The data will not be modified, so this const_cast is fine. */
103  array_buffer_ = const_cast<T *>(data_.data());
104  array_is_temporary_ = false;
105  }
106 };
107 
108 template<typename StructT, typename ElemT, ElemT (*GetFunc)(const StructT &)>
110  private:
111  Span<StructT> data_;
112 
113  public:
115  : ReadAttribute(domain, CPPType::get<ElemT>(), data.size()), data_(data)
116  {
117  }
118 
119  void get_internal(const int64_t index, void *r_value) const override
120  {
121  const StructT &struct_value = data_[index];
122  const ElemT value = GetFunc(struct_value);
123  new (r_value) ElemT(value);
124  }
125 };
126 
127 template<typename T> class ArrayWriteAttribute final : public WriteAttribute {
128  private:
129  MutableSpan<T> data_;
130 
131  public:
134  {
135  }
136 
137  void get_internal(const int64_t index, void *r_value) const override
138  {
139  new (r_value) T(data_[index]);
140  }
141 
142  void set_internal(const int64_t index, const void *value) override
143  {
144  data_[index] = *reinterpret_cast<const T *>(value);
145  }
146 
147  void initialize_span(const bool UNUSED(write_only)) override
148  {
149  array_buffer_ = data_.data();
150  array_is_temporary_ = false;
151  }
152 
153  void apply_span_if_necessary() override
154  {
155  /* Do nothing, because the span contains the attribute itself already. */
156  }
157 };
158 
159 template<typename StructT,
160  typename ElemT,
161  ElemT (*GetFunc)(const StructT &),
162  void (*SetFunc)(StructT &, const ElemT &)>
164  private:
166 
167  public:
169  : WriteAttribute(domain, CPPType::get<ElemT>(), data.size()), data_(data)
170  {
171  }
172 
173  void get_internal(const int64_t index, void *r_value) const override
174  {
175  const StructT &struct_value = data_[index];
176  const ElemT value = GetFunc(struct_value);
177  new (r_value) ElemT(value);
178  }
179 
180  void set_internal(const int64_t index, const void *value) override
181  {
182  StructT &struct_value = data_[index];
183  const ElemT &typed_value = *reinterpret_cast<const ElemT *>(value);
184  SetFunc(struct_value, typed_value);
185  }
186 };
187 
196 
200 };
201 
208  public:
209  /* Some utility enums to avoid hard to read booleans in function calls. */
213  };
217  };
221  };
222 
223  protected:
224  const std::string name_;
230 
231  public:
232  BuiltinAttributeProvider(std::string name,
233  const AttributeDomain domain,
234  const CustomDataType data_type,
235  const CreatableEnum createable,
236  const WritableEnum writable,
237  const DeletableEnum deletable)
238  : name_(std::move(name)),
239  domain_(domain),
240  data_type_(data_type),
241  createable_(createable),
242  writable_(writable),
243  deletable_(deletable)
244  {
245  }
246 
249  virtual bool try_delete(GeometryComponent &component) const = 0;
250  virtual bool try_create(GeometryComponent &UNUSED(component)) const = 0;
251  virtual bool exists(const GeometryComponent &component) const = 0;
252 
254  {
255  return name_;
256  }
257 
259  {
260  return domain_;
261  }
262 
264  {
265  return data_type_;
266  }
267 };
268 
274  public:
276  const StringRef attribute_name) const = 0;
278  const StringRef attribute_name) const = 0;
279  virtual bool try_delete(GeometryComponent &component, const StringRef attribute_name) const = 0;
281  const StringRef UNUSED(attribute_name),
282  const AttributeDomain UNUSED(domain),
283  const CustomDataType UNUSED(data_type)) const
284  {
285  /* Some providers should not create new attributes. */
286  return false;
287  };
288 
290  const AttributeForeachCallback callback) const = 0;
291  virtual void foreach_domain(const FunctionRef<void(AttributeDomain)> callback) const = 0;
292 };
293 
298  private:
299  static constexpr uint64_t supported_types_mask = CD_MASK_PROP_FLOAT | CD_MASK_PROP_FLOAT2 |
302  const AttributeDomain domain_;
303  const CustomDataAccessInfo custom_data_access_;
304 
305  public:
307  const CustomDataAccessInfo custom_data_access)
308  : domain_(domain), custom_data_access_(custom_data_access)
309  {
310  }
311 
312  ReadAttributePtr try_get_for_read(const GeometryComponent &component,
313  const StringRef attribute_name) const final;
314 
315  WriteAttributePtr try_get_for_write(GeometryComponent &component,
316  const StringRef attribute_name) const final;
317 
318  bool try_delete(GeometryComponent &component, const StringRef attribute_name) const final;
319 
320  bool try_create(GeometryComponent &component,
321  const StringRef attribute_name,
322  const AttributeDomain domain,
323  const CustomDataType data_type) const final;
324 
325  bool foreach_attribute(const GeometryComponent &component,
326  const AttributeForeachCallback callback) const final;
327 
328  void foreach_domain(const FunctionRef<void(AttributeDomain)> callback) const final
329  {
330  callback(domain_);
331  }
332 
333  private:
334  template<typename T>
335  ReadAttributePtr layer_to_read_attribute(const CustomDataLayer &layer,
336  const int domain_size) const
337  {
338  return std::make_unique<ArrayReadAttribute<T>>(
339  domain_, Span(static_cast<const T *>(layer.data), domain_size));
340  }
341 
342  template<typename T>
343  WriteAttributePtr layer_to_write_attribute(CustomDataLayer &layer, const int domain_size) const
344  {
345  return std::make_unique<ArrayWriteAttribute<T>>(
346  domain_, MutableSpan(static_cast<T *>(layer.data), domain_size));
347  }
348 
349  bool type_is_supported(CustomDataType data_type) const
350  {
351  return ((1ULL << data_type) & supported_types_mask) != 0;
352  }
353 };
354 
359  private:
360  using AsReadAttribute = ReadAttributePtr (*)(const void *data, const int domain_size);
361  using AsWriteAttribute = WriteAttributePtr (*)(void *data, const int domain_size);
362  const AttributeDomain domain_;
363  const CustomDataType attribute_type_;
364  const CustomDataType stored_type_;
365  const CustomDataAccessInfo custom_data_access_;
366  const AsReadAttribute as_read_attribute_;
367  const AsWriteAttribute as_write_attribute_;
368 
369  public:
371  const CustomDataType attribute_type,
372  const CustomDataType stored_type,
373  const CustomDataAccessInfo custom_data_access,
374  const AsReadAttribute as_read_attribute,
375  const AsWriteAttribute as_write_attribute)
376  : domain_(domain),
377  attribute_type_(attribute_type),
378  stored_type_(stored_type),
379  custom_data_access_(custom_data_access),
380  as_read_attribute_(as_read_attribute),
381  as_write_attribute_(as_write_attribute)
382  {
383  }
384 
386  const StringRef attribute_name) const final;
388  const StringRef attribute_name) const final;
389  bool try_delete(GeometryComponent &component, const StringRef attribute_name) const final;
391  const AttributeForeachCallback callback) const final;
392  void foreach_domain(const FunctionRef<void(AttributeDomain)> callback) const final;
393 };
394 
401  using AsReadAttribute = ReadAttributePtr (*)(const void *data, const int domain_size);
402  using AsWriteAttribute = WriteAttributePtr (*)(void *data, const int domain_size);
403  using UpdateOnRead = void (*)(const GeometryComponent &component);
404  using UpdateOnWrite = void (*)(GeometryComponent &component);
405  const CustomDataType stored_type_;
406  const CustomDataAccessInfo custom_data_access_;
407  const AsReadAttribute as_read_attribute_;
408  const AsWriteAttribute as_write_attribute_;
409  const UpdateOnWrite update_on_write_;
410 
411  public:
412  BuiltinCustomDataLayerProvider(std::string attribute_name,
413  const AttributeDomain domain,
414  const CustomDataType attribute_type,
415  const CustomDataType stored_type,
416  const CreatableEnum creatable,
417  const WritableEnum writable,
418  const DeletableEnum deletable,
419  const CustomDataAccessInfo custom_data_access,
420  const AsReadAttribute as_read_attribute,
421  const AsWriteAttribute as_write_attribute,
422  const UpdateOnWrite update_on_write)
424  std::move(attribute_name), domain, attribute_type, creatable, writable, deletable),
425  stored_type_(stored_type),
426  custom_data_access_(custom_data_access),
427  as_read_attribute_(as_read_attribute),
428  as_write_attribute_(as_write_attribute),
429  update_on_write_(update_on_write)
430  {
431  }
432 
435  bool try_delete(GeometryComponent &component) const final;
436  bool try_create(GeometryComponent &component) const final;
437  bool exists(const GeometryComponent &component) const final;
438 };
439 
445  private:
452  Map<std::string, const BuiltinAttributeProvider *> builtin_attribute_providers_;
457  Vector<const DynamicAttributesProvider *> dynamic_attribute_providers_;
461  VectorSet<AttributeDomain> supported_domains_;
462 
463  public:
466  : dynamic_attribute_providers_(dynamic_attribute_providers)
467  {
468  for (const BuiltinAttributeProvider *provider : builtin_attribute_providers) {
469  /* Use #add_new to make sure that no two builtin attributes have the same name. */
470  builtin_attribute_providers_.add_new(provider->name(), provider);
471  supported_domains_.add(provider->domain());
472  }
474  provider->foreach_domain([&](AttributeDomain domain) { supported_domains_.add(domain); });
475  }
476  }
477 
479  {
480  return builtin_attribute_providers_;
481  }
482 
484  {
485  return dynamic_attribute_providers_;
486  }
487 
489  {
490  return supported_domains_;
491  }
492 };
493 
494 } // namespace blender::bke
AttributeDomain
Definition: BKE_attribute.h:41
#define final(a, b, c)
Definition: BLI_hash.h:35
#define UNUSED(x)
static uint8 component(Color32 c, uint i)
Definition: ColorBlock.cpp:126
#define CD_MASK_PROP_COLOR
#define CD_MASK_PROP_FLOAT3
CustomDataType
#define CD_MASK_PROP_FLOAT2
#define CD_MASK_PROP_BOOL
#define CD_MASK_PROP_INT32
#define CD_MASK_PROP_FLOAT
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
void add_new(const Key &key, const Value &value)
Definition: BLI_map.hh:234
bool add(const Key &key)
ArrayReadAttribute(AttributeDomain domain, Span< T > data)
void get_internal(const int64_t index, void *r_value) const override
ArrayWriteAttribute(AttributeDomain domain, MutableSpan< T > data)
void get_internal(const int64_t index, void *r_value) const override
void initialize_span(const bool UNUSED(write_only)) override
void set_internal(const int64_t index, const void *value) override
virtual bool try_create(GeometryComponent &UNUSED(component)) const =0
virtual WriteAttributePtr try_get_for_write(GeometryComponent &component) const =0
BuiltinAttributeProvider(std::string name, const AttributeDomain domain, const CustomDataType data_type, const CreatableEnum createable, const WritableEnum writable, const DeletableEnum deletable)
virtual bool exists(const GeometryComponent &component) const =0
virtual ReadAttributePtr try_get_for_read(const GeometryComponent &component) const =0
virtual bool try_delete(GeometryComponent &component) const =0
bool exists(const GeometryComponent &component) const final
WriteAttributePtr try_get_for_write(GeometryComponent &component) const final
bool try_create(GeometryComponent &component) const final
BuiltinCustomDataLayerProvider(std::string attribute_name, const AttributeDomain domain, const CustomDataType attribute_type, const CustomDataType stored_type, const CreatableEnum creatable, const WritableEnum writable, const DeletableEnum deletable, const CustomDataAccessInfo custom_data_access, const AsReadAttribute as_read_attribute, const AsWriteAttribute as_write_attribute, const UpdateOnWrite update_on_write)
bool try_delete(GeometryComponent &component) const final
ReadAttributePtr try_get_for_read(const GeometryComponent &component) const final
Span< const DynamicAttributesProvider * > dynamic_attribute_providers() const
const Map< std::string, const BuiltinAttributeProvider * > & builtin_attribute_providers() const
Span< AttributeDomain > supported_domains() const
ComponentAttributeProviders(Span< const BuiltinAttributeProvider * > builtin_attribute_providers, Span< const DynamicAttributesProvider * > dynamic_attribute_providers)
void get_internal(const int64_t UNUSED(index), void *r_value) const override
ConstantReadAttribute(AttributeDomain domain, const int64_t size, const CPPType &type, const void *value)
void foreach_domain(const FunctionRef< void(AttributeDomain)> callback) const final
CustomDataAttributeProvider(const AttributeDomain domain, const CustomDataAccessInfo custom_data_access)
void get_internal(const int64_t index, void *r_value) const override
DerivedArrayReadAttribute(AttributeDomain domain, Span< StructT > data)
DerivedArrayWriteAttribute(AttributeDomain domain, MutableSpan< StructT > data)
void set_internal(const int64_t index, const void *value) override
void get_internal(const int64_t index, void *r_value) const override
virtual bool try_create(GeometryComponent &UNUSED(component), const StringRef UNUSED(attribute_name), const AttributeDomain UNUSED(domain), const CustomDataType UNUSED(data_type)) const
virtual void foreach_domain(const FunctionRef< void(AttributeDomain)> callback) const =0
virtual bool foreach_attribute(const GeometryComponent &component, const AttributeForeachCallback callback) const =0
virtual ReadAttributePtr try_get_for_read(const GeometryComponent &component, const StringRef attribute_name) const =0
virtual WriteAttributePtr try_get_for_write(GeometryComponent &component, const StringRef attribute_name) const =0
virtual bool try_delete(GeometryComponent &component, const StringRef attribute_name) const =0
bool try_delete(GeometryComponent &component, const StringRef attribute_name) const final
ReadAttributePtr try_get_for_read(const GeometryComponent &component, const StringRef attribute_name) const final
void foreach_domain(const FunctionRef< void(AttributeDomain)> callback) const final
WriteAttributePtr try_get_for_write(GeometryComponent &component, const StringRef attribute_name) const final
NamedLegacyCustomDataProvider(const AttributeDomain domain, const CustomDataType attribute_type, const CustomDataType stored_type, const CustomDataAccessInfo custom_data_access, const AsReadAttribute as_read_attribute, const AsWriteAttribute as_write_attribute)
bool foreach_attribute(const GeometryComponent &component, const AttributeForeachCallback callback) const final
void get_internal(const int64_t index, void *r_value) const override
OwnedArrayReadAttribute(AttributeDomain domain, Array< T > data)
void get(const int64_t index, void *r_value) const
AttributeDomain domain() const
AttributeDomain domain() const
void get(const int64_t index, void *r_value) const
int64_t size() const
Definition: FN_cpp_type.hh:280
int64_t alignment() const
Definition: FN_cpp_type.hh:291
void destruct(void *ptr) const
Definition: FN_cpp_type.hh:358
void fill_uninitialized(const void *value, void *dst, int64_t n) const
Definition: FN_cpp_type.hh:618
void copy_to_uninitialized(const void *src, void *dst) const
Definition: FN_cpp_type.hh:425
DEGForeachIDComponentCallback callback
T * data_
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_mallocN_aligned)(size_t len, size_t alignment, const char *str)
Definition: mallocn.c:49
#define T
std::unique_ptr< WriteAttribute > WriteAttributePtr
std::unique_ptr< ReadAttribute > ReadAttributePtr
__int64 int64_t
Definition: stdint.h:92
unsigned __int64 uint64_t
Definition: stdint.h:93
void(*)(GeometryComponent &component) UpdateCustomDataPointers
UpdateCustomDataPointers update_custom_data_pointers
const CustomData *(*)(const GeometryComponent &component) ConstCustomDataGetter
CustomData *(*)(GeometryComponent &component) CustomDataGetter