BLI: improve span access to virtual arrays

* Make the class names more consistent.
* Implement missing move-constructors and assignment-operators.
This commit is contained in:
Jacques Lucke 2022-07-02 11:45:57 +02:00
parent 3c60d62dba
commit 5d9ade27de
23 changed files with 180 additions and 90 deletions

View File

@ -218,7 +218,7 @@ struct WriteAttributeLookup {
* Supported convenience features:
* - Implicit type conversion when writing to builtin attributes.
* - Supports simple access to a span containing the attribute values (that avoids the use of
* VMutableArray_Span in many cases).
* MutableVArraySpan in many cases).
* - An output attribute can live side by side with an existing attribute with a different domain
* or data type. The old attribute will only be overwritten when the #save function is called.
*
@ -234,7 +234,7 @@ class OutputAttribute {
GVMutableArray varray_;
eAttrDomain domain_ = ATTR_DOMAIN_AUTO;
SaveFn save_;
std::unique_ptr<GVMutableArray_GSpan> optional_span_varray_;
std::unique_ptr<GMutableVArraySpan> optional_span_varray_;
bool ignore_old_values_ = false;
bool save_has_been_called_ = false;

View File

@ -155,10 +155,9 @@ GMutableSpan OutputAttribute::as_span()
{
if (!optional_span_varray_) {
const bool materialize_old_values = !ignore_old_values_;
optional_span_varray_ = std::make_unique<GVMutableArray_GSpan>(varray_,
materialize_old_values);
optional_span_varray_ = std::make_unique<GMutableVArraySpan>(varray_, materialize_old_values);
}
GVMutableArray_GSpan &span_varray = *optional_span_varray_;
GMutableVArraySpan &span_varray = *optional_span_varray_;
return span_varray;
}

View File

@ -21,14 +21,14 @@ using blender::Array;
using blender::float3;
using blender::float4x4;
using blender::GVArray;
using blender::GVArray_GSpan;
using blender::GVArraySpan;
using blender::IndexRange;
using blender::Map;
using blender::MutableSpan;
using blender::Span;
using blender::StringRefNull;
using blender::VArray;
using blender::VArray_Span;
using blender::VArraySpan;
using blender::Vector;
using blender::bke::AttributeIDRef;
using blender::bke::OutputAttribute;
@ -360,7 +360,7 @@ static void copy_attributes_between_components(const GeometryComponent &src_comp
if (!src_attribute) {
return true;
}
GVArray_GSpan src_attribute_data{src_attribute};
GVArraySpan src_attribute_data{src_attribute};
OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only(
id, meta_data.domain, meta_data.data_type);
@ -383,16 +383,16 @@ std::unique_ptr<CurveEval> curves_to_curve_eval(const Curves &curves_id)
VArray<int> resolution = curves.resolution();
VArray<int8_t> normal_mode = curves.normal_mode();
VArray_Span<float> nurbs_weights{
VArraySpan<float> nurbs_weights{
src_component.attribute_get_for_read<float>("nurbs_weight", ATTR_DOMAIN_POINT, 0.0f)};
VArray_Span<int8_t> nurbs_orders{
VArraySpan<int8_t> nurbs_orders{
src_component.attribute_get_for_read<int8_t>("nurbs_order", ATTR_DOMAIN_CURVE, 4)};
VArray_Span<int8_t> nurbs_knots_modes{
VArraySpan<int8_t> nurbs_knots_modes{
src_component.attribute_get_for_read<int8_t>("knots_mode", ATTR_DOMAIN_CURVE, 0)};
VArray_Span<int8_t> handle_types_right{
VArraySpan<int8_t> handle_types_right{
src_component.attribute_get_for_read<int8_t>("handle_type_right", ATTR_DOMAIN_POINT, 0)};
VArray_Span<int8_t> handle_types_left{
VArraySpan<int8_t> handle_types_left{
src_component.attribute_get_for_read<int8_t>("handle_type_left", ATTR_DOMAIN_POINT, 0)};
/* Create splines with the correct size and type. */

View File

@ -228,8 +228,8 @@ struct CurvesInfo {
const CurvesGeometry &profile;
/* Make sure these are spans because they are potentially accessed many times. */
VArray_Span<bool> main_cyclic;
VArray_Span<bool> profile_cyclic;
VArraySpan<bool> main_cyclic;
VArraySpan<bool> profile_cyclic;
};
static CurvesInfo get_curves_info(const CurvesGeometry &main, const CurvesGeometry &profile)
{
@ -700,8 +700,8 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main,
if (profile.curve_type_counts()[CURVE_TYPE_BEZIER] > 0) {
const VArray<int8_t> curve_types = profile.curve_types();
const VArray_Span<int8_t> handle_types_left{profile.handle_types_left()};
const VArray_Span<int8_t> handle_types_right{profile.handle_types_right()};
const VArraySpan<int8_t> handle_types_left{profile.handle_types_left()};
const VArraySpan<int8_t> handle_types_right{profile.handle_types_right()};
foreach_curve_combination(curves_info, offsets, [&](const CombinationInfo &info) {
if (curve_types[info.i_profile] == CURVE_TYPE_BEZIER) {

View File

@ -477,8 +477,8 @@ static void calculate_evaluated_offsets(const CurvesGeometry &curves,
VArray<int> resolution = curves.resolution();
VArray<bool> cyclic = curves.cyclic();
VArray_Span<int8_t> handle_types_left{curves.handle_types_left()};
VArray_Span<int8_t> handle_types_right{curves.handle_types_right()};
VArraySpan<int8_t> handle_types_left{curves.handle_types_left()};
VArraySpan<int8_t> handle_types_right{curves.handle_types_right()};
VArray<int8_t> nurbs_orders = curves.nurbs_orders();
VArray<int8_t> nurbs_knots_modes = curves.nurbs_knots_modes();
@ -1013,8 +1013,8 @@ void CurvesGeometry::calculate_bezier_auto_handles()
return;
}
const VArray<bool> cyclic = this->cyclic();
const VArray_Span<int8_t> types_left{this->handle_types_left()};
const VArray_Span<int8_t> types_right{this->handle_types_right()};
const VArraySpan<int8_t> types_left{this->handle_types_left()};
const VArraySpan<int8_t> types_right{this->handle_types_right()};
const Span<float3> positions = this->positions();
MutableSpan<float3> positions_left = this->handle_positions_left_for_write();
MutableSpan<float3> positions_right = this->handle_positions_right_for_write();

View File

@ -17,7 +17,7 @@
using blender::GMutableSpan;
using blender::GSpan;
using blender::GVArray;
using blender::GVArray_GSpan;
using blender::GVArraySpan;
/* -------------------------------------------------------------------- */
/** \name Geometry Component Implementation
@ -231,7 +231,7 @@ template<typename T> class VArray_For_SplineToPoint final : public VArrayImpl<T>
GVArray original_varray_;
/* Store existing data materialized if it was not already a span. This is expected
* to be worth it because a single spline's value will likely be accessed many times. */
VArray_Span<T> original_data_;
VArraySpan<T> original_data_;
Array<int> offsets_;
public:
@ -645,8 +645,8 @@ static bool create_point_attribute(GeometryComponent &component,
GVArray source_varray = varray_from_initializer(initializer, data_type, splines);
/* TODO: When we can call a variant of #set_all with a virtual array argument,
* this theoretically unnecessary materialize step could be removed. */
GVArray_GSpan source_varray_span{source_varray};
write_attribute.varray.set_all(source_varray_span.data());
GVArraySpan source_VArraySpan{source_varray};
write_attribute.varray.set_all(source_VArraySpan.data());
if (initializer.type == AttributeInit::Type::MoveArray) {
MEM_freeN(static_cast<const AttributeInitMove &>(initializer).data);

View File

@ -257,22 +257,24 @@ class GVMutableArray : public GVArrayCommon {
/** \} */
/* -------------------------------------------------------------------- */
/** \name #GVArray_GSpan and #GVMutableArray_GSpan.
/** \name #GVArraySpan and #GMutableVArraySpan.
* \{ */
/* A generic version of VArray_Span. */
class GVArray_GSpan : public GSpan {
/* A generic version of VArraySpan. */
class GVArraySpan : public GSpan {
private:
GVArray varray_;
void *owned_data_ = nullptr;
public:
GVArray_GSpan(GVArray varray);
~GVArray_GSpan();
GVArraySpan(GVArray varray);
GVArraySpan(GVArraySpan &&other);
~GVArraySpan();
GVArraySpan &operator=(GVArraySpan &&other);
};
/* A generic version of VMutableArray_Span. */
class GVMutableArray_GSpan : public GMutableSpan, NonCopyable, NonMovable {
/* A generic version of MutableVArraySpan. */
class GMutableVArraySpan : public GMutableSpan, NonCopyable, NonMovable {
private:
GVMutableArray varray_;
void *owned_data_ = nullptr;
@ -280,8 +282,10 @@ class GVMutableArray_GSpan : public GMutableSpan, NonCopyable, NonMovable {
bool show_not_saved_warning_ = true;
public:
GVMutableArray_GSpan(GVMutableArray varray, bool copy_values_to_span = true);
~GVMutableArray_GSpan();
GMutableVArraySpan(GVMutableArray varray, bool copy_values_to_span = true);
GMutableVArraySpan(GMutableVArraySpan &&other);
~GMutableVArraySpan();
GMutableVArraySpan &operator=(GMutableVArraySpan &&other);
void save();
void disable_not_applied_warning();

View File

@ -51,7 +51,10 @@ struct CommonVArrayInfo {
/** True when the #data becomes a dangling pointer when the virtual array is destructed. */
bool may_have_ownership = true;
/** Points either to nothing, a single value or array of values, depending on #type. */
/**
* Points either to nothing, a single value or array of values, depending on #type.
* If this is a span of a mutable virtual array, it is safe to cast away const.
*/
const void *data;
CommonVArrayInfo() = default;
@ -1117,15 +1120,15 @@ template<typename T> static constexpr bool is_VMutableArray_v<VMutableArray<T>>
* from faster access.
* - An API is called, that does not accept virtual arrays, but only spans.
*/
template<typename T> class VArray_Span final : public Span<T> {
template<typename T> class VArraySpan final : public Span<T> {
private:
VArray<T> varray_;
Array<T> owned_data_;
public:
VArray_Span() = default;
VArraySpan() = default;
VArray_Span(VArray<T> varray) : Span<T>(), varray_(std::move(varray))
VArraySpan(VArray<T> varray) : Span<T>(), varray_(std::move(varray))
{
this->size_ = varray_.size();
const CommonVArrayInfo info = varray_.common_info();
@ -1140,7 +1143,7 @@ template<typename T> class VArray_Span final : public Span<T> {
}
}
VArray_Span(VArray_Span &&other)
VArraySpan(VArraySpan &&other)
: varray_(std::move(other.varray_)), owned_data_(std::move(other.owned_data_))
{
this->size_ = varray_.size();
@ -1155,25 +1158,25 @@ template<typename T> class VArray_Span final : public Span<T> {
other.size_ = 0;
}
VArray_Span &operator=(VArray_Span &&other)
VArraySpan &operator=(VArraySpan &&other)
{
if (this == &other) {
return *this;
}
std::destroy_at(this);
new (this) VArray_Span(std::move(other));
new (this) VArraySpan(std::move(other));
return *this;
}
};
/**
* Same as #VArray_Span, but for a mutable span.
* Same as #VArraySpan, but for a mutable span.
* The important thing to note is that when changing this span, the results might not be
* immediately reflected in the underlying virtual array (only when the virtual array is a span
* internally). The #save method can be used to write all changes to the underlying virtual array,
* if necessary.
*/
template<typename T> class VMutableArray_Span final : public MutableSpan<T> {
template<typename T> class MutableVArraySpan final : public MutableSpan<T> {
private:
VMutableArray<T> varray_;
Array<T> owned_data_;
@ -1183,7 +1186,7 @@ template<typename T> class VMutableArray_Span final : public MutableSpan<T> {
public:
/* Create a span for any virtual array. This is cheap when the virtual array is a span itself. If
* not, a new array has to be allocated as a wrapper for the underlying virtual array. */
VMutableArray_Span(VMutableArray<T> varray, const bool copy_values_to_span = true)
MutableVArraySpan(VMutableArray<T> varray, const bool copy_values_to_span = true)
: MutableSpan<T>(), varray_(std::move(varray))
{
this->size_ = varray_.size();
@ -1204,15 +1207,44 @@ template<typename T> class VMutableArray_Span final : public MutableSpan<T> {
}
}
~VMutableArray_Span()
MutableVArraySpan(MutableVArraySpan &&other)
: varray_(std::move(other.varray_)),
owned_data_(std::move(owned_data_)),
show_not_saved_warning_(other.show_not_saved_warning_)
{
if (show_not_saved_warning_) {
if (!save_has_been_called_) {
std::cout << "Warning: Call `save()` to make sure that changes persist in all cases.\n";
this->size_ = varray_.size();
const CommonVArrayInfo info = varray_.common_info();
if (info.type == CommonVArrayInfo::Type::Span) {
this->data_ = reinterpret_cast<T *>(info.data);
}
else {
this->data_ = owned_data_.data();
}
other.data_ = nullptr;
other.size_ = 0;
}
~MutableVArraySpan()
{
if (varray_) {
if (show_not_saved_warning_) {
if (!save_has_been_called_) {
std::cout << "Warning: Call `save()` to make sure that changes persist in all cases.\n";
}
}
}
}
MutableVArraySpan &operator=(MutableVArraySpan &&other)
{
if (this == &other) {
return *this;
}
std::destroy_at(this);
new (this) MutableVArraySpan(std::move(other));
return *this;
}
/* Write back all values from a temporary allocated array to the underlying virtual array. */
void save()
{

View File

@ -284,10 +284,10 @@ template<int BufferSize> class GVArrayImpl_For_SmallTrivialSingleValue : public
/** \} */
/* -------------------------------------------------------------------- */
/** \name #GVArray_GSpan
/** \name #GVArraySpan
* \{ */
GVArray_GSpan::GVArray_GSpan(GVArray varray) : GSpan(varray.type()), varray_(std::move(varray))
GVArraySpan::GVArraySpan(GVArray varray) : GSpan(varray.type()), varray_(std::move(varray))
{
size_ = varray_.size();
const CommonVArrayInfo info = varray_.common_info();
@ -301,7 +301,22 @@ GVArray_GSpan::GVArray_GSpan(GVArray varray) : GSpan(varray.type()), varray_(std
}
}
GVArray_GSpan::~GVArray_GSpan()
GVArraySpan::GVArraySpan(GVArraySpan &&other)
: GSpan(other.type()), varray_(std::move(other.varray_)), owned_data_(other.owned_data_)
{
size_ = varray_.size();
const CommonVArrayInfo info = varray_.common_info();
if (info.type == CommonVArrayInfo::Type::Span) {
data_ = info.data;
}
else {
data_ = owned_data_;
}
other.data_ = nullptr;
other.size_ = 0;
}
GVArraySpan::~GVArraySpan()
{
if (owned_data_ != nullptr) {
type_->destruct_n(owned_data_, size_);
@ -309,13 +324,23 @@ GVArray_GSpan::~GVArray_GSpan()
}
}
GVArraySpan &GVArraySpan::operator=(GVArraySpan &&other)
{
if (this == &other) {
return *this;
}
std::destroy_at(this);
new (this) GVArraySpan(std::move(other));
return *this;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name #GVMutableArray_GSpan
/** \name #GMutableVArraySpan
* \{ */
GVMutableArray_GSpan::GVMutableArray_GSpan(GVMutableArray varray, const bool copy_values_to_span)
GMutableVArraySpan::GMutableVArraySpan(GVMutableArray varray, const bool copy_values_to_span)
: GMutableSpan(varray.type()), varray_(std::move(varray))
{
size_ = varray_.size();
@ -335,11 +360,31 @@ GVMutableArray_GSpan::GVMutableArray_GSpan(GVMutableArray varray, const bool cop
}
}
GVMutableArray_GSpan::~GVMutableArray_GSpan()
GMutableVArraySpan::GMutableVArraySpan(GMutableVArraySpan &&other)
: GMutableSpan(other.type()),
varray_(std::move(other.varray_)),
owned_data_(other.owned_data_),
show_not_saved_warning_(other.show_not_saved_warning_)
{
if (show_not_saved_warning_) {
if (!save_has_been_called_) {
std::cout << "Warning: Call `apply()` to make sure that changes persist in all cases.\n";
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_;
}
other.data_ = nullptr;
other.size_ = 0;
}
GMutableVArraySpan::~GMutableVArraySpan()
{
if (varray_) {
if (show_not_saved_warning_) {
if (!save_has_been_called_) {
std::cout << "Warning: Call `apply()` to make sure that changes persist in all cases.\n";
}
}
}
if (owned_data_ != nullptr) {
@ -348,7 +393,17 @@ GVMutableArray_GSpan::~GVMutableArray_GSpan()
}
}
void GVMutableArray_GSpan::save()
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()
{
save_has_been_called_ = true;
if (data_ != owned_data_) {
@ -357,7 +412,7 @@ void GVMutableArray_GSpan::save()
varray_.set_all(owned_data_);
}
void GVMutableArray_GSpan::disable_not_applied_warning()
void GMutableVArraySpan::disable_not_applied_warning()
{
show_not_saved_warning_ = false;
}

View File

@ -109,7 +109,7 @@ TEST(virtual_array, AsSpan)
{
auto func = [](int64_t index) { return (int)(10 * index); };
VArray<int> func_varray = VArray<int>::ForFunc(10, func);
VArray_Span span_varray{func_varray};
VArraySpan span_varray{func_varray};
EXPECT_EQ(span_varray.size(), 10);
Span<int> span = span_varray;
EXPECT_EQ(span.size(), 10);

View File

@ -544,7 +544,7 @@ static int snap_curves_to_surface_exec(bContext *C, wmOperator *op)
MeshComponent surface_mesh_component;
surface_mesh_component.replace(&surface_mesh, GeometryOwnershipType::ReadOnly);
VArray_Span<float2> surface_uv_map;
VArraySpan<float2> surface_uv_map;
if (curves_id.surface_uv_map != nullptr) {
surface_uv_map = surface_mesh_component
.attribute_try_get_for_read(

View File

@ -174,7 +174,7 @@ struct AddOperationExecutor {
}
/* Find UV map. */
VArray_Span<float2> surface_uv_map;
VArraySpan<float2> surface_uv_map;
if (curves_id_->surface_uv_map != nullptr) {
MeshComponent surface_component;
surface_component.replace(surface_, GeometryOwnershipType::ReadOnly);

View File

@ -64,7 +64,7 @@ struct DensityAddOperationExecutor {
Mesh *surface_ = nullptr;
Span<MLoopTri> surface_looptris_;
Span<float3> corner_normals_su_;
VArray_Span<float2> surface_uv_map_;
VArraySpan<float2> surface_uv_map_;
const CurvesSculpt *curves_sculpt_ = nullptr;
const Brush *brush_ = nullptr;
@ -226,7 +226,7 @@ struct DensityAddOperationExecutor {
}
/* Find UV map. */
VArray_Span<float2> surface_uv_map;
VArraySpan<float2> surface_uv_map;
if (curves_id_->surface_uv_map != nullptr) {
MeshComponent surface_component;
surface_component.replace(surface_, GeometryOwnershipType::ReadOnly);

View File

@ -87,7 +87,7 @@ struct SlideOperationExecutor {
Object *surface_ob_ = nullptr;
Mesh *surface_ = nullptr;
Span<MLoopTri> surface_looptris_;
VArray_Span<float2> surface_uv_map_;
VArraySpan<float2> surface_uv_map_;
VArray<float> curve_factors_;
VArray<float> point_factors_;

View File

@ -113,7 +113,7 @@ static bool vertex_paint_from_weight(Object *ob)
return false;
}
GVArray_GSpan interpolated{component.attribute_try_adapt_domain(
GVArraySpan interpolated{component.attribute_try_adapt_domain(
vertex_group, ATTR_DOMAIN_POINT, color_attribute.domain)};
color_attribute.varray.set_all(interpolated.data());

View File

@ -66,7 +66,7 @@ struct AttributeFallbacksArray {
struct PointCloudRealizeInfo {
const PointCloud *pointcloud = nullptr;
/** Matches the order stored in #AllPointCloudsInfo.attributes. */
Array<std::optional<GVArray_GSpan>> attributes;
Array<std::optional<GVArraySpan>> attributes;
/** Id attribute on the point cloud. If there are no ids, this #Span is empty. */
Span<int> stored_ids;
};
@ -96,7 +96,7 @@ struct MeshRealizeInfo {
/** Maps old material indices to new material indices. */
Array<int> material_index_map;
/** Matches the order in #AllMeshesInfo.attributes. */
Array<std::optional<GVArray_GSpan>> attributes;
Array<std::optional<GVArraySpan>> attributes;
/** Vertex ids stored on the mesh. If there are no ids, this #Span is empty. */
Span<int> stored_vertex_ids;
};
@ -116,7 +116,7 @@ struct RealizeCurveInfo {
/**
* Matches the order in #AllCurvesInfo.attributes.
*/
Array<std::optional<GVArray_GSpan>> attributes;
Array<std::optional<GVArraySpan>> attributes;
/** ID attribute on the curves. If there are no ids, this #Span is empty. */
Span<int> stored_ids;
@ -283,7 +283,7 @@ static void threaded_fill(const GPointer value, GMutableSpan dst)
}
static void copy_generic_attributes_to_result(
const Span<std::optional<GVArray_GSpan>> src_attributes,
const Span<std::optional<GVArraySpan>> src_attributes,
const AttributeFallbacksArray &attribute_fallbacks,
const OrderedAttributes &ordered_attributes,
const FunctionRef<IndexRange(eAttrDomain)> &range_fn,

View File

@ -135,7 +135,7 @@ class SampleCurveFunction : public fn::MultiFunction {
}
const VArray<float> &lengths_varray = params.readonly_single_input<float>(0, "Length");
const VArray_Span lengths{lengths_varray};
const VArraySpan lengths{lengths_varray};
#ifdef DEBUG
for (const float length : lengths) {
/* Lengths must be in range of the curve's total length. This is ensured in

View File

@ -410,8 +410,8 @@ static void convert_to_bezier(const CurveComponent &src_component,
};
auto bezier_to_bezier = [&](IndexMask selection) {
const VArray_Span<int8_t> src_types_l = src_curves.handle_types_left();
const VArray_Span<int8_t> src_types_r = src_curves.handle_types_right();
const VArraySpan<int8_t> src_types_l = src_curves.handle_types_left();
const VArraySpan<int8_t> src_types_r = src_curves.handle_types_right();
const Span<float3> src_handles_l = src_curves.handle_positions_left();
const Span<float3> src_handles_r = src_curves.handle_positions_right();
@ -569,7 +569,7 @@ static void convert_to_nurbs(const CurveComponent &src_component,
src_cyclic.get_internal_single() ? NURBS_KNOT_MODE_NORMAL : NURBS_KNOT_MODE_ENDPOINT);
}
else {
VArray_Span<bool> cyclic{src_cyclic};
VArraySpan<bool> cyclic{src_cyclic};
MutableSpan<int8_t> knots_modes = dst_curves.nurbs_knots_modes_for_write();
threading::parallel_for(selection.index_range(), 1024, [&](IndexRange range) {
for (const int i : selection.slice(range)) {

View File

@ -69,7 +69,7 @@ static void copy_attributes(const Map<AttributeIDRef, AttributeKind> &attributes
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
using T = decltype(dummy);
VArray_Span<T> span{attribute.varray.typed<T>()};
VArraySpan<T> span{attribute.varray.typed<T>()};
MutableSpan<T> out_span = result_attribute.as_span<T>();
out_span.copy_from(span);
});
@ -109,7 +109,7 @@ static void copy_attributes_based_on_mask(const Map<AttributeIDRef, AttributeKin
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
using T = decltype(dummy);
VArray_Span<T> span{attribute.varray.typed<T>()};
VArraySpan<T> span{attribute.varray.typed<T>()};
MutableSpan<T> out_span = result_attribute.as_span<T>();
copy_data_based_on_mask(span, out_span, mask);
});
@ -145,7 +145,7 @@ static void copy_attributes_based_on_map(const Map<AttributeIDRef, AttributeKind
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
using T = decltype(dummy);
VArray_Span<T> span{attribute.varray.typed<T>()};
VArraySpan<T> span{attribute.varray.typed<T>()};
MutableSpan<T> out_span = result_attribute.as_span<T>();
copy_data_based_on_map(span, out_span, index_map);
});
@ -1067,7 +1067,7 @@ static void separate_mesh_selection(GeometrySet &geometry_set,
return;
}
const VArray_Span<bool> selection_span{selection};
const VArraySpan<bool> selection_span{selection};
do_mesh_separation(geometry_set, src_component, selection_span, selection_domain, mode);
}

View File

@ -175,7 +175,7 @@ static void transfer_attributes(
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
using T = decltype(dummy);
VArray_Span<T> span{src_attribute.varray.typed<T>()};
VArraySpan<T> span{src_attribute.varray.typed<T>()};
MutableSpan<T> dst_span = dst_attribute.as_span<T>();
if (src_attribute.domain == ATTR_DOMAIN_FACE) {
dst_span.take_front(span.size()).copy_from(span);

View File

@ -178,7 +178,7 @@ static void copy_stable_id_point(const Span<int> offsets,
return;
}
VArray_Span<int> src{src_attribute.varray.typed<int>()};
VArraySpan<int> src{src_attribute.varray.typed<int>()};
MutableSpan<int> dst = dst_attribute.as_span<int>();
threaded_id_offset_copy(offsets, src, dst);
dst_attribute.save();
@ -211,7 +211,7 @@ static void copy_attributes_without_id(GeometrySet &geometry_set,
}
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
using T = decltype(dummy);
VArray_Span<T> src = src_attribute.varray.typed<T>();
VArraySpan<T> src = src_attribute.varray.typed<T>();
MutableSpan<T> dst = dst_attribute.as_span<T>();
threaded_slice_fill<T>(offsets, selection, src, dst);
});
@ -258,7 +258,7 @@ static void copy_curve_attributes_without_id(const GeometrySet &geometry_set,
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
using T = decltype(dummy);
VArray_Span<T> src{src_attribute.varray.typed<T>()};
VArraySpan<T> src{src_attribute.varray.typed<T>()};
MutableSpan<T> dst = dst_attribute.as_span<T>();
switch (out_domain) {
@ -307,7 +307,7 @@ static void copy_stable_id_curves(const bke::CurvesGeometry &src_curves,
return;
}
VArray_Span<int> src{src_attribute.varray.typed<int>()};
VArraySpan<int> src{src_attribute.varray.typed<int>()};
MutableSpan<int> dst = dst_attribute.as_span<int>();
threading::parallel_for(selection.index_range(), 512, [&](IndexRange range) {
@ -439,7 +439,7 @@ static void copy_face_attributes_without_id(GeometrySet &geometry_set,
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
using T = decltype(dummy);
VArray_Span<T> src{src_attribute.varray.typed<T>()};
VArraySpan<T> src{src_attribute.varray.typed<T>()};
MutableSpan<T> dst = dst_attribute.as_span<T>();
switch (out_domain) {
@ -487,7 +487,7 @@ static void copy_stable_id_faces(const Mesh &mesh,
return;
}
VArray_Span<int> src{src_attribute.varray.typed<int>()};
VArraySpan<int> src{src_attribute.varray.typed<int>()};
MutableSpan<int> dst = dst_attribute.as_span<int>();
Span<MPoly> polys(mesh.mpoly, mesh.totpoly);
@ -651,7 +651,7 @@ static void copy_edge_attributes_without_id(GeometrySet &geometry_set,
}
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
using T = decltype(dummy);
VArray_Span<T> src{src_attribute.varray.typed<T>()};
VArraySpan<T> src{src_attribute.varray.typed<T>()};
MutableSpan<T> dst = dst_attribute.as_span<T>();
switch (out_domain) {
@ -691,7 +691,7 @@ static void copy_stable_id_edges(const Mesh &mesh,
Span<MEdge> edges(mesh.medge, mesh.totedge);
VArray_Span<int> src{src_attribute.varray.typed<int>()};
VArraySpan<int> src{src_attribute.varray.typed<int>()};
MutableSpan<int> dst = dst_attribute.as_span<int>();
threading::parallel_for(IndexRange(selection.size()), 1024, [&](IndexRange range) {
for (const int i_selection : range) {
@ -853,7 +853,7 @@ static void duplicate_points_curve(GeometrySet &geometry_set,
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
using T = decltype(dummy);
VArray_Span<T> src{src_attribute.varray.typed<T>()};
VArraySpan<T> src{src_attribute.varray.typed<T>()};
MutableSpan<T> dst = dst_attribute.as_span<T>();
switch (domain) {

View File

@ -63,7 +63,7 @@ static void fill_new_attribute(Span<const GeometryComponent *> src_components,
GVArray read_attribute = component->attribute_get_for_read(
attribute_id, domain, data_type, nullptr);
GVArray_GSpan src_span{read_attribute};
GVArraySpan src_span{read_attribute};
const void *src_buffer = src_span.data();
void *dst_buffer = dst_span[offset];
cpp_type->copy_assign_n(src_buffer, dst_buffer, domain_num);

View File

@ -68,7 +68,7 @@ static void geometry_set_points_to_vertices(GeometrySet &geometry_set,
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
using T = decltype(dummy);
VArray<T> src_typed = src.typed<T>();
VArray_Span<T> src_typed_span{src_typed};
VArraySpan<T> src_typed_span{src_typed};
copy_attribute_to_vertices(src_typed_span, selection, dst.as_span().typed<T>());
});
dst.save();