Merge remote-tracking branch 'origin/blender-v4.1-release'

This commit is contained in:
Sybren A. Stüvel
2024-03-19 11:18:31 +01:00
4 changed files with 111 additions and 0 deletions
+6
View File
@@ -394,6 +394,12 @@ struct NlaStrip *BKE_nlastrip_find_active(struct NlaTrack *nlt);
* Make the given NLA-Strip the active one within the given block.
*/
void BKE_nlastrip_set_active(struct AnimData *adt, struct NlaStrip *strip);
/**
* Find the NLA-strip with the given name within the given track.
*
* \return pointer to the strip, or nullptr when not found.
*/
struct NlaStrip *BKE_nlastrip_find_by_name(struct NlaTrack *nlt, const char *name);
/**
* Does the given NLA-strip fall within the given bounds (times)?.
+25
View File
@@ -1457,6 +1457,31 @@ void BKE_nlastrip_set_active(AnimData *adt, NlaStrip *strip)
}
}
static NlaStrip *nlastrip_find_by_name(ListBase /* NlaStrip */ *strips, const char *name)
{
LISTBASE_FOREACH (NlaStrip *, strip, strips) {
if (STREQ(strip->name, name)) {
return strip;
}
if (strip->type != NLASTRIP_TYPE_META) {
continue;
}
NlaStrip *inner_strip = nlastrip_find_by_name(&strip->strips, name);
if (inner_strip != nullptr) {
return inner_strip;
}
}
return nullptr;
}
NlaStrip *BKE_nlastrip_find_by_name(NlaTrack *nlt, const char *name)
{
return nlastrip_find_by_name(&nlt->strips, name);
}
bool BKE_nlastrip_within_bounds(NlaStrip *strip, float min, float max)
{
const float stripLen = (strip) ? strip->end - strip->start : 0.0f;
@@ -14,6 +14,7 @@
/* Define macros in `DNA_genfile.h`. */
#define DNA_GENFILE_VERSIONING_MACROS
#include "DNA_anim_types.h"
#include "DNA_brush_types.h"
#include "DNA_camera_types.h"
#include "DNA_curve_types.h"
@@ -55,6 +56,7 @@
#include "BKE_main.hh"
#include "BKE_material.h"
#include "BKE_mesh_legacy_convert.hh"
#include "BKE_nla.h"
#include "BKE_node_runtime.hh"
#include "BKE_scene.hh"
#include "BKE_tracking.h"
@@ -349,6 +351,51 @@ static void versioning_replace_splitviewer(bNodeTree *ntree)
}
}
/**
* Exit NLA tweakmode when the AnimData struct has insufficient information.
*
* When NLA tweakmode is enabled, Blender expects certain pointers to be set up
* correctly, and if that fails, can crash. This function ensures that
* everything is consistent, by exiting tweakmode everywhere there's missing
* pointers.
*
* This shouldn't happen, but the example blend file attached to #119615 needs
* this.
*/
static void version_nla_tweakmode_incomplete(Main *bmain)
{
bool any_valid_tweakmode_left = false;
ID *id;
FOREACH_MAIN_ID_BEGIN (bmain, id) {
AnimData *adt = BKE_animdata_from_id(id);
if (!adt || !(adt->flag & ADT_NLA_EDIT_ON)) {
continue;
}
if (adt->act_track && adt->actstrip) {
/* Expected case. */
any_valid_tweakmode_left = true;
continue;
}
/* Not enough info in the blend file to reliably stay in tweak mode. This is the most important
* part of this versioning code, as it prevents future nullptr access. */
BKE_nla_tweakmode_exit(adt);
}
FOREACH_MAIN_ID_END;
if (any_valid_tweakmode_left) {
/* There are still NLA strips correctly in tweak mode. */
return;
}
/* Nothing is in a valid tweakmode, so just disable the corresponding flags on all scenes. */
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
scene->flag &= ~SCE_NLA_EDIT_ON;
}
}
void do_versions_after_linking_400(FileData *fd, Main *bmain)
{
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 9)) {
@@ -443,6 +490,10 @@ void do_versions_after_linking_400(FileData *fd, Main *bmain)
}
}
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 23)) {
version_nla_tweakmode_incomplete(bmain);
}
/**
* Always bump subversion in BKE_blender_version.h when adding versioning
* code here, and wrap it inside a MAIN_VERSION_FILE_ATLEAST check.
@@ -12,6 +12,7 @@
#include "DNA_anim_types.h"
#include "DNA_scene_types.h"
#include "BLI_listbase_wrapper.hh"
#include "BLI_utildefines.h"
#include "BLT_translation.hh"
@@ -189,6 +190,34 @@ bool rna_AnimData_tweakmode_override_apply(Main * /*bmain*/,
anim_data_dst->flag = (anim_data_dst->flag & ~ADT_NLA_EDIT_ON) |
(anim_data_src->flag & ADT_NLA_EDIT_ON);
if (!(anim_data_dst->flag & ADT_NLA_EDIT_ON)) {
/* If tweak mode is not enabled, there's nothing left to do. */
return true;
}
if (!anim_data_src->act_track || !anim_data_src->actstrip) {
/* If there is not enough information to find the active track/strip, don't bother. */
return true;
}
/* AnimData::act_track and AnimData::actstrip are not directly exposed to RNA as editable &
* overridable, so the override doesn't contain this info. Reconstruct the pointers by name. */
for (NlaTrack *track : blender::ListBaseWrapper<NlaTrack>(anim_data_dst->nla_tracks)) {
if (!STREQ(track->name, anim_data_src->act_track->name)) {
continue;
}
NlaStrip *strip = BKE_nlastrip_find_by_name(track, anim_data_src->actstrip->name);
if (!strip) {
continue;
}
anim_data_dst->act_track = track;
anim_data_dst->actstrip = strip;
break;
}
return true;
}