2022-02-11 09:07:11 +11:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
2021-03-21 19:31:24 +01:00
|
|
|
|
2022-03-19 08:26:29 +01:00
|
|
|
#include "BLI_generic_virtual_array.hh"
|
2021-03-21 19:31:24 +01:00
|
|
|
|
2022-03-19 08:26:29 +01:00
|
|
|
namespace blender {
|
2021-03-21 19:31:24 +01:00
|
|
|
|
2021-10-05 11:10:25 +11:00
|
|
|
/* -------------------------------------------------------------------- */
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
/** \name #GVArrayImpl
|
2021-10-05 11:10:25 +11:00
|
|
|
* \{ */
|
2021-04-29 15:42:32 +02:00
|
|
|
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
void GVArrayImpl::materialize(const IndexMask mask, void *dst) const
|
2021-05-10 10:28:24 +02:00
|
|
|
{
|
|
|
|
|
for (const int64_t i : mask) {
|
|
|
|
|
void *elem_dst = POINTER_OFFSET(dst, type_->size() * i);
|
|
|
|
|
this->get(i, elem_dst);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
void GVArrayImpl::materialize_to_uninitialized(const IndexMask mask, void *dst) const
|
2021-03-21 19:31:24 +01:00
|
|
|
{
|
|
|
|
|
for (const int64_t i : mask) {
|
|
|
|
|
void *elem_dst = POINTER_OFFSET(dst, type_->size() * i);
|
|
|
|
|
this->get_to_uninitialized(i, elem_dst);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-07 10:02:34 +02:00
|
|
|
void GVArrayImpl::materialize_compressed(IndexMask mask, void *dst) const
|
|
|
|
|
{
|
|
|
|
|
for (const int64_t i : mask.index_range()) {
|
|
|
|
|
void *elem_dst = POINTER_OFFSET(dst, type_->size() * i);
|
|
|
|
|
this->get(mask[i], elem_dst);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GVArrayImpl::materialize_compressed_to_uninitialized(IndexMask mask, void *dst) const
|
|
|
|
|
{
|
|
|
|
|
for (const int64_t i : mask.index_range()) {
|
|
|
|
|
void *elem_dst = POINTER_OFFSET(dst, type_->size() * i);
|
|
|
|
|
this->get_to_uninitialized(mask[i], elem_dst);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
void GVArrayImpl::get(const int64_t index, void *r_value) const
|
2021-03-21 19:31:24 +01:00
|
|
|
{
|
|
|
|
|
type_->destruct(r_value);
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
this->get_to_uninitialized(index, r_value);
|
2021-03-21 19:31:24 +01:00
|
|
|
}
|
|
|
|
|
|
2022-06-25 17:28:49 +02:00
|
|
|
CommonVArrayInfo GVArrayImpl::common_info() const
|
2021-03-21 19:31:24 +01:00
|
|
|
{
|
2022-06-25 17:28:49 +02:00
|
|
|
return {};
|
2021-03-21 19:31:24 +01:00
|
|
|
}
|
|
|
|
|
|
2022-10-03 17:37:25 -05:00
|
|
|
bool GVArrayImpl::try_assign_VArray(void * /*varray*/) const
|
2021-04-17 15:13:20 +02:00
|
|
|
{
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
return false;
|
2021-04-17 15:13:20 +02:00
|
|
|
}
|
|
|
|
|
|
2021-10-05 11:10:25 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
/** \name #GVMutableArrayImpl
|
2021-10-05 11:10:25 +11:00
|
|
|
* \{ */
|
2021-04-17 15:13:20 +02:00
|
|
|
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
void GVMutableArrayImpl::set_by_copy(const int64_t index, const void *value)
|
2021-04-17 15:13:20 +02:00
|
|
|
{
|
|
|
|
|
BUFFER_FOR_CPP_TYPE_VALUE(*type_, buffer);
|
2021-06-28 13:13:52 +02:00
|
|
|
type_->copy_construct(value, buffer);
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
this->set_by_move(index, buffer);
|
2021-04-17 15:13:20 +02:00
|
|
|
type_->destruct(buffer);
|
|
|
|
|
}
|
|
|
|
|
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
void GVMutableArrayImpl::set_by_relocate(const int64_t index, void *value)
|
2021-04-17 15:13:20 +02:00
|
|
|
{
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
this->set_by_move(index, value);
|
2021-04-17 15:13:20 +02:00
|
|
|
type_->destruct(value);
|
|
|
|
|
}
|
|
|
|
|
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
void GVMutableArrayImpl::set_all(const void *src)
|
2021-05-13 17:47:46 -05:00
|
|
|
{
|
2022-06-25 17:28:49 +02:00
|
|
|
const CommonVArrayInfo info = this->common_info();
|
|
|
|
|
if (info.type == CommonVArrayInfo::Type::Span) {
|
|
|
|
|
type_->copy_assign_n(src, const_cast<void *>(info.data), size_);
|
2021-05-13 17:47:46 -05:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
for (int64_t i : IndexRange(size_)) {
|
|
|
|
|
this->set_by_copy(i, POINTER_OFFSET(src, type_->size() * i));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-17 15:13:20 +02:00
|
|
|
void GVMutableArray::fill(const void *value)
|
|
|
|
|
{
|
2022-06-25 17:28:49 +02:00
|
|
|
const CommonVArrayInfo info = this->common_info();
|
|
|
|
|
if (info.type == CommonVArrayInfo::Type::Span) {
|
|
|
|
|
this->type().fill_assign_n(value, const_cast<void *>(info.data), this->size());
|
2021-04-17 15:13:20 +02:00
|
|
|
}
|
|
|
|
|
else {
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
for (int64_t i : IndexRange(this->size())) {
|
2021-04-17 15:13:20 +02:00
|
|
|
this->set_by_copy(i, value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-03 17:37:25 -05:00
|
|
|
bool GVMutableArrayImpl::try_assign_VMutableArray(void * /*varray*/) const
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-05 11:10:25 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
/** \name #GVArrayImpl_For_GSpan
|
2021-10-05 11:10:25 +11:00
|
|
|
* \{ */
|
2021-04-17 15:13:20 +02:00
|
|
|
|
2021-11-26 14:47:02 +01:00
|
|
|
void GVArrayImpl_For_GSpan::get(const int64_t index, void *r_value) const
|
2021-04-17 15:13:20 +02:00
|
|
|
{
|
2021-06-28 13:13:52 +02:00
|
|
|
type_->copy_assign(POINTER_OFFSET(data_, element_size_ * index), r_value);
|
2021-04-17 15:13:20 +02:00
|
|
|
}
|
|
|
|
|
|
2021-11-26 14:47:02 +01:00
|
|
|
void GVArrayImpl_For_GSpan::get_to_uninitialized(const int64_t index, void *r_value) const
|
2021-04-17 15:13:20 +02:00
|
|
|
{
|
2021-06-28 13:13:52 +02:00
|
|
|
type_->copy_construct(POINTER_OFFSET(data_, element_size_ * index), r_value);
|
2021-04-17 15:13:20 +02:00
|
|
|
}
|
|
|
|
|
|
2021-11-26 14:47:02 +01:00
|
|
|
void GVArrayImpl_For_GSpan::set_by_copy(const int64_t index, const void *value)
|
2021-04-17 15:13:20 +02:00
|
|
|
{
|
2021-06-28 13:13:52 +02:00
|
|
|
type_->copy_assign(value, POINTER_OFFSET(data_, element_size_ * index));
|
2021-04-17 15:13:20 +02:00
|
|
|
}
|
|
|
|
|
|
2021-11-26 14:47:02 +01:00
|
|
|
void GVArrayImpl_For_GSpan::set_by_move(const int64_t index, void *value)
|
2021-04-17 15:13:20 +02:00
|
|
|
{
|
2021-06-28 13:13:52 +02:00
|
|
|
type_->move_construct(value, POINTER_OFFSET(data_, element_size_ * index));
|
2021-04-17 15:13:20 +02:00
|
|
|
}
|
|
|
|
|
|
2021-11-26 14:47:02 +01:00
|
|
|
void GVArrayImpl_For_GSpan::set_by_relocate(const int64_t index, void *value)
|
2021-04-17 15:13:20 +02:00
|
|
|
{
|
2021-06-28 13:13:52 +02:00
|
|
|
type_->relocate_assign(value, POINTER_OFFSET(data_, element_size_ * index));
|
2021-04-17 15:13:20 +02:00
|
|
|
}
|
|
|
|
|
|
2022-06-25 17:28:49 +02:00
|
|
|
CommonVArrayInfo GVArrayImpl_For_GSpan::common_info() const
|
2021-04-17 15:13:20 +02:00
|
|
|
{
|
2022-06-25 17:28:49 +02:00
|
|
|
return CommonVArrayInfo{CommonVArrayInfo::Type::Span, true, data_};
|
2021-04-17 15:13:20 +02:00
|
|
|
}
|
|
|
|
|
|
2022-04-07 10:02:34 +02:00
|
|
|
void GVArrayImpl_For_GSpan::materialize(const IndexMask mask, void *dst) const
|
|
|
|
|
{
|
|
|
|
|
type_->copy_assign_indices(data_, dst, mask);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GVArrayImpl_For_GSpan::materialize_to_uninitialized(const IndexMask mask, void *dst) const
|
|
|
|
|
{
|
|
|
|
|
type_->copy_construct_indices(data_, dst, mask);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GVArrayImpl_For_GSpan::materialize_compressed(const IndexMask mask, void *dst) const
|
|
|
|
|
{
|
|
|
|
|
type_->copy_assign_compressed(data_, dst, mask);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GVArrayImpl_For_GSpan::materialize_compressed_to_uninitialized(const IndexMask mask,
|
|
|
|
|
void *dst) const
|
|
|
|
|
{
|
|
|
|
|
type_->copy_construct_compressed(data_, dst, mask);
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-05 11:10:25 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
/** \name #GVArrayImpl_For_SingleValueRef
|
2021-10-05 11:10:25 +11:00
|
|
|
* \{ */
|
2021-04-17 15:13:20 +02:00
|
|
|
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
/* Generic virtual array where each element has the same value. The value is not owned. */
|
2021-03-21 19:31:24 +01:00
|
|
|
|
2022-10-03 17:37:25 -05:00
|
|
|
void GVArrayImpl_For_SingleValueRef::get(const int64_t /*index*/, void *r_value) const
|
2022-05-31 20:41:01 +02:00
|
|
|
{
|
|
|
|
|
type_->copy_assign(value_, r_value);
|
|
|
|
|
}
|
2022-10-03 17:37:25 -05:00
|
|
|
void GVArrayImpl_For_SingleValueRef::get_to_uninitialized(const int64_t /*index*/,
|
2022-05-31 20:41:01 +02:00
|
|
|
void *r_value) const
|
|
|
|
|
{
|
|
|
|
|
type_->copy_construct(value_, r_value);
|
|
|
|
|
}
|
2022-04-07 10:02:34 +02:00
|
|
|
|
2022-06-25 17:28:49 +02:00
|
|
|
CommonVArrayInfo GVArrayImpl_For_SingleValueRef::common_info() const
|
2022-05-31 20:41:01 +02:00
|
|
|
{
|
2022-06-25 17:28:49 +02:00
|
|
|
return CommonVArrayInfo{CommonVArrayInfo::Type::Single, true, value_};
|
2022-05-31 20:41:01 +02:00
|
|
|
}
|
2022-04-07 10:02:34 +02:00
|
|
|
|
2022-05-31 20:41:01 +02:00
|
|
|
void GVArrayImpl_For_SingleValueRef::materialize(const IndexMask mask, void *dst) const
|
|
|
|
|
{
|
|
|
|
|
type_->fill_assign_indices(value_, dst, mask);
|
|
|
|
|
}
|
2022-04-07 10:02:34 +02:00
|
|
|
|
2022-05-31 20:41:01 +02:00
|
|
|
void GVArrayImpl_For_SingleValueRef::materialize_to_uninitialized(const IndexMask mask,
|
|
|
|
|
void *dst) const
|
|
|
|
|
{
|
|
|
|
|
type_->fill_construct_indices(value_, dst, mask);
|
|
|
|
|
}
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
|
2022-05-31 20:41:01 +02:00
|
|
|
void GVArrayImpl_For_SingleValueRef::materialize_compressed(const IndexMask mask, void *dst) const
|
|
|
|
|
{
|
|
|
|
|
type_->fill_assign_n(value_, dst, mask.size());
|
|
|
|
|
}
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
|
2022-05-31 20:41:01 +02:00
|
|
|
void GVArrayImpl_For_SingleValueRef::materialize_compressed_to_uninitialized(const IndexMask mask,
|
|
|
|
|
void *dst) const
|
|
|
|
|
{
|
|
|
|
|
type_->fill_construct_n(value_, dst, mask.size());
|
|
|
|
|
}
|
2021-03-21 19:31:24 +01:00
|
|
|
|
2021-10-05 11:10:25 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
/** \name #GVArrayImpl_For_SingleValue
|
2021-10-05 11:10:25 +11:00
|
|
|
* \{ */
|
2021-04-17 15:13:20 +02:00
|
|
|
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
/* Same as GVArrayImpl_For_SingleValueRef, but the value is owned. */
|
|
|
|
|
class GVArrayImpl_For_SingleValue : public GVArrayImpl_For_SingleValueRef,
|
|
|
|
|
NonCopyable,
|
|
|
|
|
NonMovable {
|
|
|
|
|
public:
|
|
|
|
|
GVArrayImpl_For_SingleValue(const CPPType &type, const int64_t size, const void *value)
|
|
|
|
|
: GVArrayImpl_For_SingleValueRef(type, size)
|
|
|
|
|
{
|
|
|
|
|
value_ = MEM_mallocN_aligned(type.size(), type.alignment(), __func__);
|
|
|
|
|
type.copy_construct(value, (void *)value_);
|
|
|
|
|
}
|
2021-04-17 15:13:20 +02:00
|
|
|
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
~GVArrayImpl_For_SingleValue() override
|
|
|
|
|
{
|
|
|
|
|
type_->destruct((void *)value_);
|
|
|
|
|
MEM_freeN((void *)value_);
|
|
|
|
|
}
|
|
|
|
|
};
|
2021-04-17 15:13:20 +02:00
|
|
|
|
2021-10-05 11:10:25 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
2021-11-26 09:59:41 +01:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name #GVArrayImpl_For_SmallTrivialSingleValue
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Contains an inline buffer that can store a single value of a trivial type.
|
|
|
|
|
* This avoids the allocation that would be done by #GVArrayImpl_For_SingleValue.
|
|
|
|
|
*/
|
|
|
|
|
template<int BufferSize> class GVArrayImpl_For_SmallTrivialSingleValue : public GVArrayImpl {
|
|
|
|
|
private:
|
|
|
|
|
AlignedBuffer<BufferSize, 8> buffer_;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
GVArrayImpl_For_SmallTrivialSingleValue(const CPPType &type,
|
|
|
|
|
const int64_t size,
|
|
|
|
|
const void *value)
|
|
|
|
|
: GVArrayImpl(type, size)
|
|
|
|
|
{
|
|
|
|
|
BLI_assert(type.is_trivial());
|
|
|
|
|
BLI_assert(type.alignment() <= 8);
|
|
|
|
|
BLI_assert(type.size() <= BufferSize);
|
|
|
|
|
type.copy_construct(value, &buffer_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
2022-10-03 17:37:25 -05:00
|
|
|
void get(const int64_t /*index*/, void *r_value) const override
|
2021-11-26 09:59:41 +01:00
|
|
|
{
|
|
|
|
|
this->copy_value_to(r_value);
|
|
|
|
|
}
|
2022-10-03 17:37:25 -05:00
|
|
|
void get_to_uninitialized(const int64_t /*index*/, void *r_value) const override
|
2021-11-26 09:59:41 +01:00
|
|
|
{
|
|
|
|
|
this->copy_value_to(r_value);
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-25 17:28:49 +02:00
|
|
|
void copy_value_to(void *dst) const
|
2021-11-26 09:59:41 +01:00
|
|
|
{
|
2022-06-25 17:28:49 +02:00
|
|
|
memcpy(dst, &buffer_, type_->size());
|
2021-11-26 09:59:41 +01:00
|
|
|
}
|
|
|
|
|
|
2022-06-25 17:28:49 +02:00
|
|
|
CommonVArrayInfo common_info() const override
|
2021-11-26 09:59:41 +01:00
|
|
|
{
|
2022-06-25 17:28:49 +02:00
|
|
|
return CommonVArrayInfo{CommonVArrayInfo::Type::Single, true, &buffer_};
|
2021-11-26 09:59:41 +01:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
|
2021-10-05 11:10:25 +11:00
|
|
|
/* -------------------------------------------------------------------- */
|
2022-07-02 11:45:57 +02:00
|
|
|
/** \name #GVArraySpan
|
2021-10-05 11:10:25 +11:00
|
|
|
* \{ */
|
2021-04-17 15:13:20 +02:00
|
|
|
|
2022-07-07 19:19:01 +02:00
|
|
|
GVArraySpan::GVArraySpan() = default;
|
|
|
|
|
|
|
|
|
|
GVArraySpan::GVArraySpan(GVArray varray)
|
|
|
|
|
: GSpan(varray ? &varray.type() : nullptr), varray_(std::move(varray))
|
2021-04-17 15:13:20 +02:00
|
|
|
{
|
2022-07-07 19:19:01 +02:00
|
|
|
if (!varray_) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-17 15:13:20 +02:00
|
|
|
size_ = varray_.size();
|
2022-06-25 17:28:49 +02:00
|
|
|
const CommonVArrayInfo info = varray_.common_info();
|
|
|
|
|
if (info.type == CommonVArrayInfo::Type::Span) {
|
|
|
|
|
data_ = info.data;
|
2021-04-17 15:13:20 +02:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
owned_data_ = MEM_mallocN_aligned(type_->size() * size_, type_->alignment(), __func__);
|
|
|
|
|
varray_.materialize_to_uninitialized(IndexRange(size_), owned_data_);
|
|
|
|
|
data_ = owned_data_;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-02 11:45:57 +02:00
|
|
|
GVArraySpan::GVArraySpan(GVArraySpan &&other)
|
2022-07-07 19:19:01 +02:00
|
|
|
: GSpan(other.type_ptr()), varray_(std::move(other.varray_)), owned_data_(other.owned_data_)
|
2022-07-02 11:45:57 +02:00
|
|
|
{
|
2022-07-07 19:19:01 +02:00
|
|
|
if (!varray_) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-02 11:45:57 +02:00
|
|
|
size_ = varray_.size();
|
|
|
|
|
const CommonVArrayInfo info = varray_.common_info();
|
|
|
|
|
if (info.type == CommonVArrayInfo::Type::Span) {
|
|
|
|
|
data_ = info.data;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
data_ = owned_data_;
|
|
|
|
|
}
|
2022-07-12 18:47:32 +02:00
|
|
|
other.owned_data_ = nullptr;
|
2022-07-02 11:45:57 +02:00
|
|
|
other.data_ = nullptr;
|
|
|
|
|
other.size_ = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GVArraySpan::~GVArraySpan()
|
2021-04-17 15:13:20 +02:00
|
|
|
{
|
|
|
|
|
if (owned_data_ != nullptr) {
|
|
|
|
|
type_->destruct_n(owned_data_, size_);
|
|
|
|
|
MEM_freeN(owned_data_);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-02 11:45:57 +02:00
|
|
|
GVArraySpan &GVArraySpan::operator=(GVArraySpan &&other)
|
|
|
|
|
{
|
|
|
|
|
if (this == &other) {
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
std::destroy_at(this);
|
|
|
|
|
new (this) GVArraySpan(std::move(other));
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-05 11:10:25 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
2022-07-02 11:45:57 +02:00
|
|
|
/** \name #GMutableVArraySpan
|
2021-10-05 11:10:25 +11:00
|
|
|
* \{ */
|
2021-04-17 15:13:20 +02:00
|
|
|
|
2022-07-07 19:19:01 +02:00
|
|
|
GMutableVArraySpan::GMutableVArraySpan() = default;
|
|
|
|
|
|
2022-07-02 11:45:57 +02:00
|
|
|
GMutableVArraySpan::GMutableVArraySpan(GVMutableArray varray, const bool copy_values_to_span)
|
2022-07-07 19:19:01 +02:00
|
|
|
: GMutableSpan(varray ? &varray.type() : nullptr), varray_(std::move(varray))
|
2021-04-17 15:13:20 +02:00
|
|
|
{
|
2022-07-07 19:19:01 +02:00
|
|
|
if (!varray_) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2021-04-17 15:13:20 +02:00
|
|
|
size_ = varray_.size();
|
2022-06-25 17:28:49 +02:00
|
|
|
const CommonVArrayInfo info = varray_.common_info();
|
|
|
|
|
if (info.type == CommonVArrayInfo::Type::Span) {
|
|
|
|
|
data_ = const_cast<void *>(info.data);
|
2021-04-17 15:13:20 +02:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
owned_data_ = MEM_mallocN_aligned(type_->size() * size_, type_->alignment(), __func__);
|
|
|
|
|
if (copy_values_to_span) {
|
|
|
|
|
varray_.materialize_to_uninitialized(IndexRange(size_), owned_data_);
|
|
|
|
|
}
|
|
|
|
|
else {
|
2021-06-28 13:13:52 +02:00
|
|
|
type_->default_construct_n(owned_data_, size_);
|
2021-04-17 15:13:20 +02:00
|
|
|
}
|
|
|
|
|
data_ = owned_data_;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-02 11:45:57 +02:00
|
|
|
GMutableVArraySpan::GMutableVArraySpan(GMutableVArraySpan &&other)
|
2022-07-07 19:19:01 +02:00
|
|
|
: GMutableSpan(other.type_ptr()),
|
2022-07-02 11:45:57 +02:00
|
|
|
varray_(std::move(other.varray_)),
|
|
|
|
|
owned_data_(other.owned_data_),
|
|
|
|
|
show_not_saved_warning_(other.show_not_saved_warning_)
|
2021-04-17 15:13:20 +02:00
|
|
|
{
|
2022-07-07 19:19:01 +02:00
|
|
|
if (!varray_) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2022-07-02 11:45:57 +02:00
|
|
|
size_ = varray_.size();
|
|
|
|
|
const CommonVArrayInfo info = varray_.common_info();
|
|
|
|
|
if (info.type == CommonVArrayInfo::Type::Span) {
|
|
|
|
|
data_ = const_cast<void *>(info.data);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
data_ = owned_data_;
|
|
|
|
|
}
|
2022-07-12 18:47:32 +02:00
|
|
|
other.owned_data_ = nullptr;
|
2022-07-02 11:45:57 +02:00
|
|
|
other.data_ = nullptr;
|
|
|
|
|
other.size_ = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GMutableVArraySpan::~GMutableVArraySpan()
|
|
|
|
|
{
|
|
|
|
|
if (varray_) {
|
|
|
|
|
if (show_not_saved_warning_) {
|
|
|
|
|
if (!save_has_been_called_) {
|
2022-07-21 12:47:44 +02:00
|
|
|
std::cout << "Warning: Call `save()` to make sure that changes persist in all cases.\n";
|
2022-07-02 11:45:57 +02:00
|
|
|
}
|
2021-04-17 15:13:20 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (owned_data_ != nullptr) {
|
|
|
|
|
type_->destruct_n(owned_data_, size_);
|
|
|
|
|
MEM_freeN(owned_data_);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-02 11:45:57 +02:00
|
|
|
GMutableVArraySpan &GMutableVArraySpan::operator=(GMutableVArraySpan &&other)
|
|
|
|
|
{
|
|
|
|
|
if (this == &other) {
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
std::destroy_at(this);
|
|
|
|
|
new (this) GMutableVArraySpan(std::move(other));
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GMutableVArraySpan::save()
|
2021-04-17 15:13:20 +02:00
|
|
|
{
|
|
|
|
|
save_has_been_called_ = true;
|
|
|
|
|
if (data_ != owned_data_) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2022-03-23 23:27:26 -05:00
|
|
|
varray_.set_all(owned_data_);
|
2021-04-17 15:13:20 +02:00
|
|
|
}
|
|
|
|
|
|
2022-07-02 11:45:57 +02:00
|
|
|
void GMutableVArraySpan::disable_not_applied_warning()
|
2021-04-17 15:13:20 +02:00
|
|
|
{
|
|
|
|
|
show_not_saved_warning_ = false;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-07 19:19:01 +02:00
|
|
|
const GVMutableArray &GMutableVArraySpan::varray() const
|
|
|
|
|
{
|
|
|
|
|
return varray_;
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-05 11:10:25 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
/** \name #GVArrayImpl_For_SlicedGVArray
|
2021-10-05 11:10:25 +11:00
|
|
|
* \{ */
|
2021-09-15 11:02:39 +02:00
|
|
|
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
class GVArrayImpl_For_SlicedGVArray : public GVArrayImpl {
|
|
|
|
|
protected:
|
|
|
|
|
GVArray varray_;
|
|
|
|
|
int64_t offset_;
|
2021-11-26 13:29:24 +01:00
|
|
|
IndexRange slice_;
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
GVArrayImpl_For_SlicedGVArray(GVArray varray, const IndexRange slice)
|
|
|
|
|
: GVArrayImpl(varray.type(), slice.size()),
|
|
|
|
|
varray_(std::move(varray)),
|
2021-11-26 13:29:24 +01:00
|
|
|
offset_(slice.start()),
|
|
|
|
|
slice_(slice)
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
{
|
|
|
|
|
BLI_assert(slice.one_after_last() <= varray_.size());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void get(const int64_t index, void *r_value) const override
|
|
|
|
|
{
|
|
|
|
|
varray_.get(index + offset_, r_value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void get_to_uninitialized(const int64_t index, void *r_value) const override
|
|
|
|
|
{
|
|
|
|
|
varray_.get_to_uninitialized(index + offset_, r_value);
|
|
|
|
|
}
|
2021-11-26 10:08:19 +01:00
|
|
|
|
2022-06-25 18:10:22 +02:00
|
|
|
CommonVArrayInfo common_info() const override
|
2021-11-26 10:08:19 +01:00
|
|
|
{
|
2022-06-25 17:28:49 +02:00
|
|
|
const CommonVArrayInfo internal_info = varray_.common_info();
|
|
|
|
|
switch (internal_info.type) {
|
|
|
|
|
case CommonVArrayInfo::Type::Any: {
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
case CommonVArrayInfo::Type::Span: {
|
|
|
|
|
return CommonVArrayInfo(CommonVArrayInfo::Type::Span,
|
|
|
|
|
internal_info.may_have_ownership,
|
|
|
|
|
POINTER_OFFSET(internal_info.data, type_->size() * offset_));
|
|
|
|
|
}
|
|
|
|
|
case CommonVArrayInfo::Type::Single: {
|
|
|
|
|
return internal_info;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
BLI_assert_unreachable();
|
|
|
|
|
return {};
|
2021-11-26 10:08:19 +01:00
|
|
|
}
|
2022-04-07 10:02:34 +02:00
|
|
|
|
|
|
|
|
void materialize_compressed_to_uninitialized(const IndexMask mask, void *dst) const override
|
|
|
|
|
{
|
|
|
|
|
if (mask.is_range()) {
|
|
|
|
|
const IndexRange mask_range = mask.as_range();
|
|
|
|
|
const IndexRange offset_mask_range{mask_range.start() + offset_, mask_range.size()};
|
|
|
|
|
varray_.materialize_compressed_to_uninitialized(offset_mask_range, dst);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
Vector<int64_t, 32> offset_mask_indices(mask.size());
|
|
|
|
|
for (const int64_t i : mask.index_range()) {
|
|
|
|
|
offset_mask_indices[i] = mask[i] + offset_;
|
|
|
|
|
}
|
|
|
|
|
varray_.materialize_compressed_to_uninitialized(offset_mask_indices.as_span(), dst);
|
|
|
|
|
}
|
|
|
|
|
}
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name #GVArrayCommon
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
GVArrayCommon::GVArrayCommon(const GVArrayCommon &other) : storage_(other.storage_)
|
|
|
|
|
{
|
|
|
|
|
impl_ = this->impl_from_storage();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GVArrayCommon::GVArrayCommon(GVArrayCommon &&other) noexcept : storage_(std::move(other.storage_))
|
|
|
|
|
{
|
|
|
|
|
impl_ = this->impl_from_storage();
|
|
|
|
|
other.storage_.reset();
|
|
|
|
|
other.impl_ = nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GVArrayCommon::GVArrayCommon(const GVArrayImpl *impl) : impl_(impl)
|
|
|
|
|
{
|
|
|
|
|
storage_ = impl_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GVArrayCommon::GVArrayCommon(std::shared_ptr<const GVArrayImpl> impl) : impl_(impl.get())
|
|
|
|
|
{
|
|
|
|
|
if (impl) {
|
|
|
|
|
storage_ = std::move(impl);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GVArrayCommon::~GVArrayCommon() = default;
|
|
|
|
|
|
|
|
|
|
void GVArrayCommon::materialize(void *dst) const
|
|
|
|
|
{
|
|
|
|
|
this->materialize(IndexMask(impl_->size()), dst);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GVArrayCommon::materialize(const IndexMask mask, void *dst) const
|
|
|
|
|
{
|
|
|
|
|
impl_->materialize(mask, dst);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GVArrayCommon::materialize_to_uninitialized(void *dst) const
|
|
|
|
|
{
|
|
|
|
|
this->materialize_to_uninitialized(IndexMask(impl_->size()), dst);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GVArrayCommon::materialize_to_uninitialized(const IndexMask mask, void *dst) const
|
|
|
|
|
{
|
|
|
|
|
BLI_assert(mask.min_array_size() <= impl_->size());
|
|
|
|
|
impl_->materialize_to_uninitialized(mask, dst);
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-07 10:02:34 +02:00
|
|
|
void GVArrayCommon::materialize_compressed(IndexMask mask, void *dst) const
|
|
|
|
|
{
|
|
|
|
|
impl_->materialize_compressed(mask, dst);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GVArrayCommon::materialize_compressed_to_uninitialized(IndexMask mask, void *dst) const
|
|
|
|
|
{
|
|
|
|
|
impl_->materialize_compressed_to_uninitialized(mask, dst);
|
|
|
|
|
}
|
|
|
|
|
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
void GVArrayCommon::copy_from(const GVArrayCommon &other)
|
|
|
|
|
{
|
|
|
|
|
if (this == &other) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
storage_ = other.storage_;
|
|
|
|
|
impl_ = this->impl_from_storage();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GVArrayCommon::move_from(GVArrayCommon &&other) noexcept
|
|
|
|
|
{
|
|
|
|
|
if (this == &other) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
storage_ = std::move(other.storage_);
|
|
|
|
|
impl_ = this->impl_from_storage();
|
|
|
|
|
other.storage_.reset();
|
|
|
|
|
other.impl_ = nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool GVArrayCommon::is_span() const
|
|
|
|
|
{
|
2022-06-25 17:28:49 +02:00
|
|
|
const CommonVArrayInfo info = impl_->common_info();
|
|
|
|
|
return info.type == CommonVArrayInfo::Type::Span;
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GSpan GVArrayCommon::get_internal_span() const
|
2021-09-15 11:02:39 +02:00
|
|
|
{
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
BLI_assert(this->is_span());
|
2022-06-25 17:28:49 +02:00
|
|
|
const CommonVArrayInfo info = impl_->common_info();
|
|
|
|
|
return GSpan(this->type(), info.data, this->size());
|
2021-09-15 11:02:39 +02:00
|
|
|
}
|
|
|
|
|
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
bool GVArrayCommon::is_single() const
|
2021-09-15 11:02:39 +02:00
|
|
|
{
|
2022-06-25 17:28:49 +02:00
|
|
|
const CommonVArrayInfo info = impl_->common_info();
|
|
|
|
|
return info.type == CommonVArrayInfo::Type::Single;
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GVArrayCommon::get_internal_single(void *r_value) const
|
|
|
|
|
{
|
|
|
|
|
BLI_assert(this->is_single());
|
2022-06-25 17:28:49 +02:00
|
|
|
const CommonVArrayInfo info = impl_->common_info();
|
|
|
|
|
this->type().copy_assign(info.data, r_value);
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GVArrayCommon::get_internal_single_to_uninitialized(void *r_value) const
|
|
|
|
|
{
|
|
|
|
|
impl_->type().default_construct(r_value);
|
|
|
|
|
this->get_internal_single(r_value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const GVArrayImpl *GVArrayCommon::impl_from_storage() const
|
|
|
|
|
{
|
2022-04-25 11:51:22 +02:00
|
|
|
if (!storage_.has_value()) {
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
return storage_.extra_info().get_varray(storage_.get());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IndexRange GVArrayCommon::index_range() const
|
|
|
|
|
{
|
|
|
|
|
return IndexRange(this->size());
|
2021-09-15 11:02:39 +02:00
|
|
|
}
|
|
|
|
|
|
2021-10-05 11:10:25 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
/** \name #GVArray
|
2021-10-05 11:10:25 +11:00
|
|
|
* \{ */
|
2021-09-15 11:02:39 +02:00
|
|
|
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
GVArray::GVArray(const GVArray &other) = default;
|
|
|
|
|
|
|
|
|
|
GVArray::GVArray(GVArray &&other) noexcept = default;
|
|
|
|
|
|
|
|
|
|
GVArray::GVArray(const GVArrayImpl *impl) : GVArrayCommon(impl)
|
2021-09-15 11:02:39 +02:00
|
|
|
{
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GVArray::GVArray(std::shared_ptr<const GVArrayImpl> impl) : GVArrayCommon(std::move(impl))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-31 20:41:01 +02:00
|
|
|
GVArray::GVArray(varray_tag::single /* tag */,
|
|
|
|
|
const CPPType &type,
|
|
|
|
|
int64_t size,
|
|
|
|
|
const void *value)
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
{
|
2021-11-26 09:59:41 +01:00
|
|
|
if (type.is_trivial() && type.size() <= 16 && type.alignment() <= 8) {
|
2022-05-31 20:41:01 +02:00
|
|
|
this->emplace<GVArrayImpl_For_SmallTrivialSingleValue<16>>(type, size, value);
|
2021-11-26 09:59:41 +01:00
|
|
|
}
|
2022-05-31 20:41:01 +02:00
|
|
|
else {
|
|
|
|
|
this->emplace<GVArrayImpl_For_SingleValue>(type, size, value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GVArray GVArray::ForSingle(const CPPType &type, const int64_t size, const void *value)
|
|
|
|
|
{
|
|
|
|
|
return GVArray(varray_tag::single{}, type, size, value);
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GVArray GVArray::ForSingleRef(const CPPType &type, const int64_t size, const void *value)
|
|
|
|
|
{
|
2022-05-31 20:41:01 +02:00
|
|
|
return GVArray(varray_tag::single_ref{}, type, size, value);
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GVArray GVArray::ForSingleDefault(const CPPType &type, const int64_t size)
|
|
|
|
|
{
|
|
|
|
|
return GVArray::ForSingleRef(type, size, type.default_value());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GVArray GVArray::ForSpan(GSpan span)
|
|
|
|
|
{
|
2022-05-31 20:41:01 +02:00
|
|
|
return GVArray(varray_tag::span{}, span);
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class GVArrayImpl_For_GArray : public GVArrayImpl_For_GSpan {
|
|
|
|
|
protected:
|
|
|
|
|
GArray<> array_;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
GVArrayImpl_For_GArray(GArray<> array)
|
2021-11-26 14:47:02 +01:00
|
|
|
: GVArrayImpl_For_GSpan(array.as_mutable_span()), array_(std::move(array))
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
{
|
2021-09-15 11:02:39 +02:00
|
|
|
}
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
GVArray GVArray::ForGArray(GArray<> array)
|
|
|
|
|
{
|
|
|
|
|
return GVArray::For<GVArrayImpl_For_GArray>(array);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GVArray GVArray::ForEmpty(const CPPType &type)
|
|
|
|
|
{
|
|
|
|
|
return GVArray::ForSpan(GSpan(type));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GVArray GVArray::slice(IndexRange slice) const
|
|
|
|
|
{
|
2022-07-04 15:30:42 -05:00
|
|
|
const CommonVArrayInfo info = this->common_info();
|
|
|
|
|
if (info.type == CommonVArrayInfo::Type::Single) {
|
|
|
|
|
return GVArray::ForSingle(this->type(), slice.size(), info.data);
|
|
|
|
|
}
|
|
|
|
|
/* Need to check for ownership, because otherwise the referenced data can be destructed when
|
|
|
|
|
* #this is destructed. */
|
|
|
|
|
if (info.type == CommonVArrayInfo::Type::Span && !info.may_have_ownership) {
|
|
|
|
|
return GVArray::ForSpan(GSpan(this->type(), info.data, this->size()).slice(slice));
|
|
|
|
|
}
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
return GVArray::For<GVArrayImpl_For_SlicedGVArray>(*this, slice);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GVArray &GVArray::operator=(const GVArray &other)
|
|
|
|
|
{
|
|
|
|
|
this->copy_from(other);
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GVArray &GVArray::operator=(GVArray &&other) noexcept
|
|
|
|
|
{
|
|
|
|
|
this->move_from(std::move(other));
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name #GVMutableArray
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
GVMutableArray::GVMutableArray(const GVMutableArray &other) = default;
|
|
|
|
|
GVMutableArray::GVMutableArray(GVMutableArray &&other) noexcept = default;
|
|
|
|
|
|
|
|
|
|
GVMutableArray::GVMutableArray(GVMutableArrayImpl *impl) : GVArrayCommon(impl)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GVMutableArray::GVMutableArray(std::shared_ptr<GVMutableArrayImpl> impl)
|
|
|
|
|
: GVArrayCommon(std::move(impl))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GVMutableArray GVMutableArray::ForSpan(GMutableSpan span)
|
|
|
|
|
{
|
2021-11-26 14:47:02 +01:00
|
|
|
return GVMutableArray::For<GVArrayImpl_For_GSpan_final>(span);
|
Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.
As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).
With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.
Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.
To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.
Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:15:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GVMutableArray::operator GVArray() const &
|
|
|
|
|
{
|
|
|
|
|
GVArray varray;
|
|
|
|
|
varray.copy_from(*this);
|
|
|
|
|
return varray;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GVMutableArray::operator GVArray() &&noexcept
|
|
|
|
|
{
|
|
|
|
|
GVArray varray;
|
|
|
|
|
varray.move_from(std::move(*this));
|
|
|
|
|
return varray;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GVMutableArray &GVMutableArray::operator=(const GVMutableArray &other)
|
|
|
|
|
{
|
|
|
|
|
this->copy_from(other);
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GVMutableArray &GVMutableArray::operator=(GVMutableArray &&other) noexcept
|
|
|
|
|
{
|
|
|
|
|
this->move_from(std::move(other));
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GVMutableArrayImpl *GVMutableArray::get_implementation() const
|
|
|
|
|
{
|
|
|
|
|
return this->get_impl();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GVMutableArray::set_all(const void *src)
|
|
|
|
|
{
|
|
|
|
|
this->get_impl()->set_all(src);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GMutableSpan GVMutableArray::get_internal_span() const
|
|
|
|
|
{
|
|
|
|
|
BLI_assert(this->is_span());
|
2022-06-25 17:28:49 +02:00
|
|
|
const CommonVArrayInfo info = impl_->common_info();
|
|
|
|
|
return GMutableSpan(this->type(), const_cast<void *>(info.data), this->size());
|
2021-09-15 11:02:39 +02:00
|
|
|
}
|
|
|
|
|
|
2021-10-05 11:10:25 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
2022-06-25 17:28:49 +02:00
|
|
|
CommonVArrayInfo GVArrayImpl_For_GSpan_final::common_info() const
|
|
|
|
|
{
|
|
|
|
|
return CommonVArrayInfo(CommonVArrayInfo::Type::Span, false, data_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CommonVArrayInfo GVArrayImpl_For_SingleValueRef_final::common_info() const
|
|
|
|
|
{
|
|
|
|
|
return CommonVArrayInfo(CommonVArrayInfo::Type::Single, false, value_);
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-19 08:26:29 +01:00
|
|
|
} // namespace blender
|