Blender V5.0
BKE_geometry_set.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
5#pragma once
6
10
11#include <iosfwd>
12
13#include "BLI_bounds_types.hh"
14#include "BLI_function_ref.hh"
16#include "BLI_map.hh"
19#include "BLI_mutex.hh"
20
21/* For #Map. */
22#include "BKE_attribute.hh"
23
24struct Curves;
25struct Curve;
26struct Mesh;
27struct PointCloud;
28struct Volume;
29struct GreasePencil;
30namespace blender::bke {
34class CurvesEditHints;
35class Instances;
39enum class AttrDomain : int8_t;
40struct GizmoEditHints;
41} // namespace blender::bke
42
43namespace blender::bke {
44
45#define GEO_COMPONENT_TYPE_ENUM_SIZE 7
46
48 /* The geometry is owned. This implies that it can be changed. */
49 Owned = 0,
50 /* The geometry can be changed, but someone else is responsible for freeing it. */
52 /* The geometry cannot be changed and someone else is responsible for freeing it. */
54};
55
57
64 public:
71 enum class Type {
72 Mesh = 0,
75 Volume = 3,
76 Curve = 4,
77 Edit = 5,
79 };
80
81 private:
82 Type type_;
83
84 public:
86 ~GeometryComponent() override = default;
87 static GeometryComponentPtr create(Type component_type);
88
89 int attribute_domain_size(AttrDomain domain) const;
90
95 virtual std::optional<AttributeAccessor> attributes() const;
96 virtual std::optional<MutableAttributeAccessor> attributes_for_write();
97
98 virtual void count_memory(MemoryCounter &memory) const;
99
103 virtual GeometryComponentPtr copy() const = 0;
104
106 virtual void clear() = 0;
107
108 /* Direct data is everything except for instances of objects/collections.
109 * If this returns true, the geometry set can be cached and is still valid after e.g. modifier
110 * evaluation ends. Instances can only be valid as long as the data they instance is valid. */
111 virtual bool owns_direct_data() const = 0;
112 virtual void ensure_owns_direct_data() = 0;
113
114 Type type() const;
115
116 virtual bool is_empty() const;
117
118 private:
119 void delete_self() override;
120 void delete_data_only() override;
121};
122
123template<typename T>
124inline constexpr bool is_geometry_component_v = std::is_base_of_v<GeometryComponent, T>;
125
146 private:
147 /* Indexed by #GeometryComponent::Type. */
148 std::array<GeometryComponentPtr, GEO_COMPONENT_TYPE_ENUM_SIZE> components_;
149
150 public:
156 std::string name;
157
167
173 template<typename Component> Component &get_component_for_write()
174 {
176 return static_cast<Component &>(this->get_component_for_write(Component::static_type));
177 }
178
182 const GeometryComponent *get_component(GeometryComponent::Type component_type) const;
183 template<typename Component> const Component *get_component() const
184 {
186 return static_cast<const Component *>(get_component(Component::static_type));
187 }
188
189 bool has(const GeometryComponent::Type component_type) const;
190 template<typename Component> bool has() const
191 {
193 return this->has(Component::static_type);
194 }
195
196 template<typename Component> bool has_component() const
197 {
199 return components_[int(Component::static_type)];
200 }
201
202 void remove(const GeometryComponent::Type component_type);
203 template<typename Component> void remove()
204 {
206 return this->remove(Component::static_type);
207 }
208
212 void keep_only(Span<GeometryComponent::Type> component_types);
213
214 void add(const GeometryComponent &component);
215
220
221 std::optional<Bounds<float3>> compute_boundbox_without_instances(bool use_radius = true,
222 bool use_subdiv = false) const;
223
224 friend std::ostream &operator<<(std::ostream &stream, const GeometrySet &geometry_set);
225
229 void clear();
230
231 bool owns_direct_data() const;
250
252 const AttributeMetaData &meta_data,
253 const GeometryComponent &component)>;
254
256 bool include_instances,
257 AttributeForeachCallback callback) const;
258
264
266 GeometryComponent::Type dst_component_type,
267 bool include_instances,
268 const AttributeFilter &attribute_filter,
269 GatheredAttributes &r_attributes) const;
270
272 bool ignore_empty) const;
273
274 /* Utility methods for creation. */
283 static GeometrySet from_volume(Volume *volume,
305
306 /* Utility methods for access. */
310 bool has_mesh() const;
314 bool has_pointcloud() const;
318 bool has_instances() const;
322 bool has_volume() const;
326 bool has_curves() const;
330 bool has_realized_data() const;
334 bool has_grease_pencil() const;
338 bool is_empty() const;
339
343 const Mesh *get_mesh() const;
347 const PointCloud *get_pointcloud() const;
351 const Volume *get_volume() const;
355 const Curves *get_curves() const;
359 const Instances *get_instances() const;
375 const GreasePencil *get_grease_pencil() const;
376
413
414 /* Utility methods for replacement. */
422 void replace_pointcloud(PointCloud *pointcloud,
427 void replace_volume(Volume *volume,
437 void replace_instances(Instances *instances,
442 void replace_grease_pencil(GreasePencil *grease_pencil,
444
445 friend bool operator==(const GeometrySet &a, const GeometrySet &b)
446 {
447 /* This compares only the component pointers, not the actual geometry data. */
448 return Span(a.components_) == Span(b.components_) && a.name == b.name;
449 }
450
452 {
453 /* This should have the same data that's also taken into account in #operator==. */
454 return get_default_hash(Span(components_), this->name);
455 }
456
457 void count_memory(MemoryCounter &memory) const;
458
459 private:
464 GeometryComponent *get_component_ptr(GeometryComponent::Type type);
465 template<typename Component> Component *get_component_ptr()
466 {
468 return static_cast<Component *>(get_component_ptr(Component::static_type));
469 }
470};
471
477 private:
478 Mesh *mesh_ = nullptr;
480
481 public:
484 ~MeshComponent() override;
485 GeometryComponentPtr copy() const override;
486
487 void clear() override;
488 bool has_mesh() const;
497 Mesh *release();
498
503 const Mesh *get() const;
509
510 bool is_empty() const final;
511
512 bool owns_direct_data() const override;
513 void ensure_owns_direct_data() override;
514
515 void count_memory(MemoryCounter &memory) const override;
516
518
519 std::optional<AttributeAccessor> attributes() const final;
521};
522
534 private:
535 PointCloud *pointcloud_ = nullptr;
537
538 public:
542 ~PointCloudComponent() override;
543 GeometryComponentPtr copy() const override;
544
545 void clear() override;
546 bool has_pointcloud() const;
550 void replace(PointCloud *pointcloud,
557
563 const PointCloud *get() const;
570
571 bool is_empty() const final;
572
573 bool owns_direct_data() const override;
574 void ensure_owns_direct_data() override;
575
576 void count_memory(MemoryCounter &memory) const override;
577
578 std::optional<AttributeAccessor> attributes() const final;
579 std::optional<MutableAttributeAccessor> attributes_for_write() final;
580
582};
583
590 private:
591 Curves *curves_ = nullptr;
593
599 mutable Curve *curve_for_render_ = nullptr;
600 mutable Mutex curve_for_render_mutex_;
601
602 public:
605 ~CurveComponent() override;
606 GeometryComponentPtr copy() const override;
607
608 void clear() override;
609 bool has_curves() const;
614 Curves *release();
615
616 const Curves *get() const;
618
619 bool is_empty() const final;
620
621 bool owns_direct_data() const override;
622 void ensure_owns_direct_data() override;
623
624 void count_memory(MemoryCounter &memory) const override;
625
630 const Curve *get_curve_for_render() const;
631
632 std::optional<AttributeAccessor> attributes() const final;
633 std::optional<MutableAttributeAccessor> attributes_for_write() final;
634
636};
637
642 private:
643 Instances *instances_ = nullptr;
645
646 public:
648 InstancesComponent(Instances *instances,
650 ~InstancesComponent() override;
651 GeometryComponentPtr copy() const override;
652
653 void clear() override;
654
655 const Instances *get() const;
657
658 void replace(Instances *instances,
660
661 bool is_empty() const final;
662
664
665 bool owns_direct_data() const override;
666 void ensure_owns_direct_data() override;
667
668 void count_memory(MemoryCounter &memory) const override;
669
670 std::optional<AttributeAccessor> attributes() const final;
671 std::optional<MutableAttributeAccessor> attributes_for_write() final;
672
674};
675
682 private:
683 Volume *volume_ = nullptr;
685
686 public:
688 ~VolumeComponent() override;
689 GeometryComponentPtr copy() const override;
690
691 void clear() override;
692 bool has_volume() const;
701 Volume *release();
702
707 const Volume *get() const;
714
715 bool owns_direct_data() const override;
716 void ensure_owns_direct_data() override;
717
718 void count_memory(MemoryCounter &memory) const override;
719
721};
722
731 public:
738 std::unique_ptr<CurvesEditHints> curves_edit_hints_;
742 std::unique_ptr<GreasePencilEditHints> grease_pencil_edit_hints_;
746 std::unique_ptr<GizmoEditHints> gizmo_edit_hints_;
747
749
751 bool owns_direct_data() const final;
753
754 void clear() override;
755
763
765};
766
773 private:
774 GreasePencil *grease_pencil_ = nullptr;
776
777 public:
779 ~GreasePencilComponent() override;
780 GeometryComponentPtr copy() const override;
781
782 void clear() override;
783 bool has_grease_pencil() const;
787 void replace(GreasePencil *grease_pencil,
794
795 const GreasePencil *get() const;
797
798 bool is_empty() const final;
799
800 bool owns_direct_data() const override;
801 void ensure_owns_direct_data() override;
802
804
805 std::optional<AttributeAccessor> attributes() const final;
807};
808
810
811} // namespace blender::bke
#define BLI_STATIC_ASSERT(a, msg)
Definition BLI_assert.h:83
#define final(a, b, c)
Definition BLI_hash.h:19
unsigned long long int uint64_t
void count_memory(MemoryCounter &memory) const override
static constexpr GeometryComponent::Type static_type
void replace(Curves *curve, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
std::optional< AttributeAccessor > attributes() const final
std::optional< MutableAttributeAccessor > attributes_for_write() final
std::unique_ptr< GreasePencilEditHints > grease_pencil_edit_hints_
std::unique_ptr< GizmoEditHints > gizmo_edit_hints_
static constexpr GeometryComponent::Type static_type
std::unique_ptr< CurvesEditHints > curves_edit_hints_
static void remember_deformed_positions_if_necessary(GeometrySet &geometry)
int attribute_domain_size(AttrDomain domain) const
virtual std::optional< AttributeAccessor > attributes() const
~GeometryComponent() override=default
virtual std::optional< MutableAttributeAccessor > attributes_for_write()
virtual bool is_empty() const
virtual void count_memory(MemoryCounter &memory) const
virtual void ensure_owns_direct_data()=0
virtual bool owns_direct_data() const =0
virtual GeometryComponentPtr copy() const =0
static GeometryComponentPtr create(Type component_type)
std::optional< AttributeAccessor > attributes() const final
static constexpr GeometryComponent::Type static_type
std::optional< MutableAttributeAccessor > attributes_for_write() final
void replace(GreasePencil *grease_pencil, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
std::optional< MutableAttributeAccessor > attributes_for_write() final
static constexpr GeometryComponent::Type static_type
void count_memory(MemoryCounter &memory) const override
std::optional< AttributeAccessor > attributes() const final
void replace(Instances *instances, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
static constexpr GeometryComponent::Type static_type
void replace(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
GeometryComponentPtr copy() const override
void count_memory(MemoryCounter &memory) const override
std::optional< AttributeAccessor > attributes() const final
std::optional< MutableAttributeAccessor > attributes_for_write() final
static constexpr GeometryComponent::Type static_type
void count_memory(MemoryCounter &memory) const override
static constexpr GeometryComponent::Type static_type
void replace(Volume *volume, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
static void clear(Message &msg)
Definition msgfmt.cc:213
ImplicitSharingPtr< GeometryComponent > GeometryComponentPtr
constexpr bool is_geometry_component_v
bool attribute_is_builtin_on_component_type(const GeometryComponent::Type type, StringRef name)
uint64_t get_default_hash(const T &v, const Args &...args)
Definition BLI_hash.hh:233
std::mutex Mutex
Definition BLI_mutex.hh:47
static void copy(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node)
const char * name
void add(const StringRef name, const AttributeDomainAndType &kind)
Vector< AttributeDomainAndType, 16 > kinds
GeometrySet & operator=(GeometrySet &&other)
void replace_volume(Volume *volume, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
void keep_only(Span< GeometryComponent::Type > component_types)
const CurvesEditHints * get_curve_edit_hints() const
GeometrySet & operator=(const GeometrySet &other)
static GeometrySet from_instances(Instances *instances, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
static GeometrySet from_grease_pencil(GreasePencil *grease_pencil, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
PointCloud * get_pointcloud_for_write()
static GeometrySet from_curves(Curves *curves, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
GizmoEditHints * get_gizmo_edit_hints_for_write()
void replace_instances(Instances *instances, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
Instances * get_instances_for_write()
const GreasePencil * get_grease_pencil() const
const Component * get_component() const
const GizmoEditHints * get_gizmo_edit_hints() const
FunctionRef< void(StringRef attribute_id, const AttributeMetaData &meta_data, const GeometryComponent &component)> AttributeForeachCallback
Vector< const GeometryComponent * > get_components() const
const Volume * get_volume() const
std::optional< Bounds< float3 > > compute_boundbox_without_instances(bool use_radius=true, bool use_subdiv=false) const
static GeometrySet from_mesh(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
friend std::ostream & operator<<(std::ostream &stream, const GeometrySet &geometry_set)
void replace_pointcloud(PointCloud *pointcloud, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
const Curves * get_curves() const
static GeometrySet from_pointcloud(PointCloud *pointcloud, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
const Instances * get_instances() const
static GeometrySet from_volume(Volume *volume, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
GeometrySet(const GeometrySet &other)
void gather_attributes_for_propagation(Span< GeometryComponent::Type > component_types, GeometryComponent::Type dst_component_type, bool include_instances, const AttributeFilter &attribute_filter, GatheredAttributes &r_attributes) const
GreasePencilEditHints * get_grease_pencil_edit_hints_for_write()
void replace_curves(Curves *curves, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
CurvesEditHints * get_curve_edit_hints_for_write()
friend bool operator==(const GeometrySet &a, const GeometrySet &b)
void count_memory(MemoryCounter &memory) const
const GreasePencilEditHints * get_grease_pencil_edit_hints() const
const PointCloud * get_pointcloud() const
const Mesh * get_mesh() const
void replace_mesh(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
GreasePencil * get_grease_pencil_for_write()
Vector< GeometryComponent::Type > gather_component_types(bool include_instances, bool ignore_empty) const
void attribute_foreach(Span< GeometryComponent::Type > component_types, bool include_instances, AttributeForeachCallback callback) const
void add(const GeometryComponent &component)
void replace_grease_pencil(GreasePencil *grease_pencil, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
GeometrySet(GeometrySet &&other)
bool override
Definition wm_files.cc:1192