Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/intern/attribute_access.cc7
-rw-r--r--source/blender/blenkernel/intern/geometry_component_curve.cc214
-rw-r--r--source/blender/blenkernel/intern/geometry_component_mesh.cc43
-rw-r--r--source/blender/blenlib/BLI_virtual_array.hh128
-rw-r--r--source/blender/functions/FN_generic_virtual_array.hh26
-rw-r--r--source/blender/functions/intern/generic_virtual_array.cc82
6 files changed, 126 insertions, 374 deletions
diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc
index 3f2c1f13337..47ddb2494d0 100644
--- a/source/blender/blenkernel/intern/attribute_access.cc
+++ b/source/blender/blenkernel/intern/attribute_access.cc
@@ -50,7 +50,7 @@ using blender::bke::AttributeIDRef;
using blender::bke::OutputAttribute;
using blender::fn::GMutableSpan;
using blender::fn::GSpan;
-using blender::fn::GVMutableArrayImpl_For_GMutableSpan;
+using blender::fn::GVArrayImpl_For_GSpan;
namespace blender::bke {
@@ -1200,8 +1200,7 @@ blender::fn::GVArray GeometryComponent::attribute_get_for_read(const AttributeID
return blender::fn::GVArray::ForSingle(*type, domain_size, default_value);
}
-class GVMutableAttribute_For_OutputAttribute
- : public blender::fn::GVMutableArrayImpl_For_GMutableSpan {
+class GVMutableAttribute_For_OutputAttribute : public blender::fn::GVArrayImpl_For_GSpan {
public:
GeometryComponent *component;
std::string attribute_name;
@@ -1210,7 +1209,7 @@ class GVMutableAttribute_For_OutputAttribute
GVMutableAttribute_For_OutputAttribute(GMutableSpan data,
GeometryComponent &component,
const AttributeIDRef &attribute_id)
- : blender::fn::GVMutableArrayImpl_For_GMutableSpan(data), component(&component)
+ : blender::fn::GVArrayImpl_For_GSpan(data), component(&component)
{
if (attribute_id.is_named()) {
this->attribute_name = attribute_id.name();
diff --git a/source/blender/blenkernel/intern/geometry_component_curve.cc b/source/blender/blenkernel/intern/geometry_component_curve.cc
index 598c61fd877..a0d7bfe135a 100644
--- a/source/blender/blenkernel/intern/geometry_component_curve.cc
+++ b/source/blender/blenkernel/intern/geometry_component_curve.cc
@@ -714,46 +714,15 @@ static bool remove_point_attribute(GeometryComponent &component,
}
/**
- * Virtual array for any control point data accessed with spans and an offset array.
- */
-template<typename T> class VArray_For_SplinePoints : public VArrayImpl<T> {
- private:
- const Array<Span<T>> data_;
- Array<int> offsets_;
-
- public:
- VArray_For_SplinePoints(Array<Span<T>> data, Array<int> offsets)
- : VArrayImpl<T>(offsets.last()), data_(std::move(data)), offsets_(std::move(offsets))
- {
- }
-
- T get(const int64_t index) const final
- {
- const PointIndices indices = lookup_point_indices(offsets_, index);
- return data_[indices.spline_index][indices.point_index];
- }
-
- void materialize(const IndexMask mask, MutableSpan<T> r_span) const final
- {
- point_attribute_materialize(data_.as_span(), offsets_, mask, r_span);
- }
-
- void materialize_to_uninitialized(const IndexMask mask, MutableSpan<T> r_span) const final
- {
- point_attribute_materialize_to_uninitialized(data_.as_span(), offsets_, mask, r_span);
- }
-};
-
-/**
* Mutable virtual array for any control point data accessed with spans and an offset array.
*/
-template<typename T> class VMutableArray_For_SplinePoints final : public VMutableArrayImpl<T> {
+template<typename T> class VArrayImpl_For_SplinePoints final : public VMutableArrayImpl<T> {
private:
Array<MutableSpan<T>> data_;
Array<int> offsets_;
public:
- VMutableArray_For_SplinePoints(Array<MutableSpan<T>> data, Array<int> offsets)
+ VArrayImpl_For_SplinePoints(Array<MutableSpan<T>> data, Array<int> offsets)
: VMutableArrayImpl<T>(offsets.last()), data_(std::move(data)), offsets_(std::move(offsets))
{
}
@@ -791,16 +760,17 @@ template<typename T> class VMutableArray_For_SplinePoints final : public VMutabl
}
};
-template<typename T> VArray<T> point_data_varray(Array<Span<T>> spans, Array<int> offsets)
+template<typename T> VArray<T> point_data_varray(Array<MutableSpan<T>> spans, Array<int> offsets)
{
- return VArray<T>::template For<VArray_For_SplinePoints<T>>(std::move(spans), std::move(offsets));
+ return VArray<T>::template For<VArrayImpl_For_SplinePoints<T>>(std::move(spans),
+ std::move(offsets));
}
template<typename T>
-VMutableArray<T> point_data_varray(Array<MutableSpan<T>> spans, Array<int> offsets)
+VMutableArray<T> point_data_varray_mutable(Array<MutableSpan<T>> spans, Array<int> offsets)
{
- return VMutableArray<T>::template For<VMutableArray_For_SplinePoints<T>>(std::move(spans),
- std::move(offsets));
+ return VMutableArray<T>::template For<VArrayImpl_For_SplinePoints<T>>(std::move(spans),
+ std::move(offsets));
}
/**
@@ -811,13 +781,13 @@ VMutableArray<T> point_data_varray(Array<MutableSpan<T>> spans, Array<int> offse
* \note There is no need to check the handle type to avoid changing auto handles, since
* retrieving write access to the position data will mark them for recomputation anyway.
*/
-class VMutableArray_For_SplinePosition final : public VMutableArrayImpl<float3> {
+class VArrayImpl_For_SplinePosition final : public VMutableArrayImpl<float3> {
private:
MutableSpan<SplinePtr> splines_;
Array<int> offsets_;
public:
- VMutableArray_For_SplinePosition(MutableSpan<SplinePtr> splines, Array<int> offsets)
+ VArrayImpl_For_SplinePosition(MutableSpan<SplinePtr> splines, Array<int> offsets)
: VMutableArrayImpl<float3>(offsets.last()), splines_(splines), offsets_(std::move(offsets))
{
}
@@ -889,104 +859,16 @@ class VMutableArray_For_SplinePosition final : public VMutableArrayImpl<float3>
}
};
-class VArray_For_BezierHandle final : public VArrayImpl<float3> {
- private:
- Span<SplinePtr> splines_;
- Array<int> offsets_;
- bool is_right_;
-
- public:
- VArray_For_BezierHandle(Span<SplinePtr> splines, Array<int> offsets, const bool is_right)
- : VArrayImpl<float3>(offsets.last()),
- splines_(std::move(splines)),
- offsets_(std::move(offsets)),
- is_right_(is_right)
- {
- }
-
- static float3 get_internal(const int64_t index,
- Span<SplinePtr> splines,
- Span<int> offsets,
- const bool is_right)
- {
- const PointIndices indices = lookup_point_indices(offsets, index);
- const Spline &spline = *splines[indices.spline_index];
- if (spline.type() == Spline::Type::Bezier) {
- const BezierSpline &bezier_spline = static_cast<const BezierSpline &>(spline);
- return is_right ? bezier_spline.handle_positions_right()[indices.point_index] :
- bezier_spline.handle_positions_left()[indices.point_index];
- }
- return float3(0);
- }
-
- float3 get(const int64_t index) const final
- {
- return get_internal(index, splines_, offsets_, is_right_);
- }
-
- /**
- * Utility so we can pass handle positions to the materialize functions above.
- *
- * \note This relies on the ability of the materialize implementations to
- * handle empty spans, since only Bezier splines have handles.
- */
- static Array<Span<float3>> get_handle_spans(Span<SplinePtr> splines, const bool is_right)
- {
- Array<Span<float3>> spans(splines.size());
- for (const int i : spans.index_range()) {
- if (splines[i]->type() == Spline::Type::Bezier) {
- BezierSpline &bezier_spline = static_cast<BezierSpline &>(*splines[i]);
- spans[i] = is_right ? bezier_spline.handle_positions_right() :
- bezier_spline.handle_positions_left();
- }
- else {
- spans[i] = {};
- }
- }
- return spans;
- }
-
- static void materialize_internal(const IndexMask mask,
- Span<SplinePtr> splines,
- Span<int> offsets,
- const bool is_right,
- MutableSpan<float3> r_span)
- {
- Array<Span<float3>> spans = get_handle_spans(splines, is_right);
- point_attribute_materialize(spans.as_span(), offsets, mask, r_span);
- }
-
- static void materialize_to_uninitialized_internal(const IndexMask mask,
- Span<SplinePtr> splines,
- Span<int> offsets,
- const bool is_right,
- MutableSpan<float3> r_span)
- {
- Array<Span<float3>> spans = get_handle_spans(splines, is_right);
- point_attribute_materialize_to_uninitialized(spans.as_span(), offsets, mask, r_span);
- }
-
- void materialize(const IndexMask mask, MutableSpan<float3> r_span) const final
- {
- materialize_internal(mask, splines_, offsets_, is_right_, r_span);
- }
-
- void materialize_to_uninitialized(const IndexMask mask, MutableSpan<float3> r_span) const final
- {
- materialize_to_uninitialized_internal(mask, splines_, offsets_, is_right_, r_span);
- }
-};
-
-class VMutableArray_For_BezierHandles final : public VMutableArrayImpl<float3> {
+class VArrayImpl_For_BezierHandles final : public VMutableArrayImpl<float3> {
private:
MutableSpan<SplinePtr> splines_;
Array<int> offsets_;
bool is_right_;
public:
- VMutableArray_For_BezierHandles(MutableSpan<SplinePtr> splines,
- Array<int> offsets,
- const bool is_right)
+ VArrayImpl_For_BezierHandles(MutableSpan<SplinePtr> splines,
+ Array<int> offsets,
+ const bool is_right)
: VMutableArrayImpl<float3>(offsets.last()),
splines_(splines),
offsets_(std::move(offsets)),
@@ -996,7 +878,14 @@ class VMutableArray_For_BezierHandles final : public VMutableArrayImpl<float3> {
float3 get(const int64_t index) const final
{
- return VArray_For_BezierHandle::get_internal(index, splines_, offsets_, is_right_);
+ const PointIndices indices = lookup_point_indices(offsets_, index);
+ const Spline &spline = *splines_[indices.spline_index];
+ if (spline.type() == Spline::Type::Bezier) {
+ const BezierSpline &bezier_spline = static_cast<const BezierSpline &>(spline);
+ return is_right_ ? bezier_spline.handle_positions_right()[indices.point_index] :
+ bezier_spline.handle_positions_left()[indices.point_index];
+ }
+ return float3(0);
}
void set(const int64_t index, float3 value) final
@@ -1040,13 +929,36 @@ class VMutableArray_For_BezierHandles final : public VMutableArrayImpl<float3> {
void materialize(const IndexMask mask, MutableSpan<float3> r_span) const final
{
- VArray_For_BezierHandle::materialize_internal(mask, splines_, offsets_, is_right_, r_span);
+ Array<Span<float3>> spans = get_handle_spans(splines_, is_right_);
+ point_attribute_materialize(spans.as_span(), offsets_, mask, r_span);
}
void materialize_to_uninitialized(const IndexMask mask, MutableSpan<float3> r_span) const final
{
- VArray_For_BezierHandle::materialize_to_uninitialized_internal(
- mask, splines_, offsets_, is_right_, r_span);
+ Array<Span<float3>> spans = get_handle_spans(splines_, is_right_);
+ point_attribute_materialize_to_uninitialized(spans.as_span(), offsets_, mask, r_span);
+ }
+
+ /**
+ * Utility so we can pass handle positions to the materialize functions above.
+ *
+ * \note This relies on the ability of the materialize implementations to
+ * handle empty spans, since only Bezier splines have handles.
+ */
+ static Array<Span<float3>> get_handle_spans(Span<SplinePtr> splines, const bool is_right)
+ {
+ Array<Span<float3>> spans(splines.size());
+ for (const int i : spans.index_range()) {
+ if (splines[i]->type() == Spline::Type::Bezier) {
+ BezierSpline &bezier_spline = static_cast<BezierSpline &>(*splines[i]);
+ spans[i] = is_right ? bezier_spline.handle_positions_right() :
+ bezier_spline.handle_positions_left();
+ }
+ else {
+ spans[i] = {};
+ }
+ }
+ return spans;
}
};
@@ -1102,9 +1014,12 @@ template<typename T> class BuiltinPointAttributeProvider : public BuiltinAttribu
}
Array<int> offsets = curve->control_point_offsets();
- Array<Span<T>> spans(splines.size());
+ Array<MutableSpan<T>> spans(splines.size());
for (const int i : splines.index_range()) {
- spans[i] = get_span_(*splines[i]);
+ Span<T> span = get_span_(*splines[i]);
+ /* Use const-cast because the underlying virtual array implementation is shared between const
+ * and non const data. */
+ spans[i] = MutableSpan<T>(const_cast<T *>(span.data()), span.size());
}
return point_data_varray(spans, offsets);
@@ -1143,7 +1058,7 @@ template<typename T> class BuiltinPointAttributeProvider : public BuiltinAttribu
spans[i] = get_mutable_span_(*splines[i]);
}
- return {point_data_varray(spans, offsets), domain_, tag_modified_fn};
+ return {point_data_varray_mutable(spans, offsets), domain_, tag_modified_fn};
}
bool try_delete(GeometryComponent &component) const final
@@ -1235,8 +1150,8 @@ class PositionAttributeProvider final : public BuiltinPointAttributeProvider<flo
};
Array<int> offsets = curve->control_point_offsets();
- return {VMutableArray<float3>::For<VMutableArray_For_SplinePosition>(curve->splines(),
- std::move(offsets)),
+ return {VMutableArray<float3>::For<VArrayImpl_For_SplinePosition>(curve->splines(),
+ std::move(offsets)),
domain_,
tag_modified_fn};
}
@@ -1270,8 +1185,10 @@ class BezierHandleAttributeProvider : public BuiltinAttributeProvider {
}
Array<int> offsets = curve->control_point_offsets();
- return VArray<float3>::For<VArray_For_BezierHandle>(
- curve->splines(), std::move(offsets), is_right_);
+ /* Use const-cast because the underlying virtual array implementation is shared between const
+ * and non const data. */
+ return VArray<float3>::For<VArrayImpl_For_BezierHandles>(
+ const_cast<CurveEval *>(curve)->splines(), std::move(offsets), is_right_);
}
WriteAttributeLookup try_get_for_write(GeometryComponent &component) const override
@@ -1288,7 +1205,7 @@ class BezierHandleAttributeProvider : public BuiltinAttributeProvider {
auto tag_modified_fn = [curve]() { curve->mark_cache_invalid(); };
Array<int> offsets = curve->control_point_offsets();
- return {VMutableArray<float3>::For<VMutableArray_For_BezierHandles>(
+ return {VMutableArray<float3>::For<VArrayImpl_For_BezierHandles>(
curve->splines(), std::move(offsets), is_right_),
domain_,
tag_modified_fn};
@@ -1377,9 +1294,12 @@ class DynamicPointAttributeProvider final : public DynamicAttributesProvider {
Array<int> offsets = curve->control_point_offsets();
attribute_math::convert_to_static_type(spans[0].type(), [&](auto dummy) {
using T = decltype(dummy);
- Array<Span<T>> data(splines.size());
+ Array<MutableSpan<T>> data(splines.size());
for (const int i : splines.index_range()) {
- data[i] = spans[i].typed<T>();
+ Span<T> span = spans[i].typed<T>();
+ /* Use const-cast because the underlying virtual array implementation is shared between
+ * const and non const data. */
+ data[i] = MutableSpan<T>(const_cast<T *>(span.data()), span.size());
BLI_assert(data[i].data() != nullptr);
}
attribute = {point_data_varray(data, offsets), ATTR_DOMAIN_POINT};
@@ -1435,7 +1355,7 @@ class DynamicPointAttributeProvider final : public DynamicAttributesProvider {
data[i] = spans[i].typed<T>();
BLI_assert(data[i].data() != nullptr);
}
- attribute = {point_data_varray(data, offsets), ATTR_DOMAIN_POINT};
+ attribute = {point_data_varray_mutable(data, offsets), ATTR_DOMAIN_POINT};
});
return attribute;
}
diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc
index a258a66cdf3..e7d48670f73 100644
--- a/source/blender/blenkernel/intern/geometry_component_mesh.cc
+++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc
@@ -996,57 +996,36 @@ static void set_crease(MEdge &edge, float value)
edge.crease = round_fl_to_uchar_clamp(value * 255.0f);
}
-class VMutableArray_For_VertexWeights final : public VMutableArrayImpl<float> {
+class VArrayImpl_For_VertexWeights final : public VMutableArrayImpl<float> {
private:
MDeformVert *dverts_;
const int dvert_index_;
public:
- VMutableArray_For_VertexWeights(MDeformVert *dverts, const int totvert, const int dvert_index)
+ VArrayImpl_For_VertexWeights(MDeformVert *dverts, const int totvert, const int dvert_index)
: VMutableArrayImpl<float>(totvert), dverts_(dverts), dvert_index_(dvert_index)
{
}
float get(const int64_t index) const override
{
- return get_internal(dverts_, dvert_index_, index);
- }
-
- void set(const int64_t index, const float value) override
- {
- MDeformWeight *weight = BKE_defvert_ensure_index(&dverts_[index], dvert_index_);
- weight->weight = value;
- }
-
- static float get_internal(const MDeformVert *dverts, const int dvert_index, const int64_t index)
- {
- if (dverts == nullptr) {
+ if (dverts_ == nullptr) {
return 0.0f;
}
- const MDeformVert &dvert = dverts[index];
+ const MDeformVert &dvert = dverts_[index];
for (const MDeformWeight &weight : Span(dvert.dw, dvert.totweight)) {
- if (weight.def_nr == dvert_index) {
+ if (weight.def_nr == dvert_index_) {
return weight.weight;
}
}
return 0.0f;
+ ;
}
-};
-class VArray_For_VertexWeights final : public VArrayImpl<float> {
- private:
- const MDeformVert *dverts_;
- const int dvert_index_;
-
- public:
- VArray_For_VertexWeights(const MDeformVert *dverts, const int totvert, const int dvert_index)
- : VArrayImpl<float>(totvert), dverts_(dverts), dvert_index_(dvert_index)
- {
- }
-
- float get(const int64_t index) const override
+ void set(const int64_t index, const float value) override
{
- return VMutableArray_For_VertexWeights::get_internal(dverts_, dvert_index_, index);
+ MDeformWeight *weight = BKE_defvert_ensure_index(&dverts_[index], dvert_index_);
+ weight->weight = value;
}
};
@@ -1077,7 +1056,7 @@ class VertexGroupsAttributeProvider final : public DynamicAttributesProvider {
static const float default_value = 0.0f;
return {VArray<float>::ForSingle(default_value, mesh->totvert), ATTR_DOMAIN_POINT};
}
- return {VArray<float>::For<VArray_For_VertexWeights>(
+ return {VArray<float>::For<VArrayImpl_For_VertexWeights>(
mesh->dvert, mesh->totvert, vertex_group_index),
ATTR_DOMAIN_POINT};
}
@@ -1109,7 +1088,7 @@ class VertexGroupsAttributeProvider final : public DynamicAttributesProvider {
mesh->dvert = (MDeformVert *)CustomData_duplicate_referenced_layer(
&mesh->vdata, CD_MDEFORMVERT, mesh->totvert);
}
- return {VMutableArray<float>::For<VMutableArray_For_VertexWeights>(
+ return {VMutableArray<float>::For<VArrayImpl_For_VertexWeights>(
mesh->dvert, mesh->totvert, vertex_group_index),
ATTR_DOMAIN_POINT};
}
diff --git a/source/blender/blenlib/BLI_virtual_array.hh b/source/blender/blenlib/BLI_virtual_array.hh
index 33b3f82c0c2..2038abc0b77 100644
--- a/source/blender/blenlib/BLI_virtual_array.hh
+++ b/source/blender/blenlib/BLI_virtual_array.hh
@@ -223,69 +223,21 @@ template<typename T> class VMutableArrayImpl : public VArrayImpl<T> {
};
/**
- * A virtual array implementation for a span. Methods in this class are final so that it can be
- * devirtualized by the compiler in some cases (e.g. when #devirtualize_varray is used).
+ * A virtual array implementation that references that wraps a span. This implementation is used by
+ * mutable and immutable spans to avoid code duplication.
*/
-template<typename T> class VArrayImpl_For_Span : public VArrayImpl<T> {
- protected:
- const T *data_ = nullptr;
-
- public:
- VArrayImpl_For_Span(const Span<T> data) : VArrayImpl<T>(data.size()), data_(data.data())
- {
- }
-
- protected:
- VArrayImpl_For_Span(const int64_t size) : VArrayImpl<T>(size)
- {
- }
-
- T get(const int64_t index) const final
- {
- return data_[index];
- }
-
- bool is_span() const final
- {
- return true;
- }
-
- Span<T> get_internal_span() const final
- {
- return Span<T>(data_, this->size_);
- }
-};
-
-/**
- * A version of #VArrayImpl_For_Span that can not be subclassed. This allows safely overwriting the
- * #may_have_ownership method.
- */
-template<typename T> class VArrayImpl_For_Span_final final : public VArrayImpl_For_Span<T> {
- public:
- using VArrayImpl_For_Span<T>::VArrayImpl_For_Span;
-
- private:
- bool may_have_ownership() const override
- {
- return false;
- }
-};
-
-/**
- * Like #VArrayImpl_For_Span but for mutable data.
- */
-template<typename T> class VMutableArrayImpl_For_MutableSpan : public VMutableArrayImpl<T> {
+template<typename T> class VArrayImpl_For_Span : public VMutableArrayImpl<T> {
protected:
T *data_ = nullptr;
public:
- VMutableArrayImpl_For_MutableSpan(const MutableSpan<T> data)
+ VArrayImpl_For_Span(const MutableSpan<T> data)
: VMutableArrayImpl<T>(data.size()), data_(data.data())
{
}
protected:
- VMutableArrayImpl_For_MutableSpan(const int64_t size) : VMutableArrayImpl<T>(size)
+ VArrayImpl_For_Span(const int64_t size) : VMutableArrayImpl<T>(size)
{
}
@@ -311,12 +263,12 @@ template<typename T> class VMutableArrayImpl_For_MutableSpan : public VMutableAr
};
/**
- * Like #VArrayImpl_For_Span_final but for mutable data.
+ * A version of #VArrayImpl_For_Span that can not be subclassed. This allows safely overwriting the
+ * #may_have_ownership method.
*/
-template<typename T>
-class VMutableArrayImpl_For_MutableSpan_final final : public VMutableArrayImpl_For_MutableSpan<T> {
+template<typename T> class VArrayImpl_For_Span_final final : public VArrayImpl_For_Span<T> {
public:
- using VMutableArrayImpl_For_MutableSpan<T>::VMutableArrayImpl_For_MutableSpan;
+ using VArrayImpl_For_Span<T>::VArrayImpl_For_Span;
private:
bool may_have_ownership() const override
@@ -340,7 +292,7 @@ class VArrayImpl_For_ArrayContainer : public VArrayImpl_For_Span<T> {
VArrayImpl_For_ArrayContainer(Container container)
: VArrayImpl_For_Span<T>((int64_t)container.size()), container_(std::move(container))
{
- this->data_ = container_.data();
+ this->data_ = const_cast<T *>(container_.data());
}
};
@@ -422,54 +374,16 @@ template<typename T, typename GetFunc> class VArrayImpl_For_Func final : public
/**
* \note: This is `final` so that #may_have_ownership can be implemented reliably.
*/
-template<typename StructT, typename ElemT, ElemT (*GetFunc)(const StructT &)>
-class VArrayImpl_For_DerivedSpan final : public VArrayImpl<ElemT> {
- private:
- const StructT *data_;
-
- public:
- VArrayImpl_For_DerivedSpan(const Span<StructT> data)
- : VArrayImpl<ElemT>(data.size()), data_(data.data())
- {
- }
-
- private:
- ElemT get(const int64_t index) const override
- {
- return GetFunc(data_[index]);
- }
-
- void materialize(IndexMask mask, MutableSpan<ElemT> r_span) const override
- {
- ElemT *dst = r_span.data();
- mask.foreach_index([&](const int64_t i) { dst[i] = GetFunc(data_[i]); });
- }
-
- void materialize_to_uninitialized(IndexMask mask, MutableSpan<ElemT> r_span) const override
- {
- ElemT *dst = r_span.data();
- mask.foreach_index([&](const int64_t i) { new (dst + i) ElemT(GetFunc(data_[i])); });
- }
-
- bool may_have_ownership() const override
- {
- return false;
- }
-};
-
-/**
- * \note: This is `final` so that #may_have_ownership can be implemented reliably.
- */
template<typename StructT,
typename ElemT,
ElemT (*GetFunc)(const StructT &),
- void (*SetFunc)(StructT &, ElemT)>
-class VMutableArrayImpl_For_DerivedSpan final : public VMutableArrayImpl<ElemT> {
+ void (*SetFunc)(StructT &, ElemT) = nullptr>
+class VArrayImpl_For_DerivedSpan final : public VMutableArrayImpl<ElemT> {
private:
StructT *data_;
public:
- VMutableArrayImpl_For_DerivedSpan(const MutableSpan<StructT> data)
+ VArrayImpl_For_DerivedSpan(const MutableSpan<StructT> data)
: VMutableArrayImpl<ElemT>(data.size()), data_(data.data())
{
}
@@ -482,6 +396,7 @@ class VMutableArrayImpl_For_DerivedSpan final : public VMutableArrayImpl<ElemT>
void set(const int64_t index, ElemT value) override
{
+ BLI_assert(SetFunc != nullptr);
SetFunc(data_[index], std::move(value));
}
@@ -840,7 +755,10 @@ template<typename T> class VArray : public VArrayCommon<T> {
*/
static VArray ForSpan(Span<T> values)
{
- return VArray::For<VArrayImpl_For_Span_final<T>>(values);
+ /* Cast const away, because the virtual array implementation for const and non const spans is
+ * shared. */
+ MutableSpan<T> span{const_cast<T *>(values.data()), values.size()};
+ return VArray::For<VArrayImpl_For_Span_final<T>>(span);
}
/**
@@ -859,7 +777,10 @@ template<typename T> class VArray : public VArrayCommon<T> {
template<typename StructT, T (*GetFunc)(const StructT &)>
static VArray ForDerivedSpan(Span<StructT> values)
{
- return VArray::For<VArrayImpl_For_DerivedSpan<StructT, T, GetFunc>>(values);
+ /* Cast const away, because the virtual array implementation for const and non const derived
+ * spans is shared. */
+ MutableSpan<StructT> span{const_cast<StructT *>(values.data()), values.size()};
+ return VArray::For<VArrayImpl_For_DerivedSpan<StructT, T, GetFunc>>(span);
}
/**
@@ -919,7 +840,7 @@ template<typename T> class VMutableArray : public VArrayCommon<T> {
*/
static VMutableArray ForSpan(MutableSpan<T> values)
{
- return VMutableArray::For<VMutableArrayImpl_For_MutableSpan_final<T>>(values);
+ return VMutableArray::For<VArrayImpl_For_Span_final<T>>(values);
}
/**
@@ -929,8 +850,7 @@ template<typename T> class VMutableArray : public VArrayCommon<T> {
template<typename StructT, T (*GetFunc)(const StructT &), void (*SetFunc)(StructT &, T)>
static VMutableArray ForDerivedSpan(MutableSpan<StructT> values)
{
- return VMutableArray::For<VMutableArrayImpl_For_DerivedSpan<StructT, T, GetFunc, SetFunc>>(
- values);
+ return VMutableArray::For<VArrayImpl_For_DerivedSpan<StructT, T, GetFunc, SetFunc>>(values);
}
/** Convert to a #VArray by copying. */
diff --git a/source/blender/functions/FN_generic_virtual_array.hh b/source/blender/functions/FN_generic_virtual_array.hh
index b822f3a7c33..aed7c206fe5 100644
--- a/source/blender/functions/FN_generic_virtual_array.hh
+++ b/source/blender/functions/FN_generic_virtual_array.hh
@@ -555,37 +555,19 @@ template<typename T> class VMutableArrayImpl_For_GVMutableArray : public VMutabl
/** \} */
/* -------------------------------------------------------------------- */
-/** \name #GVArrayImpl_For_GSpan and #GVMutableArrayImpl_For_GMutableSpan.
+/** \name #GVArrayImpl_For_GSpan.
* \{ */
-class GVArrayImpl_For_GSpan : public GVArrayImpl {
- protected:
- const void *data_ = nullptr;
- const int64_t element_size_;
-
- public:
- GVArrayImpl_For_GSpan(const GSpan span);
-
- protected:
- GVArrayImpl_For_GSpan(const CPPType &type, const int64_t size);
-
- void get(const int64_t index, void *r_value) const override;
- void get_to_uninitialized(const int64_t index, void *r_value) const override;
-
- bool is_span() const override;
- GSpan get_internal_span() const override;
-};
-
-class GVMutableArrayImpl_For_GMutableSpan : public GVMutableArrayImpl {
+class GVArrayImpl_For_GSpan : public GVMutableArrayImpl {
protected:
void *data_ = nullptr;
const int64_t element_size_;
public:
- GVMutableArrayImpl_For_GMutableSpan(const GMutableSpan span);
+ GVArrayImpl_For_GSpan(const GMutableSpan span);
protected:
- GVMutableArrayImpl_For_GMutableSpan(const CPPType &type, const int64_t size);
+ GVArrayImpl_For_GSpan(const CPPType &type, const int64_t size);
public:
void get(const int64_t index, void *r_value) const override;
diff --git a/source/blender/functions/intern/generic_virtual_array.cc b/source/blender/functions/intern/generic_virtual_array.cc
index b8f44c15c2f..415445eebd6 100644
--- a/source/blender/functions/intern/generic_virtual_array.cc
+++ b/source/blender/functions/intern/generic_virtual_array.cc
@@ -139,107 +139,56 @@ bool GVMutableArrayImpl::try_assign_VMutableArray(void *UNUSED(varray)) const
/** \name #GVArrayImpl_For_GSpan
* \{ */
-GVArrayImpl_For_GSpan::GVArrayImpl_For_GSpan(const GSpan span)
- : GVArrayImpl(span.type(), span.size()), data_(span.data()), element_size_(span.type().size())
-{
-}
-
-GVArrayImpl_For_GSpan::GVArrayImpl_For_GSpan(const CPPType &type, const int64_t size)
- : GVArrayImpl(type, size), element_size_(type.size())
-{
-}
-
-void GVArrayImpl_For_GSpan::get(const int64_t index, void *r_value) const
-{
- type_->copy_assign(POINTER_OFFSET(data_, element_size_ * index), r_value);
-}
-
-void GVArrayImpl_For_GSpan::get_to_uninitialized(const int64_t index, void *r_value) const
-{
- type_->copy_construct(POINTER_OFFSET(data_, element_size_ * index), r_value);
-}
-
-bool GVArrayImpl_For_GSpan::is_span() const
-{
- return true;
-}
-
-GSpan GVArrayImpl_For_GSpan::get_internal_span() const
-{
- return GSpan(*type_, data_, size_);
-}
-
-/** See #VArrayImpl_For_Span_final. */
-class GVArrayImpl_For_GSpan_final final : public GVArrayImpl_For_GSpan {
- public:
- using GVArrayImpl_For_GSpan::GVArrayImpl_For_GSpan;
-
- private:
- bool may_have_ownership() const override
- {
- return false;
- }
-};
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name #GVMutableArrayImpl_For_GMutableSpan
- * \{ */
-
-GVMutableArrayImpl_For_GMutableSpan::GVMutableArrayImpl_For_GMutableSpan(const GMutableSpan span)
+GVArrayImpl_For_GSpan::GVArrayImpl_For_GSpan(const GMutableSpan span)
: GVMutableArrayImpl(span.type(), span.size()),
data_(span.data()),
element_size_(span.type().size())
{
}
-GVMutableArrayImpl_For_GMutableSpan::GVMutableArrayImpl_For_GMutableSpan(const CPPType &type,
- const int64_t size)
+GVArrayImpl_For_GSpan::GVArrayImpl_For_GSpan(const CPPType &type, const int64_t size)
: GVMutableArrayImpl(type, size), element_size_(type.size())
{
}
-void GVMutableArrayImpl_For_GMutableSpan::get(const int64_t index, void *r_value) const
+void GVArrayImpl_For_GSpan::get(const int64_t index, void *r_value) const
{
type_->copy_assign(POINTER_OFFSET(data_, element_size_ * index), r_value);
}
-void GVMutableArrayImpl_For_GMutableSpan::get_to_uninitialized(const int64_t index,
- void *r_value) const
+void GVArrayImpl_For_GSpan::get_to_uninitialized(const int64_t index, void *r_value) const
{
type_->copy_construct(POINTER_OFFSET(data_, element_size_ * index), r_value);
}
-void GVMutableArrayImpl_For_GMutableSpan::set_by_copy(const int64_t index, const void *value)
+void GVArrayImpl_For_GSpan::set_by_copy(const int64_t index, const void *value)
{
type_->copy_assign(value, POINTER_OFFSET(data_, element_size_ * index));
}
-void GVMutableArrayImpl_For_GMutableSpan::set_by_move(const int64_t index, void *value)
+void GVArrayImpl_For_GSpan::set_by_move(const int64_t index, void *value)
{
type_->move_construct(value, POINTER_OFFSET(data_, element_size_ * index));
}
-void GVMutableArrayImpl_For_GMutableSpan::set_by_relocate(const int64_t index, void *value)
+void GVArrayImpl_For_GSpan::set_by_relocate(const int64_t index, void *value)
{
type_->relocate_assign(value, POINTER_OFFSET(data_, element_size_ * index));
}
-bool GVMutableArrayImpl_For_GMutableSpan::is_span() const
+bool GVArrayImpl_For_GSpan::is_span() const
{
return true;
}
-GSpan GVMutableArrayImpl_For_GMutableSpan::get_internal_span() const
+GSpan GVArrayImpl_For_GSpan::get_internal_span() const
{
return GSpan(*type_, data_, size_);
}
-class GVMutableArrayImpl_For_GMutableSpan_final final
- : public GVMutableArrayImpl_For_GMutableSpan {
+class GVArrayImpl_For_GSpan_final final : public GVArrayImpl_For_GSpan {
public:
- using GVMutableArrayImpl_For_GMutableSpan::GVMutableArrayImpl_For_GMutableSpan;
+ using GVArrayImpl_For_GSpan::GVArrayImpl_For_GSpan;
private:
bool may_have_ownership() const override
@@ -682,7 +631,10 @@ GVArray GVArray::ForSingleDefault(const CPPType &type, const int64_t size)
GVArray GVArray::ForSpan(GSpan span)
{
- return GVArray::For<GVArrayImpl_For_GSpan_final>(span);
+ /* Use const-cast because the underlying virtual array implementation is shared between const
+ * and non const data. */
+ GMutableSpan mutable_span{span.type(), const_cast<void *>(span.data()), span.size()};
+ return GVArray::For<GVArrayImpl_For_GSpan_final>(mutable_span);
}
class GVArrayImpl_For_GArray : public GVArrayImpl_For_GSpan {
@@ -691,7 +643,7 @@ class GVArrayImpl_For_GArray : public GVArrayImpl_For_GSpan {
public:
GVArrayImpl_For_GArray(GArray<> array)
- : GVArrayImpl_For_GSpan(array.as_span()), array_(std::move(array))
+ : GVArrayImpl_For_GSpan(array.as_mutable_span()), array_(std::move(array))
{
}
};
@@ -743,7 +695,7 @@ GVMutableArray::GVMutableArray(std::shared_ptr<GVMutableArrayImpl> impl)
GVMutableArray GVMutableArray::ForSpan(GMutableSpan span)
{
- return GVMutableArray::For<GVMutableArrayImpl_For_GMutableSpan_final>(span);
+ return GVMutableArray::For<GVArrayImpl_For_GSpan_final>(span);
}
GVMutableArray::operator GVArray() const &