Attributes: Integrate implicit sharing with the attribute API #107059
|
@ -338,12 +338,11 @@ GAttributeReader BuiltinCustomDataLayerProvider::try_get_for_read(const void *ow
|
|||
}
|
||||
|
||||
/* When the number of elements is zero, layers might have null data but still exist. */
|
||||
const CPPType &type = *custom_data_type_to_cpp_type(data_type_);
|
||||
const int element_num = custom_data_access_.get_element_num(owner);
|
||||
if (element_num == 0) {
|
||||
if (this->layer_exists(*custom_data)) {
|
||||
return {GVArray::ForSingle(*custom_data_type_to_cpp_type(data_type_), 0, nullptr),
|
||||
domain_,
|
||||
nullptr};
|
||||
return {GVArray::ForSpan({type, nullptr, 0}), domain_, nullptr};
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
@ -359,9 +358,7 @@ GAttributeReader BuiltinCustomDataLayerProvider::try_get_for_read(const void *ow
|
|||
return {};
|
||||
}
|
||||
const CustomDataLayer &layer = custom_data->layers[index];
|
||||
return {GVArray::ForSpan({*custom_data_type_to_cpp_type(data_type_), layer.data, element_num}),
|
||||
domain_,
|
||||
layer.sharing_info};
|
||||
return {GVArray::ForSpan({type, layer.data, element_num}), domain_, layer.sharing_info};
|
||||
}
|
||||
|
||||
GAttributeWriter BuiltinCustomDataLayerProvider::try_get_for_write(void *owner) const
|
||||
|
@ -386,21 +383,18 @@ GAttributeWriter BuiltinCustomDataLayerProvider::try_get_for_write(void *owner)
|
|||
return {};
|
||||
}
|
||||
|
||||
int index;
|
||||
void *data = nullptr;
|
||||
if (stored_as_named_attribute_) {
|
||||
index = CustomData_get_named_layer_index(custom_data, stored_type_, name_.c_str());
|
||||
data = CustomData_get_layer_named_for_write(
|
||||
custom_data, stored_type_, name_.c_str(), element_num);
|
||||
}
|
||||
else {
|
||||
index = CustomData_get_layer_index(custom_data, stored_type_);
|
||||
data = CustomData_get_layer_for_write(custom_data, stored_type_, element_num);
|
||||
}
|
||||
if (index == -1) {
|
||||
if (data == nullptr) {
|
||||
return {};
|
||||
}
|
||||
CustomDataLayer &layer = custom_data->layers[index];
|
||||
|
||||
return {GVMutableArray::ForSpan({type, layer.data, element_num}),
|
||||
domain_,
|
||||
std::move(tag_modified_fn)};
|
||||
return {GVMutableArray::ForSpan({type, data, element_num}), domain_, std::move(tag_modified_fn)};
|
||||
}
|
||||
|
||||
bool BuiltinCustomDataLayerProvider::try_delete(void *owner) const
|
||||
|
|
|
@ -171,8 +171,6 @@ class CustomDataAttributeProvider final : public DynamicAttributesProvider {
|
|||
* if the stored type is the same as the attribute type.
|
||||
*/
|
||||
class BuiltinCustomDataLayerProvider final : public BuiltinAttributeProvider {
|
||||
using AsReadAttribute = GAttributeReader (*)(const void *data, int element_num);
|
||||
using AsWriteAttribute = GVMutableArray (*)(void *data, int element_num);
|
||||
using UpdateOnRead = void (*)(const void *owner);
|
||||
using UpdateOnChange = void (*)(void *owner);
|
||||
const eCustomDataType stored_type_;
|
||||
|
|
|
@ -885,12 +885,14 @@ class Map {
|
|||
}
|
||||
|
||||
/**
|
||||
* Remove all key-value-pairs for that the given predicate is true.
|
||||
* Remove all key-value-pairs for that the given predicate is true and return the number of
|
||||
* removed pairs.
|
||||
*
|
||||
* This is similar to std::erase_if.
|
||||
*/
|
||||
template<typename Predicate> void remove_if(Predicate &&predicate)
|
||||
template<typename Predicate> int64_t remove_if(Predicate &&predicate)
|
||||
{
|
||||
const int64_t prev_size = this->size();
|
||||
for (Slot &slot : slots_) {
|
||||
if (slot.is_occupied()) {
|
||||
const Key &key = *slot.key();
|
||||
|
@ -901,6 +903,7 @@ class Map {
|
|||
}
|
||||
}
|
||||
}
|
||||
return prev_size - this->size();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -489,12 +489,14 @@ class Set {
|
|||
}
|
||||
|
||||
/**
|
||||
* Remove all values for which the given predicate is true.
|
||||
* Remove all values for which the given predicate is true and return the number of removed
|
||||
* values.
|
||||
*
|
||||
* This is similar to std::erase_if.
|
||||
*/
|
||||
template<typename Predicate> void remove_if(Predicate &&predicate)
|
||||
template<typename Predicate> int64_t remove_if(Predicate &&predicate)
|
||||
{
|
||||
const int64_t prev_size = this->size();
|
||||
for (Slot &slot : slots_) {
|
||||
if (slot.is_occupied()) {
|
||||
const Key &key = *slot.key();
|
||||
|
@ -504,6 +506,7 @@ class Set {
|
|||
}
|
||||
}
|
||||
}
|
||||
return prev_size - this->size();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -816,14 +816,17 @@ class Vector {
|
|||
}
|
||||
|
||||
/**
|
||||
* Remove all values for which the given predicate is true.
|
||||
* Remove all values for which the given predicate is true and return the number of values
|
||||
* removed.
|
||||
*
|
||||
* This is similar to std::erase_if.
|
||||
*/
|
||||
template<typename Predicate> void remove_if(Predicate &&predicate)
|
||||
template<typename Predicate> int64_t remove_if(Predicate &&predicate)
|
||||
{
|
||||
const T *prev_end = this->end();
|
||||
end_ = std::remove_if(this->begin(), this->end(), predicate);
|
||||
UPDATE_VECTOR_SIZE(this);
|
||||
return int64_t(prev_end - end_);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -347,13 +347,14 @@ class VectorSet {
|
|||
}
|
||||
|
||||
/**
|
||||
* Remove all values for which the given predicate is true. This may change the order of elements
|
||||
* in the vector.
|
||||
* Remove all values for which the given predicate is true and return the number or values
|
||||
* removed. This may change the order of elements in the vector.
|
||||
*
|
||||
* This is similar to std::erase_if.
|
||||
*/
|
||||
template<typename Predicate> void remove_if(Predicate &&predicate)
|
||||
template<typename Predicate> int64_t remove_if(Predicate &&predicate)
|
||||
{
|
||||
const int64_t prev_size = this->size();
|
||||
for (Slot &slot : slots_) {
|
||||
if (slot.is_occupied()) {
|
||||
const int64_t index = slot.index();
|
||||
|
@ -363,6 +364,7 @@ class VectorSet {
|
|||
}
|
||||
}
|
||||
}
|
||||
return prev_size - this->size();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -646,8 +646,8 @@ TEST(map, RemoveIf)
|
|||
for (const int64_t i : IndexRange(100)) {
|
||||
map.add(i * i, i);
|
||||
}
|
||||
map.remove_if([](auto item) { return item.key > 100; });
|
||||
EXPECT_EQ(map.size(), 11);
|
||||
const int64_t removed = map.remove_if([](auto item) { return item.key > 100; });
|
||||
EXPECT_EQ(map.size() + removed, 100);
|
||||
for (const int64_t i : IndexRange(100)) {
|
||||
if (i <= 10) {
|
||||
EXPECT_EQ(map.lookup(i * i), i);
|
||||
|
|
|
@ -582,8 +582,8 @@ TEST(set, RemoveIf)
|
|||
for (const int64_t i : IndexRange(100)) {
|
||||
set.add(i * i);
|
||||
}
|
||||
set.remove_if([](const int64_t key) { return key > 100; });
|
||||
EXPECT_EQ(set.size(), 11);
|
||||
const int64_t removed = set.remove_if([](const int64_t key) { return key > 100; });
|
||||
EXPECT_EQ(set.size() + removed, 100);
|
||||
for (const int64_t i : IndexRange(100)) {
|
||||
EXPECT_EQ(set.contains(i * i), i <= 10);
|
||||
}
|
||||
|
|
|
@ -134,8 +134,8 @@ TEST(vector_set, RemoveIf)
|
|||
for (const int64_t i : IndexRange(100)) {
|
||||
set.add(i * i);
|
||||
}
|
||||
set.remove_if([](const int64_t key) { return key % 2 == 0; });
|
||||
EXPECT_EQ(set.size(), 50);
|
||||
const int64_t removed = set.remove_if([](const int64_t key) { return key % 2 == 0; });
|
||||
EXPECT_EQ(set.size() + removed, 100);
|
||||
for (const int64_t i : IndexRange(100)) {
|
||||
EXPECT_EQ(set.contains(i * i), i % 2 == 1);
|
||||
}
|
||||
|
|
|
@ -422,7 +422,8 @@ TEST(vector, Remove)
|
|||
TEST(vector, RemoveIf)
|
||||
{
|
||||
Vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8};
|
||||
vec.remove_if([](const int x) { return x % 2 == 0; });
|
||||
const int64_t removed = vec.remove_if([](const int x) { return x % 2 == 0; });
|
||||
EXPECT_EQ(vec.size() + removed, 8);
|
||||
const Vector<int> expected_vec = {1, 3, 5, 7};
|
||||
EXPECT_EQ(vec.size(), expected_vec.size());
|
||||
EXPECT_EQ_ARRAY(vec.data(), expected_vec.data(), size_t(vec.size()));
|
||||
|
|
|
@ -1840,8 +1840,14 @@ void DepsgraphRelationBuilder::build_driver_variables(ID *id, FCurve *fcu)
|
|||
* - Modifications of evaluated IDs from a Python handler.
|
||||
* Such modifications are not fully integrated in the dependency graph evaluation as it
|
||||
* has issues with copy-on-write tagging and the fact that relations are defined by the
|
||||
* original main database status. */
|
||||
if (target_id != variable_exit_key.ptr.owner_id) {
|
||||
* original main database status.
|
||||
*
|
||||
* The original report for this is #98618.
|
||||
*
|
||||
* The not-so-obvious part is that we don't do such relation for the context properties.
|
||||
* They are resolved at the graph build time and do not change at runtime (#107081).
|
||||
*/
|
||||
if (target_id != variable_exit_key.ptr.owner_id && dvar->type != DVAR_TYPE_CONTEXT_PROP) {
|
||||
if (deg_copy_on_write_is_needed(GS(target_id->name))) {
|
||||
ComponentKey target_id_key(target_id, NodeType::COPY_ON_WRITE);
|
||||
add_relation(target_id_key, driver_key, "Target ID -> Driver");
|
||||
|
|
|
@ -280,6 +280,9 @@ void WM_OT_alembic_export(wmOperatorType *ot)
|
|||
FILE_DEFAULTDISPLAY,
|
||||
FILE_SORT_DEFAULT);
|
||||
|
||||
PropertyRNA *prop = RNA_def_string(ot->srna, "filter_glob", "*.abc", 0, "", "");
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN);
|
||||
|
||||
RNA_def_int(ot->srna,
|
||||
"start",
|
||||
INT_MIN,
|
||||
|
@ -673,6 +676,9 @@ void WM_OT_alembic_import(wmOperatorType *ot)
|
|||
FILE_DEFAULTDISPLAY,
|
||||
FILE_SORT_DEFAULT);
|
||||
|
||||
PropertyRNA *prop = RNA_def_string(ot->srna, "filter_glob", "*.abc", 0, "", "");
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN);
|
||||
|
||||
RNA_def_float(
|
||||
ot->srna,
|
||||
"scale",
|
||||
|
|
|
@ -454,6 +454,9 @@ void WM_OT_collada_export(wmOperatorType *ot)
|
|||
FILE_DEFAULTDISPLAY,
|
||||
FILE_SORT_DEFAULT);
|
||||
|
||||
PropertyRNA *prop = RNA_def_string(ot->srna, "filter_glob", "*.dae", 0, "", "");
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN);
|
||||
|
||||
RNA_def_enum(ot->srna,
|
||||
"prop_bc_export_ui_section",
|
||||
prop_bc_export_ui_section,
|
||||
|
@ -776,6 +779,9 @@ void WM_OT_collada_import(wmOperatorType *ot)
|
|||
FILE_DEFAULTDISPLAY,
|
||||
FILE_SORT_DEFAULT);
|
||||
|
||||
PropertyRNA *prop = RNA_def_string(ot->srna, "filter_glob", "*.dae", 0, "", "");
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN);
|
||||
|
||||
RNA_def_boolean(ot->srna,
|
||||
"import_units",
|
||||
0,
|
||||
|
|
|
@ -258,6 +258,9 @@ void WM_OT_usd_export(struct wmOperatorType *ot)
|
|||
FILE_DEFAULTDISPLAY,
|
||||
FILE_SORT_DEFAULT);
|
||||
|
||||
PropertyRNA *prop = RNA_def_string(ot->srna, "filter_glob", "*.usd", 0, "", "");
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN);
|
||||
|
||||
RNA_def_boolean(ot->srna,
|
||||
"selected_objects_only",
|
||||
false,
|
||||
|
@ -557,6 +560,9 @@ void WM_OT_usd_import(struct wmOperatorType *ot)
|
|||
FILE_DEFAULTDISPLAY,
|
||||
FILE_SORT_DEFAULT);
|
||||
|
||||
PropertyRNA *prop = RNA_def_string(ot->srna, "filter_glob", "*.usd", 0, "", "");
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN);
|
||||
|
||||
RNA_def_float(
|
||||
ot->srna,
|
||||
"scale",
|
||||
|
|
Loading…
Reference in New Issue