diff options
author | Julian Eisel <julian@blender.org> | 2022-11-10 15:17:42 +0300 |
---|---|---|
committer | Julian Eisel <julian@blender.org> | 2022-11-10 15:17:42 +0300 |
commit | 7246c387435769a169ac24c91434c615df6434b4 (patch) | |
tree | 61842e3e0ce85e80720fdd7476d44d2e629f59fd /source/blender/blenkernel/BKE_geometry_set.hh | |
parent | c5f55d17096d373791363e46004176e3f7f7ae52 (diff) | |
parent | 0b4bd3ddc016298e868169a541cf6c132b10c587 (diff) |
Merge branch 'master' into asset-browser-grid-viewasset-browser-grid-view
Diffstat (limited to 'source/blender/blenkernel/BKE_geometry_set.hh')
-rw-r--r-- | source/blender/blenkernel/BKE_geometry_set.hh | 300 |
1 files changed, 35 insertions, 265 deletions
diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh index a5c4d5e1365..b488806c8e7 100644 --- a/source/blender/blenkernel/BKE_geometry_set.hh +++ b/source/blender/blenkernel/BKE_geometry_set.hh @@ -26,7 +26,6 @@ struct Curves; struct Collection; struct Curve; -struct CurveEval; struct Mesh; struct Object; struct PointCloud; @@ -44,6 +43,7 @@ enum class GeometryOwnershipType { namespace blender::bke { class ComponentAttributeProviders; class CurvesEditHints; +class Instances; } // namespace blender::bke class GeometryComponent; @@ -247,6 +247,12 @@ struct GeometrySet { */ static GeometrySet create_with_curves( Curves *curves, GeometryOwnershipType ownership = GeometryOwnershipType::Owned); + /** + * Create a new geometry set that only contains the given instances. + */ + static GeometrySet create_with_instances( + blender::bke::Instances *instances, + GeometryOwnershipType ownership = GeometryOwnershipType::Owned); /* Utility methods for access. */ /** @@ -295,6 +301,10 @@ struct GeometrySet { */ const Curves *get_curves_for_read() const; /** + * Returns read-only instances or null. + */ + const blender::bke::Instances *get_instances_for_read() const; + /** * Returns read-only curve edit hints or null. */ const blender::bke::CurvesEditHints *get_curve_edit_hints_for_read() const; @@ -316,6 +326,10 @@ struct GeometrySet { */ Curves *get_curves_for_write(); /** + * Returns mutable instances or null. No ownership is transferred. + */ + blender::bke::Instances *get_instances_for_write(); + /** * Returns mutable curve edit hints or null. */ blender::bke::CurvesEditHints *get_curve_edit_hints_for_write(); @@ -340,6 +354,11 @@ struct GeometrySet { */ void replace_curves(Curves *curves, GeometryOwnershipType ownership = GeometryOwnershipType::Owned); + /** + * Clear the existing instances and replace them with the given one. + */ + void replace_instances(blender::bke::Instances *instances, + GeometryOwnershipType ownership = GeometryOwnershipType::Owned); private: /** @@ -465,46 +484,7 @@ class PointCloudComponent : public GeometryComponent { }; /** - * Legacy runtime-only curves type. - * These curves are stored differently than other geometry components, because the data structure - * used here does not correspond exactly to the #Curve DNA data structure. A #CurveEval is stored - * here instead, though the component does give access to a #Curve for interfacing with render - * engines and other areas of Blender that expect to use a data-block with an #ID. - */ -class CurveComponentLegacy : public GeometryComponent { - private: - CurveEval *curve_ = nullptr; - GeometryOwnershipType ownership_ = GeometryOwnershipType::Owned; - - public: - CurveComponentLegacy(); - ~CurveComponentLegacy(); - GeometryComponent *copy() const override; - - void clear(); - bool has_curve() const; - /** - * Clear the component and replace it with the new curve. - */ - void replace(CurveEval *curve, GeometryOwnershipType ownership = GeometryOwnershipType::Owned); - CurveEval *release(); - - const CurveEval *get_for_read() const; - CurveEval *get_for_write(); - - bool is_empty() const final; - - bool owns_direct_data() const override; - void ensure_owns_direct_data() override; - - std::optional<blender::bke::AttributeAccessor> attributes() const final; - std::optional<blender::bke::MutableAttributeAccessor> attributes_for_write() final; - - static constexpr inline GeometryComponentType static_type = GEO_COMPONENT_TYPE_CURVE; -}; - -/** - * A geometry component that stores a group of curves, corresponding the #Curves data-block type + * A geometry component that stores a group of curves, corresponding the #Curves data-block * and the #CurvesGeometry type. Attributes are stored on the control point domain and the * curve domain. */ @@ -514,10 +494,9 @@ class CurveComponent : public GeometryComponent { GeometryOwnershipType ownership_ = GeometryOwnershipType::Owned; /** - * Curve data necessary to hold the draw cache for rendering, consistent over multiple redraws. - * This is necessary because Blender assumes that objects evaluate to an object data type, and - * we use #CurveEval rather than #Curve here. It also allows us to mostly reuse the same - * batch cache implementation. + * Because rendering #Curves isn't fully working yet, we must provide a #Curve for the render + * engine and depsgraph object iterator in some cases. This allows using the old curve rendering + * even when the new curve data structure is used. */ mutable Curve *curve_for_render_ = nullptr; mutable std::mutex curve_for_render_mutex_; @@ -556,244 +535,35 @@ class CurveComponent : public GeometryComponent { }; /** - * Holds a reference to conceptually unique geometry or a pointer to object/collection data - * that is instanced with a transform in #InstancesComponent. - */ -class InstanceReference { - public: - enum class Type { - /** - * An empty instance. This allows an `InstanceReference` to be default constructed without - * being in an invalid state. There might also be other use cases that we haven't explored much - * yet (such as changing the instance later on, and "disabling" some instances). - */ - None, - Object, - Collection, - GeometrySet, - }; - - private: - Type type_ = Type::None; - /** Depending on the type this is either null, an Object or Collection pointer. */ - void *data_ = nullptr; - std::unique_ptr<GeometrySet> geometry_set_; - - public: - InstanceReference() = default; - - InstanceReference(Object &object) : type_(Type::Object), data_(&object) - { - } - - InstanceReference(Collection &collection) : type_(Type::Collection), data_(&collection) - { - } - - InstanceReference(GeometrySet geometry_set) - : type_(Type::GeometrySet), - geometry_set_(std::make_unique<GeometrySet>(std::move(geometry_set))) - { - } - - InstanceReference(const InstanceReference &other) : type_(other.type_), data_(other.data_) - { - if (other.geometry_set_) { - geometry_set_ = std::make_unique<GeometrySet>(*other.geometry_set_); - } - } - - InstanceReference(InstanceReference &&other) - : type_(other.type_), data_(other.data_), geometry_set_(std::move(other.geometry_set_)) - { - other.type_ = Type::None; - other.data_ = nullptr; - } - - InstanceReference &operator=(const InstanceReference &other) - { - if (this == &other) { - return *this; - } - this->~InstanceReference(); - new (this) InstanceReference(other); - return *this; - } - - InstanceReference &operator=(InstanceReference &&other) - { - if (this == &other) { - return *this; - } - this->~InstanceReference(); - new (this) InstanceReference(std::move(other)); - return *this; - } - - Type type() const - { - return type_; - } - - Object &object() const - { - BLI_assert(type_ == Type::Object); - return *(Object *)data_; - } - - Collection &collection() const - { - BLI_assert(type_ == Type::Collection); - return *(Collection *)data_; - } - - const GeometrySet &geometry_set() const - { - BLI_assert(type_ == Type::GeometrySet); - return *geometry_set_; - } - - bool owns_direct_data() const - { - if (type_ != Type::GeometrySet) { - /* The object and collection instances are not direct data. */ - return true; - } - return geometry_set_->owns_direct_data(); - } - - void ensure_owns_direct_data() - { - if (type_ != Type::GeometrySet) { - return; - } - geometry_set_->ensure_owns_direct_data(); - } - - uint64_t hash() const - { - return blender::get_default_hash_2(data_, geometry_set_.get()); - } - - friend bool operator==(const InstanceReference &a, const InstanceReference &b) - { - return a.data_ == b.data_ && a.geometry_set_.get() == b.geometry_set_.get(); - } -}; - -/** - * A geometry component that stores instances. The instance data can be any type described by - * #InstanceReference. Geometry instances can even contain instances themselves, for nested - * instancing. Each instance has an index into an array of unique instance data, and a transform. - * The component can also store generic attributes for each instance. - * - * The component works differently from other geometry components in that it stores - * data about instancing directly, rather than owning a pointer to a separate data structure. - * - * This component is not responsible for handling the interface to a render engine, or other - * areas that work with all visible geometry, that is handled by the dependency graph iterator - * (see `DEG_depsgraph_query.h`). + * A geometry component that stores #Instances. */ class InstancesComponent : public GeometryComponent { private: - /** - * Indexed set containing information about the data that is instanced. - * Actual instances store an index ("handle") into this set. - */ - blender::VectorSet<InstanceReference> references_; - - /** Index into `references_`. Determines what data is instanced. */ - blender::Vector<int> instance_reference_handles_; - /** Transformation of the instances. */ - blender::Vector<blender::float4x4> instance_transforms_; - - /* These almost unique ids are generated based on the `id` attribute, which might not contain - * unique ids at all. They are *almost* unique, because under certain very unlikely - * circumstances, they are not unique. Code using these ids should not crash when they are not - * unique but can generally expect them to be unique. */ - mutable std::mutex almost_unique_ids_mutex_; - mutable blender::Array<int> almost_unique_ids_; - - blender::bke::CustomDataAttributes attributes_; + blender::bke::Instances *instances_ = nullptr; + GeometryOwnershipType ownership_ = GeometryOwnershipType::Owned; public: InstancesComponent(); - ~InstancesComponent() = default; + ~InstancesComponent(); GeometryComponent *copy() const override; void clear(); - void reserve(int min_capacity); - /** - * Resize the transform, handles, and attributes to the specified capacity. - * - * \note This function should be used carefully, only when it's guaranteed - * that the data will be filled. - */ - void resize(int capacity); - - /** - * Returns a handle for the given reference. - * If the reference exists already, the handle of the existing reference is returned. - * Otherwise a new handle is added. - */ - int add_reference(const InstanceReference &reference); - /** - * Add a reference to the instance reference with an index specified by the #instance_handle - * argument. For adding many instances, using #resize and accessing the transform array directly - * is preferred. - */ - void add_instance(int instance_handle, const blender::float4x4 &transform); - - blender::Span<InstanceReference> references() const; - void remove_unused_references(); - - /** - * If references have a collection or object type, convert them into geometry instances - * recursively. After that, the geometry sets can be edited. There may still be instances of - * other types of they can't be converted to geometry sets. - */ - void ensure_geometry_instances(); - /** - * With write access to the instances component, the data in the instanced geometry sets can be - * changed. This is a function on the component rather than each reference to ensure `const` - * correctness for that reason. - */ - GeometrySet &geometry_set_from_reference(int reference_index); - - blender::Span<int> instance_reference_handles() const; - blender::MutableSpan<int> instance_reference_handles(); - blender::MutableSpan<blender::float4x4> instance_transforms(); - blender::Span<blender::float4x4> instance_transforms() const; + const blender::bke::Instances *get_for_read() const; + blender::bke::Instances *get_for_write(); - int instances_num() const; - int references_num() const; - - /** - * Remove the indices that are not contained in the mask input, and remove unused instance - * references afterwards. - */ - void remove_instances(const blender::IndexMask mask); - - blender::Span<int> almost_unique_ids() const; - - blender::bke::CustomDataAttributes &instance_attributes(); - const blender::bke::CustomDataAttributes &instance_attributes() const; - - std::optional<blender::bke::AttributeAccessor> attributes() const final; - std::optional<blender::bke::MutableAttributeAccessor> attributes_for_write() final; - - void foreach_referenced_geometry( - blender::FunctionRef<void(const GeometrySet &geometry_set)> callback) const; + void replace(blender::bke::Instances *instances, + GeometryOwnershipType ownership = GeometryOwnershipType::Owned); bool is_empty() const final; bool owns_direct_data() const override; void ensure_owns_direct_data() override; - static constexpr inline GeometryComponentType static_type = GEO_COMPONENT_TYPE_INSTANCES; + std::optional<blender::bke::AttributeAccessor> attributes() const final; + std::optional<blender::bke::MutableAttributeAccessor> attributes_for_write() final; - private: + static constexpr inline GeometryComponentType static_type = GEO_COMPONENT_TYPE_INSTANCES; }; /** |