diff options
author | Jacques Lucke <jacques@blender.org> | 2021-10-29 10:28:31 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2021-10-29 10:28:31 +0300 |
commit | cf771807b7997949611dbf76b43150592c9977cb (patch) | |
tree | d1b986d9cd4bf56c93edf9755d6163cc6263b0dc /source/blender/blenkernel/intern/geometry_component_curve.cc | |
parent | b546202a9afa5ee358893d82e6a1ba0f69cca254 (diff) |
Geometry Nodes: do cache invalidation after writing attributes
This is a better and more general fix for T92511 and T92508 than
the ones that I committed before.
Previously, we tagged caches dirty when first accessing attributes.
This led to incorrect caches when under some circumstances. Now
cache invalidation is part of `OutputAttribute.save()`.
A nice side benefit of this change is that it may make things more
efficient in some cases, because we don't invalidate caches when
they don't have to be invalidated.
Differential Revision: https://developer.blender.org/D13009
Diffstat (limited to 'source/blender/blenkernel/intern/geometry_component_curve.cc')
-rw-r--r-- | source/blender/blenkernel/intern/geometry_component_curve.cc | 63 |
1 files changed, 38 insertions, 25 deletions
diff --git a/source/blender/blenkernel/intern/geometry_component_curve.cc b/source/blender/blenkernel/intern/geometry_component_curve.cc index d2a404b860a..d3c3fcc1e67 100644 --- a/source/blender/blenkernel/intern/geometry_component_curve.cc +++ b/source/blender/blenkernel/intern/geometry_component_curve.cc @@ -433,7 +433,7 @@ class BuiltinSplineAttributeProvider final : public BuiltinAttributeProvider { return as_read_attribute_(*curve); } - GVMutableArrayPtr try_get_for_write(GeometryComponent &component) const final + WriteAttributeLookup try_get_for_write(GeometryComponent &component) const final { if (writable_ != Writable) { return {}; @@ -442,7 +442,7 @@ class BuiltinSplineAttributeProvider final : public BuiltinAttributeProvider { if (curve == nullptr) { return {}; } - return as_write_attribute_(*curve); + return {as_write_attribute_(*curve), domain_}; } bool try_delete(GeometryComponent &UNUSED(component)) const final @@ -1122,7 +1122,7 @@ template<typename T> class BuiltinPointAttributeProvider : public BuiltinAttribu return point_data_gvarray(spans, offsets); } - GVMutableArrayPtr try_get_for_write(GeometryComponent &component) const override + WriteAttributeLookup try_get_for_write(GeometryComponent &component) const override { CurveEval *curve = get_curve_from_component_for_write(component); if (curve == nullptr) { @@ -1133,25 +1133,30 @@ template<typename T> class BuiltinPointAttributeProvider : public BuiltinAttribu return {}; } + std::function<void()> tag_modified_fn; + if (update_on_write_ != nullptr) { + tag_modified_fn = [curve, update = update_on_write_]() { + for (SplinePtr &spline : curve->splines()) { + update(*spline); + } + }; + } + MutableSpan<SplinePtr> splines = curve->splines(); if (splines.size() == 1) { - if (update_on_write_) { - update_on_write_(*splines[0]); - } - return std::make_unique<fn::GVMutableArray_For_GMutableSpan>( - get_mutable_span_(*splines.first())); + return {std::make_unique<fn::GVMutableArray_For_GMutableSpan>( + get_mutable_span_(*splines.first())), + domain_, + std::move(tag_modified_fn)}; } Array<int> offsets = curve->control_point_offsets(); Array<MutableSpan<T>> spans(splines.size()); for (const int i : splines.index_range()) { spans[i] = get_mutable_span_(*splines[i]); - if (update_on_write_) { - update_on_write_(*splines[i]); - } } - return point_data_gvarray(spans, offsets); + return {point_data_gvarray(spans, offsets), domain_, tag_modified_fn}; } bool try_delete(GeometryComponent &component) const final @@ -1223,7 +1228,7 @@ class PositionAttributeProvider final : public BuiltinPointAttributeProvider<flo { } - GVMutableArrayPtr try_get_for_write(GeometryComponent &component) const final + WriteAttributeLookup try_get_for_write(GeometryComponent &component) const final { CurveEval *curve = get_curve_from_component_for_write(component); if (curve == nullptr) { @@ -1236,16 +1241,19 @@ class PositionAttributeProvider final : public BuiltinPointAttributeProvider<flo return BuiltinPointAttributeProvider<float3>::try_get_for_write(component); } - /* Changing the positions requires recalculation of cached evaluated data in many cases. - * This could set more specific flags in the future to avoid unnecessary recomputation. */ - for (SplinePtr &spline : curve->splines()) { - spline->mark_cache_invalid(); - } + auto tag_modified_fn = [curve]() { + /* Changing the positions requires recalculation of cached evaluated data in many cases. + * This could set more specific flags in the future to avoid unnecessary recomputation. */ + curve->mark_cache_invalid(); + }; Array<int> offsets = curve->control_point_offsets(); - return std::make_unique< - fn::GVMutableArray_For_EmbeddedVMutableArray<float3, VMutableArray_For_SplinePosition>>( - offsets.last(), curve->splines(), std::move(offsets)); + return {std::make_unique< + fn::GVMutableArray_For_EmbeddedVMutableArray<float3, + VMutableArray_For_SplinePosition>>( + offsets.last(), curve->splines(), std::move(offsets)), + domain_, + tag_modified_fn}; } }; @@ -1281,7 +1289,7 @@ class BezierHandleAttributeProvider : public BuiltinAttributeProvider { offsets.last(), curve->splines(), std::move(offsets), is_right_); } - GVMutableArrayPtr try_get_for_write(GeometryComponent &component) const override + WriteAttributeLookup try_get_for_write(GeometryComponent &component) const override { CurveEval *curve = get_curve_from_component_for_write(component); if (curve == nullptr) { @@ -1292,10 +1300,15 @@ class BezierHandleAttributeProvider : public BuiltinAttributeProvider { return {}; } + auto tag_modified_fn = [curve]() { curve->mark_cache_invalid(); }; + Array<int> offsets = curve->control_point_offsets(); - return std::make_unique< - fn::GVMutableArray_For_EmbeddedVMutableArray<float3, VMutableArray_For_BezierHandles>>( - offsets.last(), curve->splines(), std::move(offsets), is_right_); + return { + std::make_unique< + fn::GVMutableArray_For_EmbeddedVMutableArray<float3, VMutableArray_For_BezierHandles>>( + offsets.last(), curve->splines(), std::move(offsets), is_right_), + domain_, + tag_modified_fn}; } bool try_delete(GeometryComponent &UNUSED(component)) const final |