diff options
Diffstat (limited to 'source/blender/functions')
-rw-r--r-- | source/blender/functions/FN_cpp_type.hh | 2 | ||||
-rw-r--r-- | source/blender/functions/FN_generic_pointer.hh | 10 | ||||
-rw-r--r-- | source/blender/functions/FN_generic_value_map.hh | 5 | ||||
-rw-r--r-- | source/blender/functions/FN_generic_virtual_array.hh | 52 | ||||
-rw-r--r-- | source/blender/functions/FN_multi_function_params.hh | 7 | ||||
-rw-r--r-- | source/blender/functions/intern/cpp_types.cc | 4 | ||||
-rw-r--r-- | source/blender/functions/intern/generic_virtual_array.cc | 93 |
7 files changed, 167 insertions, 6 deletions
diff --git a/source/blender/functions/FN_cpp_type.hh b/source/blender/functions/FN_cpp_type.hh index 54ea0103fe5..cd1597a742c 100644 --- a/source/blender/functions/FN_cpp_type.hh +++ b/source/blender/functions/FN_cpp_type.hh @@ -666,7 +666,7 @@ class CPPType : NonCopyable, NonMovable { template<typename T> bool is() const { - return this == &CPPType::get<T>(); + return this == &CPPType::get<std::decay_t<T>>(); } }; diff --git a/source/blender/functions/FN_generic_pointer.hh b/source/blender/functions/FN_generic_pointer.hh index 2bd66daa7fe..f88ff09f916 100644 --- a/source/blender/functions/FN_generic_pointer.hh +++ b/source/blender/functions/FN_generic_pointer.hh @@ -66,6 +66,16 @@ class GMutablePointer { return type_ != nullptr && type_->is<T>(); } + template<typename T> T relocate_out() + { + BLI_assert(this->is_type<T>()); + T value; + type_->relocate_to_initialized(data_, &value); + data_ = nullptr; + type_ = nullptr; + return value; + } + void destruct() { BLI_assert(data_ != nullptr); diff --git a/source/blender/functions/FN_generic_value_map.hh b/source/blender/functions/FN_generic_value_map.hh index 68cb945f1af..4e7fe298874 100644 --- a/source/blender/functions/FN_generic_value_map.hh +++ b/source/blender/functions/FN_generic_value_map.hh @@ -93,6 +93,11 @@ template<typename Key> class GValueMap { return values_.pop_as(key); } + template<typename ForwardKey> GPointer lookup(const ForwardKey &key) const + { + return values_.lookup_as(key); + } + /* Remove the value for the given name from the container and remove it. */ template<typename T, typename ForwardKey> T extract(const ForwardKey &key) { diff --git a/source/blender/functions/FN_generic_virtual_array.hh b/source/blender/functions/FN_generic_virtual_array.hh index c1af00fd4cd..d530d10b3c8 100644 --- a/source/blender/functions/FN_generic_virtual_array.hh +++ b/source/blender/functions/FN_generic_virtual_array.hh @@ -34,6 +34,12 @@ namespace blender::fn { template<typename T> class GVArray_Typed; template<typename T> class GVMutableArray_Typed; +class GVArray; +class GVMutableArray; + +using GVArrayPtr = std::unique_ptr<GVArray>; +using GVMutableArrayPtr = std::unique_ptr<GVMutableArray>; + /* A generically typed version of `VArray<T>`. */ class GVArray { protected: @@ -117,6 +123,7 @@ class GVArray { BLI_assert(this->is_single()); if (size_ == 1) { this->get(0, r_value); + return; } this->get_internal_single_impl(r_value); } @@ -128,6 +135,10 @@ class GVArray { this->get_internal_single(r_value); } + void materialize(void *dst) const; + void materialize(const IndexMask mask, void *dst) const; + + void materialize_to_uninitialized(void *dst) const; void materialize_to_uninitialized(const IndexMask mask, void *dst) const; template<typename T> const VArray<T> *try_get_internal_varray() const @@ -142,6 +153,8 @@ class GVArray { return GVArray_Typed<T>(*this); } + GVArrayPtr shallow_copy() const; + protected: virtual void get_impl(const int64_t index, void *r_value) const; virtual void get_to_uninitialized_impl(const int64_t index, void *r_value) const = 0; @@ -152,6 +165,9 @@ class GVArray { virtual bool is_single_impl() const; virtual void get_internal_single_impl(void *UNUSED(r_value)) const; + virtual void materialize_impl(const IndexMask mask, void *dst) const; + virtual void materialize_to_uninitialized_impl(const IndexMask mask, void *dst) const; + virtual const void *try_get_internal_varray_impl() const; }; @@ -204,17 +220,22 @@ class GVMutableArray : public GVArray { void fill(const void *value); + /* Copy the values from the source buffer to all elements in the virtual array. */ + void set_all(const void *src) + { + this->set_all_impl(src); + } + protected: virtual void set_by_copy_impl(const int64_t index, const void *value); virtual void set_by_relocate_impl(const int64_t index, void *value); virtual void set_by_move_impl(const int64_t index, void *value) = 0; + virtual void set_all_impl(const void *src); + virtual void *try_get_internal_mutable_varray_impl(); }; -using GVArrayPtr = std::unique_ptr<GVArray>; -using GVMutableArrayPtr = std::unique_ptr<GVMutableArray>; - class GVArray_For_GSpan : public GVArray { protected: const void *data_ = nullptr; @@ -361,6 +382,16 @@ template<typename T> class GVArray_For_VArray : public GVArray { *(T *)r_value = varray_->get_internal_single(); } + void materialize_impl(const IndexMask mask, void *dst) const override + { + varray_->materialize(mask, MutableSpan((T *)dst, mask.min_array_size())); + } + + void materialize_to_uninitialized_impl(const IndexMask mask, void *dst) const override + { + varray_->materialize_to_uninitialized(mask, MutableSpan((T *)dst, mask.min_array_size())); + } + const void *try_get_internal_varray_impl() const override { return varray_; @@ -531,6 +562,21 @@ template<typename T> class GVMutableArray_For_VMutableArray : public GVMutableAr varray_->set(index, std::move(value_)); } + void set_all_impl(const void *src) override + { + varray_->set_all(Span((T *)src, size_)); + } + + void materialize_impl(const IndexMask mask, void *dst) const override + { + varray_->materialize(mask, MutableSpan((T *)dst, mask.min_array_size())); + } + + void materialize_to_uninitialized_impl(const IndexMask mask, void *dst) const override + { + varray_->materialize_to_uninitialized(mask, MutableSpan((T *)dst, mask.min_array_size())); + } + const void *try_get_internal_varray_impl() const override { return (const VArray<T> *)varray_; diff --git a/source/blender/functions/FN_multi_function_params.hh b/source/blender/functions/FN_multi_function_params.hh index 3b15f0278f3..e292d11def7 100644 --- a/source/blender/functions/FN_multi_function_params.hh +++ b/source/blender/functions/FN_multi_function_params.hh @@ -27,6 +27,7 @@ #include "BLI_resource_scope.hh" +#include "FN_generic_pointer.hh" #include "FN_generic_vector_array.hh" #include "FN_generic_virtual_vector_array.hh" #include "FN_multi_function_signature.hh" @@ -64,6 +65,12 @@ class MFParamsBuilder { this->add_readonly_single_input(scope_.construct<GVArray_For_GSpan>(__func__, span), expected_name); } + void add_readonly_single_input(GPointer value, StringRef expected_name = "") + { + this->add_readonly_single_input(scope_.construct<GVArray_For_SingleValueRef>( + __func__, *value.type(), min_array_size_, value.get()), + expected_name); + } void add_readonly_single_input(const GVArray &ref, StringRef expected_name = "") { this->assert_current_param_type(MFParamType::ForSingleInput(ref.type()), expected_name); diff --git a/source/blender/functions/intern/cpp_types.cc b/source/blender/functions/intern/cpp_types.cc index 53c5def57e9..9c2c1621e23 100644 --- a/source/blender/functions/intern/cpp_types.cc +++ b/source/blender/functions/intern/cpp_types.cc @@ -34,8 +34,8 @@ MAKE_CPP_TYPE(int32, int32_t) MAKE_CPP_TYPE(uint32, uint32_t) MAKE_CPP_TYPE(uint8, uint8_t) -MAKE_CPP_TYPE(Color4f, blender::Color4f) -MAKE_CPP_TYPE(Color4b, blender::Color4b) +MAKE_CPP_TYPE(ColorGeometry4f, blender::ColorGeometry4f) +MAKE_CPP_TYPE(ColorGeometry4b, blender::ColorGeometry4b) MAKE_CPP_TYPE(string, std::string) diff --git a/source/blender/functions/intern/generic_virtual_array.cc b/source/blender/functions/intern/generic_virtual_array.cc index e11501828f8..87dae06ccdc 100644 --- a/source/blender/functions/intern/generic_virtual_array.cc +++ b/source/blender/functions/intern/generic_virtual_array.cc @@ -19,11 +19,71 @@ namespace blender::fn { /* -------------------------------------------------------------------- + * GVArray_For_ShallowCopy. + */ + +class GVArray_For_ShallowCopy : public GVArray { + private: + const GVArray &varray_; + + public: + GVArray_For_ShallowCopy(const GVArray &varray) + : GVArray(varray.type(), varray.size()), varray_(varray) + { + } + + private: + void get_impl(const int64_t index, void *r_value) const override + { + varray_.get(index, r_value); + } + + void get_to_uninitialized_impl(const int64_t index, void *r_value) const override + { + varray_.get_to_uninitialized(index, r_value); + } + + void materialize_to_uninitialized_impl(const IndexMask mask, void *dst) const override + { + varray_.materialize_to_uninitialized(mask, dst); + } +}; + +/* -------------------------------------------------------------------- * GVArray. */ +void GVArray::materialize(void *dst) const +{ + this->materialize(IndexMask(size_), dst); +} + +void GVArray::materialize(const IndexMask mask, void *dst) const +{ + this->materialize_impl(mask, dst); +} + +void GVArray::materialize_impl(const IndexMask mask, void *dst) const +{ + for (const int64_t i : mask) { + void *elem_dst = POINTER_OFFSET(dst, type_->size() * i); + this->get(i, elem_dst); + } +} + +void GVArray::materialize_to_uninitialized(void *dst) const +{ + this->materialize_to_uninitialized(IndexMask(size_), dst); +} + void GVArray::materialize_to_uninitialized(const IndexMask mask, void *dst) const { + BLI_assert(mask.min_array_size() <= size_); + this->materialize_to_uninitialized_impl(mask, dst); +} + +void GVArray::materialize_to_uninitialized_impl(const IndexMask mask, void *dst) const +{ for (const int64_t i : mask) { void *elem_dst = POINTER_OFFSET(dst, type_->size() * i); this->get_to_uninitialized(i, elem_dst); @@ -62,6 +122,26 @@ const void *GVArray::try_get_internal_varray_impl() const return nullptr; } +/** + * Creates a new `std::unique_ptr<GVArray>` based on this `GVArray`. + * The lifetime of the returned virtual array must not be longer than the lifetime of this virtual + * array. + */ +GVArrayPtr GVArray::shallow_copy() const +{ + if (this->is_span()) { + return std::make_unique<GVArray_For_GSpan>(this->get_internal_span()); + } + if (this->is_single()) { + BUFFER_FOR_CPP_TYPE_VALUE(*type_, buffer); + this->get_internal_single(buffer); + std::unique_ptr new_varray = std::make_unique<GVArray_For_SingleValue>(*type_, size_, buffer); + type_->destruct(buffer); + return new_varray; + } + return std::make_unique<GVArray_For_ShallowCopy>(*this); +} + /* -------------------------------------------------------------------- * GVMutableArray. */ @@ -80,6 +160,19 @@ void GVMutableArray::set_by_relocate_impl(const int64_t index, void *value) type_->destruct(value); } +void GVMutableArray::set_all_impl(const void *src) +{ + if (this->is_span()) { + const GMutableSpan span = this->get_internal_span(); + type_->copy_to_initialized_n(src, span.data(), size_); + } + else { + for (int64_t i : IndexRange(size_)) { + this->set_by_copy(i, POINTER_OFFSET(src, type_->size() * i)); + } + } +} + void *GVMutableArray::try_get_internal_mutable_varray_impl() { return nullptr; |