diff options
author | Hans Goudey <h.goudey@me.com> | 2021-04-22 17:25:40 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2021-04-22 17:25:40 +0300 |
commit | 26d4864ee63cd0e80eb445c5cc30ab24829562ef (patch) | |
tree | 2cdd72484a4d22b27640d491cdf66796d12fd4f1 /source/blender | |
parent | da443d82eecc8cac005db072ee6e4efbc6ec6a1d (diff) | |
parent | d1ccc5b9694b7c737158f4d4bd83ae780b32d258 (diff) |
Merge branch 'master' into geometry-nodes-curve-support
Diffstat (limited to 'source/blender')
33 files changed, 380 insertions, 149 deletions
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c index f83ee409187..b7c226ada1d 100644 --- a/source/blender/blenfont/intern/blf_font.c +++ b/source/blender/blenfont/intern/blf_font.c @@ -41,6 +41,7 @@ #include "BLI_listbase.h" #include "BLI_math.h" +#include "BLI_math_color_blend.h" #include "BLI_rect.h" #include "BLI_string.h" #include "BLI_string_utf8.h" @@ -640,18 +641,12 @@ static void blf_font_draw_buffer_ex(FontBLF *font, (size_t)buf_info->ch); float *fbuf = buf_info->fbuf + buf_ofs; - if (a >= 1.0f) { - fbuf[0] = b_col_float[0]; - fbuf[1] = b_col_float[1]; - fbuf[2] = b_col_float[2]; - fbuf[3] = 1.0f; - } - else { - fbuf[0] = (b_col_float[0] * a) + (fbuf[0] * (1.0f - a)); - fbuf[1] = (b_col_float[1] * a) + (fbuf[1] * (1.0f - a)); - fbuf[2] = (b_col_float[2] * a) + (fbuf[2] * (1.0f - a)); - fbuf[3] = MIN2(fbuf[3] + a, 1.0f); /* clamp to 1.0 */ - } + float font_pixel[4]; + font_pixel[0] = b_col_float[0] * a; + font_pixel[1] = b_col_float[1] * a; + font_pixel[2] = b_col_float[2] * a; + font_pixel[3] = a; + blend_color_mix_float(fbuf, fbuf, font_pixel); } } @@ -677,19 +672,12 @@ static void blf_font_draw_buffer_ex(FontBLF *font, (size_t)buf_info->ch); unsigned char *cbuf = buf_info->cbuf + buf_ofs; - if (a >= 1.0f) { - cbuf[0] = b_col_char[0]; - cbuf[1] = b_col_char[1]; - cbuf[2] = b_col_char[2]; - cbuf[3] = 255; - } - else { - cbuf[0] = (unsigned char)((b_col_char[0] * a) + (cbuf[0] * (1.0f - a))); - cbuf[1] = (unsigned char)((b_col_char[1] * a) + (cbuf[1] * (1.0f - a))); - cbuf[2] = (unsigned char)((b_col_char[2] * a) + (cbuf[2] * (1.0f - a))); - /* clamp to 255 */ - cbuf[3] = (unsigned char)MIN2((int)cbuf[3] + (int)(a * 255), 255); - } + uchar font_pixel[4]; + font_pixel[0] = b_col_char[0]; + font_pixel[1] = b_col_char[1]; + font_pixel[2] = b_col_char[2]; + font_pixel[3] = unit_float_to_uchar_clamp(a); + blend_color_mix_byte(cbuf, cbuf, font_pixel); } } diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh index b9fdf5f37b4..cfcd9d25638 100644 --- a/source/blender/blenkernel/BKE_geometry_set.hh +++ b/source/blender/blenkernel/BKE_geometry_set.hh @@ -72,6 +72,65 @@ using AttributeForeachCallback = blender::FunctionRef<bool(blender::StringRefNul const AttributeMetaData &meta_data)>; /** + * Base class for the attribute intializer types described below. + */ +struct AttributeInit { + enum class Type { + Default, + VArray, + MoveArray, + }; + Type type; + AttributeInit(const Type type) : type(type) + { + } +}; + +/** + * Create an attribute using the default value for the data type. + * The default values may depend on the attribute provider implementation. + */ +struct AttributeInitDefault : public AttributeInit { + AttributeInitDefault() : AttributeInit(Type::Default) + { + } +}; + +/** + * Create an attribute by copying data from an existing virtual array. The virtual array + * must have the same type as the newly created attribute. + * + * Note that this can be used to fill the new attribute with the default + */ +struct AttributeInitVArray : public AttributeInit { + const blender::fn::GVArray *varray; + + AttributeInitVArray(const blender::fn::GVArray *varray) + : AttributeInit(Type::VArray), varray(varray) + { + } +}; + +/** + * Create an attribute with a by passing ownership of a pre-allocated contiguous array of data. + * Sometimes data is created before a geometry component is available. In that case, it's + * preferable to move data directly to the created attribute to avoid a new allocation and a copy. + * + * Note that this will only have a benefit for attributes that are stored directly as contigious + * arrays, so not for some built-in attributes. + * + * The array must be allocated with MEM_*, since `attribute_try_create` will free the array if it + * can't be used directly, and that is generally how Blender expects custom data to be allocated. + */ +struct AttributeInitMove : public AttributeInit { + void *data = nullptr; + + AttributeInitMove(void *data) : AttributeInit(Type::MoveArray), data(data) + { + } +}; + +/** * This is the base class for specialized geometry component types. */ class GeometryComponent { @@ -104,6 +163,10 @@ class GeometryComponent { /* Return true when any attribute with this name exists, including built in attributes. */ bool attribute_exists(const blender::StringRef attribute_name) const; + /* Return the data type and domain of an attribute with the given name if it exists. */ + std::optional<AttributeMetaData> attribute_get_meta_data( + const blender::StringRef attribute_name) const; + /* Returns true when the geometry component supports this attribute domain. */ bool attribute_domain_supported(const AttributeDomain domain) const; /* Can only be used with supported domain types. */ @@ -135,11 +198,13 @@ class GeometryComponent { /* Returns true when the attribute has been created. */ bool attribute_try_create(const blender::StringRef attribute_name, const AttributeDomain domain, - const CustomDataType data_type); + const CustomDataType data_type, + const AttributeInit &initializer); /* Try to create the builtin attribute with the given name. No data type or domain has to be * provided, because those are fixed for builtin attributes. */ - bool attribute_try_create_builtin(const blender::StringRef attribute_name); + bool attribute_try_create_builtin(const blender::StringRef attribute_name, + const AttributeInit &initializer); blender::Set<std::string> attribute_names() const; bool attribute_foreach(const AttributeForeachCallback callback) const; diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc index 656c669f5f6..32a4885572d 100644 --- a/source/blender/blenkernel/intern/attribute_access.cc +++ b/source/blender/blenkernel/intern/attribute_access.cc @@ -252,7 +252,43 @@ bool BuiltinCustomDataLayerProvider::try_delete(GeometryComponent &component) co return delete_success; } -bool BuiltinCustomDataLayerProvider::try_create(GeometryComponent &component) const +static bool add_custom_data_layer_from_attribute_init(CustomData &custom_data, + const CustomDataType data_type, + const int domain_size, + const AttributeInit &initializer) +{ + switch (initializer.type) { + case AttributeInit::Type::Default: { + void *data = CustomData_add_layer(&custom_data, data_type, CD_DEFAULT, nullptr, domain_size); + return data != nullptr; + } + case AttributeInit::Type::VArray: { + void *data = CustomData_add_layer(&custom_data, data_type, CD_DEFAULT, nullptr, domain_size); + if (data == nullptr) { + return false; + } + const GVArray *varray = static_cast<const AttributeInitVArray &>(initializer).varray; + varray->materialize_to_uninitialized(IndexRange(varray->size()), data); + return true; + } + case AttributeInit::Type::MoveArray: { + void *source_data = static_cast<const AttributeInitMove &>(initializer).data; + void *data = CustomData_add_layer( + &custom_data, data_type, CD_ASSIGN, source_data, domain_size); + if (data == nullptr) { + MEM_freeN(source_data); + return false; + } + return true; + } + } + + BLI_assert_unreachable(); + return false; +} + +bool BuiltinCustomDataLayerProvider::try_create(GeometryComponent &component, + const AttributeInit &initializer) const { if (createable_ != Creatable) { return false; @@ -265,10 +301,10 @@ bool BuiltinCustomDataLayerProvider::try_create(GeometryComponent &component) co /* Exists already. */ return false; } + const int domain_size = component.attribute_domain_size(domain_); - const void *data = CustomData_add_layer( - custom_data, stored_type_, CD_DEFAULT, nullptr, domain_size); - const bool success = data != nullptr; + const bool success = add_custom_data_layer_from_attribute_init( + *custom_data, stored_type_, domain_size, initializer); if (success) { custom_data_access_.update_custom_data_pointers(component); } @@ -370,10 +406,52 @@ bool CustomDataAttributeProvider::try_delete(GeometryComponent &component, return false; } +static bool add_named_custom_data_layer_from_attribute_init(const StringRef attribute_name, + CustomData &custom_data, + const CustomDataType data_type, + const int domain_size, + const AttributeInit &initializer) +{ + char attribute_name_c[MAX_NAME]; + attribute_name.copy(attribute_name_c); + + switch (initializer.type) { + case AttributeInit::Type::Default: { + void *data = CustomData_add_layer_named( + &custom_data, data_type, CD_DEFAULT, nullptr, domain_size, attribute_name_c); + return data != nullptr; + } + case AttributeInit::Type::VArray: { + void *data = CustomData_add_layer_named( + &custom_data, data_type, CD_DEFAULT, nullptr, domain_size, attribute_name_c); + if (data == nullptr) { + return false; + } + const GVArray *varray = static_cast<const AttributeInitVArray &>(initializer).varray; + varray->materialize_to_uninitialized(IndexRange(varray->size()), data); + return true; + } + case AttributeInit::Type::MoveArray: { + void *source_data = static_cast<const AttributeInitMove &>(initializer).data; + void *data = CustomData_add_layer_named( + &custom_data, data_type, CD_ASSIGN, source_data, domain_size, attribute_name_c); + if (data == nullptr) { + MEM_freeN(source_data); + return false; + } + return true; + } + } + + BLI_assert_unreachable(); + return false; +} + bool CustomDataAttributeProvider::try_create(GeometryComponent &component, const StringRef attribute_name, const AttributeDomain domain, - const CustomDataType data_type) const + const CustomDataType data_type, + const AttributeInit &initializer) const { if (domain_ != domain) { return false; @@ -391,10 +469,8 @@ bool CustomDataAttributeProvider::try_create(GeometryComponent &component, } } const int domain_size = component.attribute_domain_size(domain_); - char attribute_name_c[MAX_NAME]; - attribute_name.copy(attribute_name_c); - CustomData_add_layer_named( - custom_data, data_type, CD_DEFAULT, nullptr, domain_size, attribute_name_c); + add_named_custom_data_layer_from_attribute_init( + attribute_name, *custom_data, data_type, domain_size, initializer); return true; } @@ -619,7 +695,8 @@ bool GeometryComponent::attribute_try_delete(const StringRef attribute_name) bool GeometryComponent::attribute_try_create(const StringRef attribute_name, const AttributeDomain domain, - const CustomDataType data_type) + const CustomDataType data_type, + const AttributeInit &initializer) { using namespace blender::bke; if (attribute_name.is_empty()) { @@ -638,18 +715,19 @@ bool GeometryComponent::attribute_try_create(const StringRef attribute_name, if (builtin_provider->data_type() != data_type) { return false; } - return builtin_provider->try_create(*this); + return builtin_provider->try_create(*this, initializer); } for (const DynamicAttributesProvider *dynamic_provider : providers->dynamic_attribute_providers()) { - if (dynamic_provider->try_create(*this, attribute_name, domain, data_type)) { + if (dynamic_provider->try_create(*this, attribute_name, domain, data_type, initializer)) { return true; } } return false; } -bool GeometryComponent::attribute_try_create_builtin(const blender::StringRef attribute_name) +bool GeometryComponent::attribute_try_create_builtin(const blender::StringRef attribute_name, + const AttributeInit &initializer) { using namespace blender::bke; if (attribute_name.is_empty()) { @@ -664,7 +742,7 @@ bool GeometryComponent::attribute_try_create_builtin(const blender::StringRef at if (builtin_provider == nullptr) { return false; } - return builtin_provider->try_create(*this); + return builtin_provider->try_create(*this, initializer); } Set<std::string> GeometryComponent::attribute_names() const @@ -727,6 +805,20 @@ bool GeometryComponent::attribute_exists(const blender::StringRef attribute_name return false; } +std::optional<AttributeMetaData> GeometryComponent::attribute_get_meta_data( + const StringRef attribute_name) const +{ + std::optional<AttributeMetaData> result{std::nullopt}; + this->attribute_foreach([&](StringRefNull name, const AttributeMetaData &meta_data) { + if (attribute_name == name) { + result = meta_data; + return false; + } + return true; + }); + return result; +} + static std::unique_ptr<blender::fn::GVArray> try_adapt_data_type( std::unique_ptr<blender::fn::GVArray> varray, const blender::fn::CPPType &to_type) { @@ -858,7 +950,8 @@ static void save_output_attribute(blender::bke::OutputAttribute &output_attribut const CPPType &cpp_type = output_attribute.cpp_type(); component.attribute_try_delete(name); - if (!component.attribute_try_create(varray.final_name, domain, data_type)) { + if (!component.attribute_try_create( + varray.final_name, domain, data_type, AttributeInitDefault())) { CLOG_WARN(&LOG, "Could not create the '%s' attribute with type '%s'.", name.c_str(), @@ -896,7 +989,15 @@ static blender::bke::OutputAttribute create_output_attribute( if (component.attribute_is_builtin(attribute_name)) { WriteAttributeLookup attribute = component.attribute_try_get_for_write(attribute_name); if (!attribute) { - component.attribute_try_create_builtin(attribute_name); + if (default_value) { + const int64_t domain_size = component.attribute_domain_size(domain); + const GVArray_For_SingleValueRef default_varray{*cpp_type, domain_size, default_value}; + component.attribute_try_create_builtin(attribute_name, + AttributeInitVArray(&default_varray)); + } + else { + component.attribute_try_create_builtin(attribute_name, AttributeInitDefault()); + } attribute = component.attribute_try_get_for_write(attribute_name); if (!attribute) { /* Builtin attribute does not exist and can't be created. */ @@ -917,9 +1018,19 @@ static blender::bke::OutputAttribute create_output_attribute( return OutputAttribute(std::move(varray), domain, {}, ignore_old_values); } + const int domain_size = component.attribute_domain_size(domain); + WriteAttributeLookup attribute = component.attribute_try_get_for_write(attribute_name); if (!attribute) { - component.attribute_try_create(attribute_name, domain, data_type); + if (default_value) { + const GVArray_For_SingleValueRef default_varray{*cpp_type, domain_size, default_value}; + component.attribute_try_create( + attribute_name, domain, data_type, AttributeInitVArray(&default_varray)); + } + else { + component.attribute_try_create(attribute_name, domain, data_type, AttributeInitDefault()); + } + attribute = component.attribute_try_get_for_write(attribute_name); if (!attribute) { /* Can't create the attribute. */ @@ -931,7 +1042,6 @@ static blender::bke::OutputAttribute create_output_attribute( return OutputAttribute(std::move(attribute.varray), domain, {}, ignore_old_values); } - const int domain_size = component.attribute_domain_size(domain); /* Allocate a new array that lives next to the existing attribute. It will overwrite the existing * attribute after processing is done. */ void *data = MEM_mallocN_aligned( diff --git a/source/blender/blenkernel/intern/attribute_access_intern.hh b/source/blender/blenkernel/intern/attribute_access_intern.hh index 7cf585dfbfc..b3a795faa30 100644 --- a/source/blender/blenkernel/intern/attribute_access_intern.hh +++ b/source/blender/blenkernel/intern/attribute_access_intern.hh @@ -89,7 +89,8 @@ class BuiltinAttributeProvider { virtual GVArrayPtr try_get_for_read(const GeometryComponent &component) const = 0; virtual GVMutableArrayPtr try_get_for_write(GeometryComponent &component) const = 0; virtual bool try_delete(GeometryComponent &component) const = 0; - virtual bool try_create(GeometryComponent &UNUSED(component)) const = 0; + virtual bool try_create(GeometryComponent &UNUSED(component), + const AttributeInit &UNUSED(initializer)) const = 0; virtual bool exists(const GeometryComponent &component) const = 0; StringRefNull name() const @@ -122,7 +123,8 @@ class DynamicAttributesProvider { virtual bool try_create(GeometryComponent &UNUSED(component), const StringRef UNUSED(attribute_name), const AttributeDomain UNUSED(domain), - const CustomDataType UNUSED(data_type)) const + const CustomDataType UNUSED(data_type), + const AttributeInit &UNUSED(initializer)) const { /* Some providers should not create new attributes. */ return false; @@ -162,7 +164,8 @@ class CustomDataAttributeProvider final : public DynamicAttributesProvider { bool try_create(GeometryComponent &component, const StringRef attribute_name, const AttributeDomain domain, - const CustomDataType data_type) const final; + const CustomDataType data_type, + const AttributeInit &initializer) const final; bool foreach_attribute(const GeometryComponent &component, const AttributeForeachCallback callback) const final; @@ -278,7 +281,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; bool try_delete(GeometryComponent &component) const final; - bool try_create(GeometryComponent &component) const final; + bool try_create(GeometryComponent &component, const AttributeInit &initializer) const final; bool exists(const GeometryComponent &component) const final; }; diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc index e5accd98952..e54c3716660 100644 --- a/source/blender/blenkernel/intern/geometry_component_mesh.cc +++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc @@ -1014,7 +1014,8 @@ class NormalAttributeProvider final : public BuiltinAttributeProvider { return false; } - bool try_create(GeometryComponent &UNUSED(component)) const final + bool try_create(GeometryComponent &UNUSED(component), + const AttributeInit &UNUSED(initializer)) const final { return false; } diff --git a/source/blender/blenkernel/intern/geometry_set_instances.cc b/source/blender/blenkernel/intern/geometry_set_instances.cc index 2e9f6daabad..47db5d1f901 100644 --- a/source/blender/blenkernel/intern/geometry_set_instances.cc +++ b/source/blender/blenkernel/intern/geometry_set_instances.cc @@ -449,7 +449,8 @@ static void join_attributes(Span<GeometryInstanceGroup> set_groups, const CPPType *cpp_type = bke::custom_data_type_to_cpp_type(data_type_output); BLI_assert(cpp_type != nullptr); - result.attribute_try_create(entry.key, domain_output, data_type_output); + result.attribute_try_create( + entry.key, domain_output, data_type_output, AttributeInitDefault()); WriteAttributeLookup write_attribute = result.attribute_try_get_for_write(name); if (!write_attribute || &write_attribute.varray->type() != cpp_type || write_attribute.domain != domain_output) { diff --git a/source/blender/blenkernel/intern/mesh_mirror.c b/source/blender/blenkernel/intern/mesh_mirror.c index a22b52d68d5..93a2e9058fa 100644 --- a/source/blender/blenkernel/intern/mesh_mirror.c +++ b/source/blender/blenkernel/intern/mesh_mirror.c @@ -51,7 +51,7 @@ Mesh *BKE_mesh_mirror_bisect_on_mirror_plane_for_modifier(MirrorModifierData *mm (axis == 1 && mmd->flag & MOD_MIR_BISECT_FLIP_AXIS_Y) || (axis == 2 && mmd->flag & MOD_MIR_BISECT_FLIP_AXIS_Z)); - const float bisect_distance = 0.001f; + const float bisect_distance = mmd->bisect_threshold; Mesh *result; BMesh *bm; diff --git a/source/blender/blenloader/intern/versioning_300.c b/source/blender/blenloader/intern/versioning_300.c index e98062c3703..6b13b21f057 100644 --- a/source/blender/blenloader/intern/versioning_300.c +++ b/source/blender/blenloader/intern/versioning_300.c @@ -20,6 +20,12 @@ /* allow readfile to use deprecated functionality */ #define DNA_DEPRECATED_ALLOW +#include "BLI_listbase.h" +#include "BLI_utildefines.h" + +#include "DNA_genfile.h" +#include "DNA_modifier_types.h" + #include "BKE_main.h" #include "BLO_readfile.h" @@ -27,7 +33,6 @@ void do_versions_after_linking_300(Main *UNUSED(bmain), ReportList *UNUSED(reports)) { - /** * Versioning code until next subversion bump goes here. * @@ -44,9 +49,8 @@ void do_versions_after_linking_300(Main *UNUSED(bmain), ReportList *UNUSED(repor } /* NOLINTNEXTLINE: readability-function-size */ -void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *UNUSED(bmain)) +void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain) { - UNUSED_VARS(fd); /** * Versioning code until next subversion bump goes here. @@ -59,5 +63,18 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *UNUSED(bmain) */ { /* Keep this block, even when empty. */ + + /* Set default value for the new bisect_threshold parameter in the mirror modifier. */ + if (!DNA_struct_elem_find(fd->filesdna, "MirrorModifierData", "float", "bisect_threshold")) { + LISTBASE_FOREACH (Object *, ob, &bmain->objects) { + LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) { + if (md->type == eModifierType_Mirror) { + MirrorModifierData *mmd = (MirrorModifierData *)md; + /* This was the previous hard-coded value. */ + mmd->bisect_threshold = 0.001f; + } + } + } + } } } diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h index 12d6f1fce54..179c9d5b30d 100644 --- a/source/blender/editors/include/ED_keyframing.h +++ b/source/blender/editors/include/ED_keyframing.h @@ -511,6 +511,7 @@ bool ED_autokeyframe_property(struct bContext *C, #define ANIM_KS_ROTATION_ID "Rotation" #define ANIM_KS_SCALING_ID "Scaling" #define ANIM_KS_LOC_ROT_SCALE_ID "LocRotScale" +#define ANIM_KS_LOC_ROT_SCALE_CPROP_ID "LocRotScaleCProp" #define ANIM_KS_AVAILABLE_ID "Available" #define ANIM_KS_WHOLE_CHARACTER_ID "WholeCharacter" #define ANIM_KS_WHOLE_CHARACTER_SELECTED_ID "WholeCharacterSelected" diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index 3277baeba5b..512f912a532 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.c @@ -43,6 +43,7 @@ #include "BKE_curve.h" #include "BKE_duplilist.h" #include "BKE_editmesh.h" +#include "BKE_geometry_set.h" #include "BKE_global.h" #include "BKE_layer.h" #include "BKE_mesh.h" @@ -500,10 +501,12 @@ static void iter_snap_objects(SnapObjectContext *sctx, } Object *obj_eval = DEG_get_evaluated_object(depsgraph, base->object); - if (obj_eval->transflag & OB_DUPLI) { - DupliObject *dupli_ob; + if (obj_eval->transflag & OB_DUPLI || + (obj_eval->runtime.geometry_set_eval != NULL && + BKE_geometry_set_has_instances(obj_eval->runtime.geometry_set_eval))) { ListBase *lb = object_duplilist(depsgraph, sctx->scene, obj_eval); - for (dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) { + for (DupliObject *dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) { + BLI_assert(DEG_is_evaluated_object(dupli_ob->ob)); sob_callback(sctx, dupli_ob->ob, dupli_ob->mat, diff --git a/source/blender/makesdna/DNA_modifier_defaults.h b/source/blender/makesdna/DNA_modifier_defaults.h index d8e48c51107..f6dac88051b 100644 --- a/source/blender/makesdna/DNA_modifier_defaults.h +++ b/source/blender/makesdna/DNA_modifier_defaults.h @@ -429,6 +429,7 @@ { \ .flag = MOD_MIR_AXIS_X | MOD_MIR_VGROUP, \ .tolerance = 0.001f, \ + .bisect_threshold = 0.001f, \ .uv_offset = {0.0f, 0.0f}, \ .uv_offset_copy = {0.0f, 0.0f}, \ .mirror_ob = NULL, \ diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index ca6f1467d9c..c61e940190f 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -368,6 +368,8 @@ typedef struct MirrorModifierData { short axis DNA_DEPRECATED; short flag; float tolerance; + float bisect_threshold; + char _pad[4]; float uv_offset[2]; float uv_offset_copy[2]; struct Object *mirror_ob; diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 67335b81a31..e3fb443951f 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -2226,6 +2226,14 @@ static void rna_def_modifier_mirror(BlenderRNA *brna) prop, "Merge Distance", "Distance within which mirrored vertices are merged"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); + prop = RNA_def_property(srna, "bisect_threshold", PROP_FLOAT, PROP_DISTANCE); + RNA_def_property_float_sdna(prop, NULL, "bisect_threshold"); + RNA_def_property_range(prop, 0, FLT_MAX); + RNA_def_property_ui_range(prop, 0, 1, 0.01, 6); + RNA_def_property_ui_text( + prop, "Bisect Distance", "Distance from the bisect plane within which vertices are removed"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + prop = RNA_def_property(srna, "mirror_object", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "mirror_ob"); RNA_def_property_ui_text(prop, "Mirror Object", "Object to use as mirror"); diff --git a/source/blender/modifiers/intern/MOD_mirror.c b/source/blender/modifiers/intern/MOD_mirror.c index afe94d8dead..b800ce7f803 100644 --- a/source/blender/modifiers/intern/MOD_mirror.c +++ b/source/blender/modifiers/intern/MOD_mirror.c @@ -165,6 +165,13 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel) uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_mirror_merge")); uiItemR(sub, ptr, "merge_threshold", 0, "", ICON_NONE); + bool is_bisect_set[3]; + RNA_boolean_get_array(ptr, "use_bisect_axis", is_bisect_set); + + sub = uiLayoutRow(col, true); + uiLayoutSetActive(sub, is_bisect_set[0] || is_bisect_set[1] || is_bisect_set[2]); + uiItemR(sub, ptr, "bisect_threshold", 0, IFACE_("Bisect Distance"), ICON_NONE); + modifier_panel_end(layout, ptr); } diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index d3f12a8a941..f72a21ffe1b 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -271,6 +271,17 @@ static bool isDisabled(const struct Scene *UNUSED(scene), return false; } +static bool logging_enabled(const ModifierEvalContext *ctx) +{ + if (!DEG_is_active(ctx->depsgraph)) { + return false; + } + if ((ctx->flag & MOD_APPLY_ORCO) != 0) { + return false; + } + return true; +} + class GeometryNodesEvaluator { public: using LogSocketValueFn = std::function<void(DSocket, Span<GPointer>)>; @@ -1290,7 +1301,7 @@ static GeometrySet compute_geometry(const DerivedNodeTree &tree, find_sockets_to_preview(nmd, ctx, tree, preview_sockets); auto log_socket_value = [&](const DSocket socket, const Span<GPointer> values) { - if (!DEG_is_active(ctx->depsgraph)) { + if (!logging_enabled(ctx)) { return; } Span<uint64_t> keys = preview_sockets.lookup(socket); @@ -1401,7 +1412,7 @@ static void modifyGeometry(ModifierData *md, return; } - if (DEG_is_active(ctx->depsgraph)) { + if (logging_enabled(ctx)) { reset_tree_ui_storage(tree.used_node_tree_refs(), *ctx->object, *md); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_clamp.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_clamp.cc index 06679adbf97..b544c962849 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_clamp.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_clamp.cc @@ -126,13 +126,13 @@ static AttributeDomain get_result_domain(const GeometryComponent &component, StringRef source_name, StringRef result_name) { - ReadAttributeLookup result_attribute = component.attribute_try_get_for_read(result_name); - if (result_attribute) { - return result_attribute.domain; + std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(result_name); + if (result_info) { + return result_info->domain; } - ReadAttributeLookup source_attribute = component.attribute_try_get_for_read(source_name); - if (source_attribute) { - return source_attribute.domain; + std::optional<AttributeMetaData> source_info = component.attribute_get_meta_data(source_name); + if (source_info) { + return source_info->domain; } return ATTR_DOMAIN_POINT; } diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_color_ramp.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_color_ramp.cc index 05ff100603f..6e41573470d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_color_ramp.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_color_ramp.cc @@ -47,15 +47,15 @@ static AttributeDomain get_result_domain(const GeometryComponent &component, StringRef result_name) { /* Use the domain of the result attribute if it already exists. */ - ReadAttributeLookup result_attribute = component.attribute_try_get_for_read(result_name); - if (result_attribute) { - return result_attribute.domain; + std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(result_name); + if (result_info) { + return result_info->domain; } /* Otherwise use the input attribute's domain if it exists. */ - ReadAttributeLookup input_attribute = component.attribute_try_get_for_read(input_name); - if (input_attribute) { - return input_attribute.domain; + std::optional<AttributeMetaData> source_info = component.attribute_get_meta_data(input_name); + if (source_info) { + return source_info->domain; } return ATTR_DOMAIN_POINT; diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_combine_xyz.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_combine_xyz.cc index 10e9d9c44f8..b30b2ff113f 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_combine_xyz.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_combine_xyz.cc @@ -77,9 +77,9 @@ static AttributeDomain get_result_domain(const GeometryComponent &component, StringRef result_name) { /* Use the domain of the result attribute if it already exists. */ - ReadAttributeLookup result_attribute = component.attribute_try_get_for_read(result_name); - if (result_attribute) { - return result_attribute.domain; + std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(result_name); + if (result_info) { + return result_info->domain; } /* Otherwise use the highest priority domain from existing input attributes, or the default. */ diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_compare.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_compare.cc index 103ef7befa3..dfaeeaa85aa 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_compare.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_compare.cc @@ -234,9 +234,9 @@ static AttributeDomain get_result_domain(const GeometryComponent &component, StringRef result_name) { /* Use the domain of the result attribute if it already exists. */ - ReadAttributeLookup result_attribute = component.attribute_try_get_for_read(result_name); - if (result_attribute) { - return result_attribute.domain; + std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(result_name); + if (result_info) { + return result_info->domain; } /* Otherwise use the highest priority domain from existing input attributes, or the default. */ diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_convert.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_convert.cc index efcd5fd01a9..cfc8e5801fc 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_convert.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_convert.cc @@ -55,13 +55,13 @@ static AttributeDomain get_result_domain(const GeometryComponent &component, StringRef source_name, StringRef result_name) { - ReadAttributeLookup result_attribute = component.attribute_try_get_for_read(result_name); - if (result_attribute) { - return result_attribute.domain; + std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(result_name); + if (result_info) { + return result_info->domain; } - ReadAttributeLookup source_attribute = component.attribute_try_get_for_read(source_name); - if (source_attribute) { - return source_attribute.domain; + std::optional<AttributeMetaData> source_info = component.attribute_get_meta_data(source_name); + if (source_info) { + return source_info->domain; } return ATTR_DOMAIN_POINT; } @@ -75,14 +75,14 @@ static bool conversion_can_be_skipped(const GeometryComponent &component, if (source_name != result_name) { return false; } - ReadAttributeLookup read_attribute = component.attribute_try_get_for_read(source_name); - if (!read_attribute) { + std::optional<AttributeMetaData> info = component.attribute_get_meta_data(result_name); + if (!info) { return false; } - if (read_attribute.domain != result_domain) { + if (info->domain != result_domain) { return false; } - if (read_attribute.varray->type() != *bke::custom_data_type_to_cpp_type(result_type)) { + if (info->data_type != result_type) { return false; } return true; diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc index eeef3ead6bf..dd77a8101b5 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc @@ -68,13 +68,12 @@ static void geo_node_attribute_fill_update(bNodeTree *UNUSED(ntree), bNode *node namespace blender::nodes { -static AttributeDomain get_result_domain(const GeometryComponent &component, - StringRef attribute_name) +static AttributeDomain get_result_domain(const GeometryComponent &component, const StringRef name) { /* Use the domain of the result attribute if it already exists. */ - ReadAttributeLookup result_attribute = component.attribute_try_get_for_read(attribute_name); - if (result_attribute) { - return result_attribute.domain; + std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(name); + if (result_info) { + return result_info->domain; } return ATTR_DOMAIN_POINT; } diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_map_range.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_map_range.cc index f30fa541f70..6b7e3ba3a3f 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_map_range.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_map_range.cc @@ -318,13 +318,13 @@ static AttributeDomain get_result_domain(const GeometryComponent &component, StringRef source_name, StringRef result_name) { - ReadAttributeLookup result_attribute = component.attribute_try_get_for_read(result_name); - if (result_attribute) { - return result_attribute.domain; + std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(result_name); + if (result_info) { + return result_info->domain; } - ReadAttributeLookup source_attribute = component.attribute_try_get_for_read(source_name); - if (source_attribute) { - return source_attribute.domain; + std::optional<AttributeMetaData> source_info = component.attribute_get_meta_data(source_name); + if (source_info) { + return source_info->domain; } return ATTR_DOMAIN_POINT; } diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_math.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_math.cc index aa92ce081e9..8f03e0db04f 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_math.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_math.cc @@ -200,9 +200,9 @@ static AttributeDomain get_result_domain(const GeometryComponent &component, StringRef result_name) { /* Use the domain of the result attribute if it already exists. */ - ReadAttributeLookup result_attribute = component.attribute_try_get_for_read(result_name); - if (result_attribute) { - return result_attribute.domain; + std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(result_name); + if (result_info) { + return result_info->domain; } /* Otherwise use the highest priority domain from existing input attributes, or the default. */ diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_mix.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_mix.cc index 2a64cfaa41f..dcec53b53d9 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_mix.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_mix.cc @@ -141,9 +141,9 @@ static AttributeDomain get_result_domain(const GeometryComponent &component, StringRef result_name) { /* Use the domain of the result attribute if it already exists. */ - ReadAttributeLookup result_attribute = component.attribute_try_get_for_read(result_name); - if (result_attribute) { - return result_attribute.domain; + std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(result_name); + if (result_info) { + return result_info->domain; } /* Otherwise use the highest priority domain from existing input attributes, or the default. */ diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc index 815bf083e86..f10e752268a 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc @@ -196,12 +196,12 @@ Array<uint32_t> get_geometry_element_ids_as_uints(const GeometryComponent &compo static AttributeDomain get_result_domain(const GeometryComponent &component, const GeoNodeExecParams ¶ms, - StringRef attribute_name) + const StringRef name) { /* Use the domain of the result attribute if it already exists. */ - ReadAttributeLookup result_attribute = component.attribute_try_get_for_read(attribute_name); - if (result_attribute) { - return result_attribute.domain; + std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(name); + if (result_info) { + return result_info->domain; } /* Otherwise use the input domain chosen in the interface. */ diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_sample_texture.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_sample_texture.cc index 18de78a056d..26912efff4c 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_sample_texture.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_sample_texture.cc @@ -49,20 +49,19 @@ static void geo_node_attribute_sample_texture_layout(uiLayout *layout, namespace blender::nodes { static AttributeDomain get_result_domain(const GeometryComponent &component, - StringRef result_attribute_name, - StringRef map_attribute_name) + const StringRef result_name, + const StringRef map_name) { /* Use the domain of the result attribute if it already exists. */ - ReadAttributeLookup result_attribute = component.attribute_try_get_for_read( - result_attribute_name); - if (result_attribute) { - return result_attribute.domain; + std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(result_name); + if (result_info) { + return result_info->domain; } /* Otherwise use the name of the map attribute. */ - ReadAttributeLookup map_attribute = component.attribute_try_get_for_read(map_attribute_name); - if (map_attribute) { - return map_attribute.domain; + std::optional<AttributeMetaData> map_info = component.attribute_get_meta_data(map_name); + if (map_info) { + return map_info->domain; } /* The node won't execute in this case, but we still have to return a value. */ diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_separate_xyz.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_separate_xyz.cc index 5e1b8f23b41..5192934d611 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_separate_xyz.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_separate_xyz.cc @@ -71,23 +71,23 @@ static void extract_input(const int index, const Span<float3> &input, MutableSpa static AttributeDomain get_result_domain(const GeometryComponent &component, const GeoNodeExecParams ¶ms, - StringRef result_name_x, - StringRef result_name_y, - StringRef result_name_z) + const StringRef name_x, + const StringRef name_y, + const StringRef name_z) { /* Use the highest priority domain from any existing attribute outputs. */ Vector<AttributeDomain, 3> output_domains; - ReadAttributeLookup attribute_x = component.attribute_try_get_for_read(result_name_x); - ReadAttributeLookup attribute_y = component.attribute_try_get_for_read(result_name_y); - ReadAttributeLookup attribute_z = component.attribute_try_get_for_read(result_name_z); - if (attribute_x) { - output_domains.append(attribute_x.domain); + std::optional<AttributeMetaData> info_x = component.attribute_get_meta_data(name_x); + std::optional<AttributeMetaData> info_y = component.attribute_get_meta_data(name_y); + std::optional<AttributeMetaData> info_z = component.attribute_get_meta_data(name_z); + if (info_x) { + output_domains.append(info_x->domain); } - if (attribute_y) { - output_domains.append(attribute_y.domain); + if (info_y) { + output_domains.append(info_y->domain); } - if (attribute_z) { - output_domains.append(attribute_z.domain); + if (info_z) { + output_domains.append(info_z->domain); } if (output_domains.size() > 0) { return bke::attribute_domain_highest_priority(output_domains); diff --git a/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc b/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc index 28d5d9a96f7..772bd8a1080 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc @@ -306,17 +306,14 @@ BLI_NOINLINE static void interpolate_existing_attributes( const MeshComponent &source_component = *set.get_component_for_read<MeshComponent>(); const Mesh &mesh = *source_component.get_for_read(); - /* Use a dummy read without specifying a domain or data type in order to - * get the existing attribute's domain. Interpolation is done manually based - * on the bary coords in #interpolate_attribute. */ - ReadAttributeLookup dummy_attribute = source_component.attribute_try_get_for_read( + std::optional<AttributeMetaData> attribute_info = component.attribute_get_meta_data( attribute_name); - if (!dummy_attribute) { + if (!attribute_info) { i_instance += set_group.transforms.size(); continue; } - const AttributeDomain source_domain = dummy_attribute.domain; + const AttributeDomain source_domain = attribute_info->domain; GVArrayPtr source_attribute = source_component.attribute_get_for_read( attribute_name, source_domain, output_data_type, nullptr); if (!source_attribute) { diff --git a/source/blender/nodes/intern/node_geometry_exec.cc b/source/blender/nodes/intern/node_geometry_exec.cc index 2648336f0c0..08fbe1ac1e6 100644 --- a/source/blender/nodes/intern/node_geometry_exec.cc +++ b/source/blender/nodes/intern/node_geometry_exec.cc @@ -126,11 +126,11 @@ CustomDataType GeoNodeExecParams::get_input_attribute_data_type( if (found_socket->type == SOCK_STRING) { const std::string name = this->get_input<std::string>(found_socket->identifier); - ReadAttributeLookup attribute = component.attribute_try_get_for_read(name); - if (!attribute) { - return default_type; + std::optional<AttributeMetaData> info = component.attribute_get_meta_data(name); + if (info) { + return info->data_type; } - return bke::cpp_type_to_custom_data_type(attribute.varray->type()); + return default_type; } if (found_socket->type == SOCK_FLOAT) { return CD_PROP_FLOAT; @@ -169,9 +169,9 @@ AttributeDomain GeoNodeExecParams::get_highest_priority_input_domain( if (found_socket->type == SOCK_STRING) { const std::string name = this->get_input<std::string>(found_socket->identifier); - ReadAttributeLookup attribute = component.attribute_try_get_for_read(name); - if (attribute) { - input_domains.append(attribute.domain); + std::optional<AttributeMetaData> info = component.attribute_get_meta_data(name); + if (info) { + input_domains.append(info->domain); } } } diff --git a/source/blender/python/gpu/gpu_py_buffer.c b/source/blender/python/gpu/gpu_py_buffer.c index 8ee11ff882c..e36e3b42617 100644 --- a/source/blender/python/gpu/gpu_py_buffer.c +++ b/source/blender/python/gpu/gpu_py_buffer.c @@ -81,7 +81,7 @@ static bool pygpu_buffer_pyobj_as_shape(PyObject *shape_obj, } } else if (PySequence_Check(shape_obj)) { - Py_ssize_t shape_len = PySequence_Size(shape_obj); + shape_len = PySequence_Size(shape_obj); if (shape_len > MAX_DIMENSIONS) { PyErr_SetString(PyExc_AttributeError, "too many dimensions, max is " STRINGIFY(MAX_DIMENSIONS)); @@ -111,8 +111,6 @@ static bool pygpu_buffer_pyobj_as_shape(PyObject *shape_obj, return false; } } - - *r_shape_len = shape_len; } else { PyErr_Format(PyExc_TypeError, @@ -398,7 +396,7 @@ static PyObject *pygpu_buffer__tp_new(PyTypeObject *UNUSED(type), PyObject *args return NULL; } - if (pygpu_buffer_pyobj_as_shape(length_ob, shape, &shape_len) == -1) { + if (!pygpu_buffer_pyobj_as_shape(length_ob, shape, &shape_len)) { return NULL; } diff --git a/source/blender/sequencer/intern/image_cache.c b/source/blender/sequencer/intern/image_cache.c index 290ee185865..089bb5a6bec 100644 --- a/source/blender/sequencer/intern/image_cache.c +++ b/source/blender/sequencer/intern/image_cache.c @@ -976,14 +976,34 @@ static void seq_cache_recycle_linked(Scene *scene, SeqCacheKey *base) SeqCacheKey *next = base->link_next; while (base) { + if (!BLI_ghash_haskey(cache->hash, base)) { + break; /* Key has already been removed from cache. */ + } + SeqCacheKey *prev = base->link_prev; + if (prev != NULL && prev->link_next != base) { + /* Key has been removed and replaced and doesn't belong to this chain anymore. */ + base->link_prev = NULL; + break; + } + BLI_ghash_remove(cache->hash, base, seq_cache_keyfree, seq_cache_valfree); base = prev; } base = next; while (base) { + if (!BLI_ghash_haskey(cache->hash, base)) { + break; /* Key has already been removed from cache. */ + } + next = base->link_next; + if (next != NULL && next->link_prev != base) { + /* Key has been removed and replaced and doesn't belong to this chain anymore. */ + base->link_next = NULL; + break; + } + BLI_ghash_remove(cache->hash, base, seq_cache_keyfree, seq_cache_valfree); base = next; } diff --git a/source/blender/sequencer/intern/render.c b/source/blender/sequencer/intern/render.c index 572fff0ad38..96c881c9c5f 100644 --- a/source/blender/sequencer/intern/render.c +++ b/source/blender/sequencer/intern/render.c @@ -1537,13 +1537,14 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, /* opengl offscreen render */ depsgraph = BKE_scene_ensure_depsgraph(context->bmain, scene, view_layer); BKE_scene_graph_update_for_newframe(depsgraph); + Object *camera_eval = DEG_get_evaluated_object(depsgraph, camera); ibuf = sequencer_view3d_fn( /* set for OpenGL render (NULL when scrubbing) */ depsgraph, scene, &context->scene->display.shading, context->scene->r.seq_prev_type, - camera, + camera_eval, width, height, IB_rect, diff --git a/source/blender/sequencer/intern/strip_relations.c b/source/blender/sequencer/intern/strip_relations.c index 1a2ff08bd08..1215cb78b56 100644 --- a/source/blender/sequencer/intern/strip_relations.c +++ b/source/blender/sequencer/intern/strip_relations.c @@ -114,7 +114,6 @@ static void sequence_invalidate_cache(Scene *scene, Editing *ed = scene->ed; if (invalidate_self) { - SEQ_relations_sequence_free_anim(seq); seq_cache_cleanup_sequence(scene, seq, seq, invalidate_types, false); } |