Merge branch 'blender-v3.0-release'

This commit is contained in:
Jacques Lucke 2021-10-29 09:49:48 +02:00
commit 1688cb27cd
8 changed files with 98 additions and 43 deletions

View File

@ -183,6 +183,8 @@ struct WriteAttributeLookup {
GVMutableArrayPtr varray;
/* Domain the attributes lives on in the geometry. */
AttributeDomain domain;
/* Call this after changing the attribute to invalidate caches that depend on this attribute. */
std::function<void()> tag_modified_fn;
/* Convenience function to check if the attribute has been found. */
operator bool() const

View File

@ -570,6 +570,8 @@ struct CurveEval {
blender::Array<int> evaluated_point_offsets() const;
blender::Array<float> accumulated_spline_lengths() const;
void mark_cache_invalid();
void assert_valid_point_attributes() const;
};

View File

@ -360,7 +360,7 @@ GVArrayPtr BuiltinCustomDataLayerProvider::try_get_for_read(
return as_read_attribute_(data, domain_size);
}
GVMutableArrayPtr BuiltinCustomDataLayerProvider::try_get_for_write(
WriteAttributeLookup BuiltinCustomDataLayerProvider::try_get_for_write(
GeometryComponent &component) const
{
if (writable_ != Writable) {
@ -397,10 +397,14 @@ GVMutableArrayPtr BuiltinCustomDataLayerProvider::try_get_for_write(
data = new_data;
}
std::function<void()> tag_modified_fn;
if (update_on_write_ != nullptr) {
update_on_write_(component);
tag_modified_fn = [component = &component, update = update_on_write_]() {
update(*component);
};
}
return as_write_attribute_(data, domain_size);
return {as_write_attribute_(data, domain_size), domain_, std::move(tag_modified_fn)};
}
bool BuiltinCustomDataLayerProvider::try_delete(GeometryComponent &component) const
@ -925,7 +929,7 @@ blender::bke::WriteAttributeLookup GeometryComponent::attribute_try_get_for_writ
const BuiltinAttributeProvider *builtin_provider =
providers->builtin_attribute_providers().lookup_default_as(attribute_id.name(), nullptr);
if (builtin_provider != nullptr) {
return {builtin_provider->try_get_for_write(*this), builtin_provider->domain()};
return builtin_provider->try_get_for_write(*this);
}
}
for (const DynamicAttributesProvider *dynamic_provider :
@ -1249,6 +1253,20 @@ static void save_output_attribute(OutputAttribute &output_attribute)
varray.get(i, buffer);
write_attribute.varray->set_by_relocate(i, buffer);
}
if (write_attribute.tag_modified_fn) {
write_attribute.tag_modified_fn();
}
}
static std::function<void(OutputAttribute &)> get_simple_output_attribute_save_method(
const blender::bke::WriteAttributeLookup &attribute)
{
if (!attribute.tag_modified_fn) {
return {};
}
return [tag_modified_fn = attribute.tag_modified_fn](OutputAttribute &UNUSED(attribute)) {
tag_modified_fn();
};
}
static OutputAttribute create_output_attribute(GeometryComponent &component,
@ -1293,14 +1311,21 @@ static OutputAttribute create_output_attribute(GeometryComponent &component,
/* Builtin attribute is on different domain. */
return {};
}
GVMutableArrayPtr varray = std::move(attribute.varray);
if (varray->type() == *cpp_type) {
/* Builtin attribute matches exactly. */
return OutputAttribute(std::move(varray), domain, {}, ignore_old_values);
return OutputAttribute(std::move(varray),
domain,
get_simple_output_attribute_save_method(attribute),
ignore_old_values);
}
/* Builtin attribute is on the same domain but has a different data type. */
varray = conversions.try_convert(std::move(varray), *cpp_type);
return OutputAttribute(std::move(varray), domain, {}, ignore_old_values);
return OutputAttribute(std::move(varray),
domain,
get_simple_output_attribute_save_method(attribute),
ignore_old_values);
}
const int domain_size = component.attribute_domain_size(domain);
@ -1324,7 +1349,11 @@ static OutputAttribute create_output_attribute(GeometryComponent &component,
}
if (attribute.domain == domain && attribute.varray->type() == *cpp_type) {
/* Existing generic attribute matches exactly. */
return OutputAttribute(std::move(attribute.varray), domain, {}, ignore_old_values);
return OutputAttribute(std::move(attribute.varray),
domain,
get_simple_output_attribute_save_method(attribute),
ignore_old_values);
}
/* Allocate a new array that lives next to the existing attribute. It will overwrite the existing

View File

@ -87,7 +87,7 @@ class BuiltinAttributeProvider {
}
virtual GVArrayPtr try_get_for_read(const GeometryComponent &component) const = 0;
virtual GVMutableArrayPtr try_get_for_write(GeometryComponent &component) const = 0;
virtual WriteAttributeLookup try_get_for_write(GeometryComponent &component) const = 0;
virtual bool try_delete(GeometryComponent &component) const = 0;
virtual bool try_create(GeometryComponent &UNUSED(component),
const AttributeInit &UNUSED(initializer)) const = 0;
@ -267,7 +267,7 @@ class BuiltinCustomDataLayerProvider final : public BuiltinAttributeProvider {
}
GVArrayPtr try_get_for_read(const GeometryComponent &component) const final;
GVMutableArrayPtr try_get_for_write(GeometryComponent &component) const final;
WriteAttributeLookup try_get_for_write(GeometryComponent &component) const final;
bool try_delete(GeometryComponent &component) const final;
bool try_create(GeometryComponent &component, const AttributeInit &initializer) const final;
bool exists(const GeometryComponent &component) const final;

View File

@ -160,6 +160,13 @@ blender::Array<float> CurveEval::accumulated_spline_lengths() const
return spline_lengths;
}
void CurveEval::mark_cache_invalid()
{
for (SplinePtr &spline : splines_) {
spline->mark_cache_invalid();
}
}
static BezierSpline::HandleType handle_type_from_dna_bezt(const eBezTriple_Handle dna_handle_type)
{
switch (dna_handle_type) {

View File

@ -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

View File

@ -398,15 +398,16 @@ class InstancePositionAttributeProvider final : public BuiltinAttributeProvider
transforms);
}
GVMutableArrayPtr try_get_for_write(GeometryComponent &component) const final
WriteAttributeLookup try_get_for_write(GeometryComponent &component) const final
{
InstancesComponent &instances_component = static_cast<InstancesComponent &>(component);
MutableSpan<float4x4> transforms = instances_component.instance_transforms();
return std::make_unique<fn::GVMutableArray_For_DerivedSpan<float4x4,
float3,
get_transform_position,
set_transform_position>>(
transforms);
return {
std::make_unique<fn::GVMutableArray_For_DerivedSpan<float4x4,
float3,
get_transform_position,
set_transform_position>>(transforms),
domain_};
}
bool try_delete(GeometryComponent &UNUSED(component)) const final
@ -443,13 +444,14 @@ class InstanceIDAttributeProvider final : public BuiltinAttributeProvider {
return std::make_unique<fn::GVArray_For_Span<int>>(instances.instance_ids());
}
GVMutableArrayPtr try_get_for_write(GeometryComponent &component) const final
WriteAttributeLookup try_get_for_write(GeometryComponent &component) const final
{
InstancesComponent &instances = static_cast<InstancesComponent &>(component);
if (instances.instance_ids().is_empty()) {
return {};
}
return std::make_unique<fn::GVMutableArray_For_MutableSpan<int>>(instances.instance_ids());
return {std::make_unique<fn::GVMutableArray_For_MutableSpan<int>>(instances.instance_ids()),
domain_};
}
bool try_delete(GeometryComponent &component) const final

View File

@ -1210,7 +1210,7 @@ class NormalAttributeProvider final : public BuiltinAttributeProvider {
return std::make_unique<fn::GVArray_For_ArrayContainer<Array<float3>>>(std::move(normals));
}
GVMutableArrayPtr try_get_for_write(GeometryComponent &UNUSED(component)) const final
WriteAttributeLookup try_get_for_write(GeometryComponent &UNUSED(component)) const final
{
return {};
}