Blender  V3.3
BKE_geometry_set.hh
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #pragma once
4 
9 #include <atomic>
10 #include <iostream>
11 #include <mutex>
12 
13 #include "BLI_float4x4.hh"
14 #include "BLI_function_ref.hh"
15 #include "BLI_hash.hh"
16 #include "BLI_map.hh"
17 #include "BLI_math_vec_types.hh"
18 #include "BLI_set.hh"
19 #include "BLI_user_counter.hh"
20 #include "BLI_vector_set.hh"
21 
23 #include "BKE_attribute.hh"
24 #include "BKE_geometry_set.h"
25 
26 struct Curves;
27 struct Collection;
28 struct Curve;
29 struct CurveEval;
30 struct Mesh;
31 struct Object;
32 struct PointCloud;
33 struct Volume;
34 
36  /* The geometry is owned. This implies that it can be changed. */
37  Owned = 0,
38  /* The geometry can be changed, but someone else is responsible for freeing it. */
39  Editable = 1,
40  /* The geometry cannot be changed and someone else is responsible for freeing it. */
41  ReadOnly = 2,
42 };
43 
44 namespace blender::bke {
45 class ComponentAttributeProviders;
46 class CurvesEditHints;
47 } // namespace blender::bke
48 
49 class GeometryComponent;
50 
57  private:
58  /* The reference count has two purposes. When it becomes zero, the component is freed. When it is
59  * larger than one, the component becomes immutable. */
60  mutable std::atomic<int> users_ = 1;
62 
63  public:
65  virtual ~GeometryComponent() = default;
66  static GeometryComponent *create(GeometryComponentType component_type);
67 
68  int attribute_domain_size(eAttrDomain domain) const;
69 
74  virtual std::optional<blender::bke::AttributeAccessor> attributes() const;
75  virtual std::optional<blender::bke::MutableAttributeAccessor> attributes_for_write();
76 
77  /* The returned component should be of the same type as the type this is called on. */
78  virtual GeometryComponent *copy() const = 0;
79 
80  /* Direct data is everything except for instances of objects/collections.
81  * If this returns true, the geometry set can be cached and is still valid after e.g. modifier
82  * evaluation ends. Instances can only be valid as long as the data they instance is valid. */
83  virtual bool owns_direct_data() const = 0;
84  virtual void ensure_owns_direct_data() = 0;
85 
86  void user_add() const;
87  void user_remove() const;
88  bool is_mutable() const;
89 
91 
92  virtual bool is_empty() const;
93 };
94 
95 template<typename T>
96 inline constexpr bool is_geometry_component_v = std::is_base_of_v<GeometryComponent, T>;
97 
116 struct GeometrySet {
117  private:
119  /* Indexed by #GeometryComponentType. */
120  std::array<GeometryComponentPtr, GEO_COMPONENT_TYPE_ENUM_SIZE> components_;
121 
122  public:
127  GeometrySet(const GeometrySet &other);
132 
138  template<typename Component> Component &get_component_for_write()
139  {
140  BLI_STATIC_ASSERT(is_geometry_component_v<Component>, "");
141  return static_cast<Component &>(this->get_component_for_write(Component::static_type));
142  }
143 
148  template<typename Component> const Component *get_component_for_read() const
149  {
150  BLI_STATIC_ASSERT(is_geometry_component_v<Component>, "");
151  return static_cast<const Component *>(get_component_for_read(Component::static_type));
152  }
153 
154  bool has(const GeometryComponentType component_type) const;
155  template<typename Component> bool has() const
156  {
157  BLI_STATIC_ASSERT(is_geometry_component_v<Component>, "");
158  return this->has(Component::static_type);
159  }
160 
161  void remove(const GeometryComponentType component_type);
162  template<typename Component> void remove()
163  {
164  BLI_STATIC_ASSERT(is_geometry_component_v<Component>, "");
165  return this->remove(Component::static_type);
166  }
167 
171  void keep_only(const blender::Span<GeometryComponentType> component_types);
178 
179  void add(const GeometryComponent &component);
180 
185 
187 
188  friend std::ostream &operator<<(std::ostream &stream, const GeometrySet &geometry_set);
189 
193  void clear();
194 
195  bool owns_direct_data() const;
202 
205  const blender::bke::AttributeMetaData &meta_data,
206  const GeometryComponent &component)>;
207 
209  bool include_instances,
211 
213  blender::Span<GeometryComponentType> component_types,
214  GeometryComponentType dst_component_type,
215  bool include_instances,
217 
219  bool ignore_empty) const;
220 
222 
228 
229  /* Utility methods for creation. */
250 
251  /* Utility methods for access. */
255  bool has_mesh() const;
259  bool has_pointcloud() const;
263  bool has_instances() const;
267  bool has_volume() const;
271  bool has_curves() const;
275  bool has_realized_data() const;
279  bool is_empty() const;
280 
284  const Mesh *get_mesh_for_read() const;
288  const PointCloud *get_pointcloud_for_read() const;
292  const Volume *get_volume_for_read() const;
296  const Curves *get_curves_for_read() const;
301 
322 
323  /* Utility methods for replacement. */
331  void replace_pointcloud(PointCloud *pointcloud,
336  void replace_volume(Volume *volume,
343 
344  private:
349  GeometryComponent *get_component_ptr(GeometryComponentType type);
350  template<typename Component> Component *get_component_ptr()
351  {
352  BLI_STATIC_ASSERT(is_geometry_component_v<Component>, "");
353  return static_cast<Component *>(get_component_ptr(Component::static_type));
354  }
355 };
356 
365  private:
366  Mesh *mesh_ = nullptr;
368 
369  public:
370  MeshComponent();
371  ~MeshComponent();
372  GeometryComponent *copy() const override;
373 
374  void clear();
375  bool has_mesh() const;
384  Mesh *release();
385 
390  const Mesh *get_for_read() const;
395  Mesh *get_for_write();
396 
397  bool is_empty() const final;
398 
399  bool owns_direct_data() const override;
400  void ensure_owns_direct_data() override;
401 
403 
404  std::optional<blender::bke::AttributeAccessor> attributes() const final;
405  std::optional<blender::bke::MutableAttributeAccessor> attributes_for_write() final;
406 };
407 
419  private:
420  PointCloud *pointcloud_ = nullptr;
422 
423  public:
426  GeometryComponent *copy() const override;
427 
428  void clear();
429  bool has_pointcloud() const;
433  void replace(PointCloud *pointcloud,
439  PointCloud *release();
440 
446  const PointCloud *get_for_read() const;
453 
454  bool is_empty() const final;
455 
456  bool owns_direct_data() const override;
457  void ensure_owns_direct_data() override;
458 
459  std::optional<blender::bke::AttributeAccessor> attributes() const final;
460  std::optional<blender::bke::MutableAttributeAccessor> attributes_for_write() final;
461 
463 
464  private:
465 };
466 
475  private:
476  CurveEval *curve_ = nullptr;
478 
479  public:
482  GeometryComponent *copy() const override;
483 
484  void clear();
485  bool has_curve() const;
490  CurveEval *release();
491 
492  const CurveEval *get_for_read() const;
494 
495  bool is_empty() const final;
496 
497  bool owns_direct_data() const override;
498  void ensure_owns_direct_data() override;
499 
500  std::optional<blender::bke::AttributeAccessor> attributes() const final;
501  std::optional<blender::bke::MutableAttributeAccessor> attributes_for_write() final;
502 
504 };
505 
512  private:
513  Curves *curves_ = nullptr;
515 
522  mutable Curve *curve_for_render_ = nullptr;
523  mutable std::mutex curve_for_render_mutex_;
524 
525  public:
526  CurveComponent();
527  ~CurveComponent();
528  GeometryComponent *copy() const override;
529 
530  void clear();
531  bool has_curves() const;
536  Curves *release();
537 
538  const Curves *get_for_read() const;
540 
541  bool is_empty() const final;
542 
543  bool owns_direct_data() const override;
544  void ensure_owns_direct_data() override;
545 
550  const Curve *get_curve_for_render() const;
551 
552  std::optional<blender::bke::AttributeAccessor> attributes() const final;
553  std::optional<blender::bke::MutableAttributeAccessor> attributes_for_write() final;
554 
556 };
557 
563  public:
564  enum class Type {
570  None,
571  Object,
572  Collection,
573  GeometrySet,
574  };
575 
576  private:
577  Type type_ = Type::None;
579  void *data_ = nullptr;
580  std::unique_ptr<GeometrySet> geometry_set_;
581 
582  public:
583  InstanceReference() = default;
584 
585  InstanceReference(Object &object) : type_(Type::Object), data_(&object)
586  {
587  }
588 
589  InstanceReference(Collection &collection) : type_(Type::Collection), data_(&collection)
590  {
591  }
592 
594  : type_(Type::GeometrySet),
595  geometry_set_(std::make_unique<GeometrySet>(std::move(geometry_set)))
596  {
597  }
598 
599  InstanceReference(const InstanceReference &other) : type_(other.type_), data_(other.data_)
600  {
601  if (other.geometry_set_) {
602  geometry_set_ = std::make_unique<GeometrySet>(*other.geometry_set_);
603  }
604  }
605 
607  : type_(other.type_), data_(other.data_), geometry_set_(std::move(other.geometry_set_))
608  {
609  other.type_ = Type::None;
610  other.data_ = nullptr;
611  }
612 
614  {
615  if (this == &other) {
616  return *this;
617  }
618  this->~InstanceReference();
619  new (this) InstanceReference(other);
620  return *this;
621  }
622 
624  {
625  if (this == &other) {
626  return *this;
627  }
628  this->~InstanceReference();
629  new (this) InstanceReference(std::move(other));
630  return *this;
631  }
632 
633  Type type() const
634  {
635  return type_;
636  }
637 
638  Object &object() const
639  {
640  BLI_assert(type_ == Type::Object);
641  return *(Object *)data_;
642  }
643 
645  {
646  BLI_assert(type_ == Type::Collection);
647  return *(Collection *)data_;
648  }
649 
650  const GeometrySet &geometry_set() const
651  {
652  BLI_assert(type_ == Type::GeometrySet);
653  return *geometry_set_;
654  }
655 
656  bool owns_direct_data() const
657  {
658  if (type_ != Type::GeometrySet) {
659  /* The object and collection instances are not direct data. */
660  return true;
661  }
662  return geometry_set_->owns_direct_data();
663  }
664 
666  {
667  if (type_ != Type::GeometrySet) {
668  return;
669  }
670  geometry_set_->ensure_owns_direct_data();
671  }
672 
673  uint64_t hash() const
674  {
675  return blender::get_default_hash_2(data_, geometry_set_.get());
676  }
677 
678  friend bool operator==(const InstanceReference &a, const InstanceReference &b)
679  {
680  return a.data_ == b.data_ && a.geometry_set_.get() == b.geometry_set_.get();
681  }
682 };
683 
698  private:
704 
706  blender::Vector<int> instance_reference_handles_;
708  blender::Vector<blender::float4x4> instance_transforms_;
709 
710  /* These almost unique ids are generated based on the `id` attribute, which might not contain
711  * unique ids at all. They are *almost* unique, because under certain very unlikely
712  * circumstances, they are not unique. Code using these ids should not crash when they are not
713  * unique but can generally expect them to be unique. */
714  mutable std::mutex almost_unique_ids_mutex_;
715  mutable blender::Array<int> almost_unique_ids_;
716 
718 
719  public:
721  ~InstancesComponent() = default;
722  GeometryComponent *copy() const override;
723 
724  void clear();
725 
726  void reserve(int min_capacity);
733  void resize(int capacity);
734 
740  int add_reference(const InstanceReference &reference);
746  void add_instance(int instance_handle, const blender::float4x4 &transform);
747 
748  blender::Span<InstanceReference> references() const;
749  void remove_unused_references();
750 
756  void ensure_geometry_instances();
762  GeometrySet &geometry_set_from_reference(int reference_index);
763 
764  blender::Span<int> instance_reference_handles() const;
765  blender::MutableSpan<int> instance_reference_handles();
766  blender::MutableSpan<blender::float4x4> instance_transforms();
767  blender::Span<blender::float4x4> instance_transforms() const;
768 
769  int instances_num() const;
770  int references_num() const;
771 
776  void remove_instances(const blender::IndexMask mask);
777 
778  blender::Span<int> almost_unique_ids() const;
779 
780  blender::bke::CustomDataAttributes &instance_attributes();
781  const blender::bke::CustomDataAttributes &instance_attributes() const;
782 
783  std::optional<blender::bke::AttributeAccessor> attributes() const final;
784  std::optional<blender::bke::MutableAttributeAccessor> attributes_for_write() final;
785 
786  void foreach_referenced_geometry(
787  blender::FunctionRef<void(const GeometrySet &geometry_set)> callback) const;
788 
789  bool is_empty() const final;
790 
791  bool owns_direct_data() const override;
793 
795 
796  private:
797 };
798 
805  private:
806  Volume *volume_ = nullptr;
808 
809  public:
810  VolumeComponent();
811  ~VolumeComponent();
812  GeometryComponent *copy() const override;
813 
814  void clear();
815  bool has_volume() const;
824  Volume *release();
825 
830  const Volume *get_for_read() const;
837 
838  bool owns_direct_data() const override;
839  void ensure_owns_direct_data() override;
840 
842 };
843 
852  public:
859  std::unique_ptr<blender::bke::CurvesEditHints> curves_edit_hints_;
860 
862 
863  GeometryComponent *copy() const final;
864  bool owns_direct_data() const final;
866 
873  static void remember_deformed_curve_positions_if_necessary(GeometrySet &geometry);
874 
876 };
eAttrDomain
Definition: BKE_attribute.h:25
GeometryComponentType
@ GEO_COMPONENT_TYPE_MESH
@ GEO_COMPONENT_TYPE_POINT_CLOUD
@ GEO_COMPONENT_TYPE_INSTANCES
@ GEO_COMPONENT_TYPE_EDIT
@ GEO_COMPONENT_TYPE_CURVE
@ GEO_COMPONENT_TYPE_VOLUME
GeometryOwnershipType
constexpr bool is_geometry_component_v
#define BLI_STATIC_ASSERT(a, msg)
Definition: BLI_assert.h:83
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define final(a, b, c)
Definition: BLI_hash.h:21
ThreadMutex mutex
static uint8 component(Color32 c, uint i)
Definition: ColorBlock.cpp:108
struct Collection Collection
struct Object Object
_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
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to curves
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
std::unique_ptr< blender::bke::CurvesEditHints > curves_edit_hints_
void user_add() const
Definition: geometry_set.cc:84
int attribute_domain_size(eAttrDomain domain) const
Definition: geometry_set.cc:63
virtual bool is_empty() const
virtual void ensure_owns_direct_data()=0
GeometryComponent(GeometryComponentType type)
Definition: geometry_set.cc:39
virtual ~GeometryComponent()=default
static GeometryComponent * create(GeometryComponentType component_type)
Definition: geometry_set.cc:43
virtual std::optional< blender::bke::AttributeAccessor > attributes() const
Definition: geometry_set.cc:75
virtual std::optional< blender::bke::MutableAttributeAccessor > attributes_for_write()
Definition: geometry_set.cc:79
GeometryComponentType type() const
void user_remove() const
Definition: geometry_set.cc:89
bool is_mutable() const
Definition: geometry_set.cc:97
virtual GeometryComponent * copy() const =0
virtual bool owns_direct_data() const =0
InstanceReference(Object &object)
InstanceReference(GeometrySet geometry_set)
Object & object() const
InstanceReference(const InstanceReference &other)
InstanceReference & operator=(InstanceReference &&other)
InstanceReference(InstanceReference &&other)
uint64_t hash() const
InstanceReference(Collection &collection)
friend bool operator==(const InstanceReference &a, const InstanceReference &b)
InstanceReference & operator=(const InstanceReference &other)
InstanceReference()=default
bool owns_direct_data() const
Collection & collection() const
const GeometrySet & geometry_set() const
~InstancesComponent()=default
std::optional< blender::bke::MutableAttributeAccessor > attributes_for_write() final
const Mesh * get_for_read() const
bool is_empty() const final
void replace(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
std::optional< blender::bke::AttributeAccessor > attributes() const final
GeometryComponent * copy() const override
bool owns_direct_data() const override
void ensure_owns_direct_data() override
static constexpr GeometryComponentType static_type
Curve curve
DEGForeachIDComponentCallback callback
SyclQueue void void size_t num_bytes void
T * data_
Definition: eval_output.h:163
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Definition: math_float4.h:513
static unsigned a[3]
Definition: RandGen.cpp:78
uint64_t get_default_hash_2(const T1 &v1, const T2 &v2)
Definition: BLI_hash.hh:223
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
unsigned __int64 uint64_t
Definition: stdint.h:90
const PointCloud * get_pointcloud_for_read() const
bool has_volume() const
void replace_mesh(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
static GeometrySet create_with_curves(Curves *curves, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
blender::Vector< const GeometryComponent * > get_components_for_read() const
GeometrySet(GeometrySet &&other)
Curves * get_curves_for_write()
void ensure_owns_direct_data()
const Volume * get_volume_for_read() const
void replace_curves(Curves *curves, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
static GeometrySet create_with_mesh(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
void keep_only_during_modify(const blender::Span< GeometryComponentType > component_types)
GeometrySet & operator=(const GeometrySet &other)
bool has_realized_data() const
blender::Vector< GeometryComponentType > gather_component_types(bool include_instances, bool ignore_empty) const
void replace_volume(Volume *volume, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
static GeometrySet create_with_volume(Volume *volume, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
Component & get_component_for_write()
PointCloud * get_pointcloud_for_write()
const Mesh * get_mesh_for_read() const
bool owns_direct_data() const
const Curves * get_curves_for_read() const
bool is_empty() const
void attribute_foreach(blender::Span< GeometryComponentType > component_types, bool include_instances, AttributeForeachCallback callback) const
void gather_attributes_for_propagation(blender::Span< GeometryComponentType > component_types, GeometryComponentType dst_component_type, bool include_instances, blender::Map< blender::bke::AttributeIDRef, blender::bke::AttributeKind > &r_attributes) const
friend std::ostream & operator<<(std::ostream &stream, const GeometrySet &geometry_set)
GeometrySet(const GeometrySet &other)
Mesh * get_mesh_for_write()
void add(const GeometryComponent &component)
bool has_instances() const
void modify_geometry_sets(ForeachSubGeometryCallback callback)
static GeometrySet create_with_pointcloud(PointCloud *pointcloud, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
void keep_only(const blender::Span< GeometryComponentType > component_types)
bool has_mesh() const
blender::bke::CurvesEditHints * get_curve_edit_hints_for_write()
bool has_curves() const
const blender::bke::CurvesEditHints * get_curve_edit_hints_for_read() const
Volume * get_volume_for_write()
bool compute_boundbox_without_instances(blender::float3 *r_min, blender::float3 *r_max) const
void remove_geometry_during_modify()
void replace_pointcloud(PointCloud *pointcloud, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
const Component * get_component_for_read() const
bool has() const
GeometrySet & operator=(GeometrySet &&other)
bool has_pointcloud() const
bool override
Definition: wm_files.c:1022