Fix #135122: Crash when using pose assets created without slots.

The issue was that the versioning code didn't run when loading the action.
Thus it had no slots and so was crashing trying to get the first slot.

This PR fixes that in 2 ways:
* Check the slot count of the loaded action, and return/notify the user
* Actually make sure the actions are versioned

Point 1 is important anyway because actions can have no slots (though unlikely).
Point 2 ensures that old pose assets can actually be used

Pull Request: https://projects.blender.org/blender/blender/pulls/135232
This commit is contained in:
Christoph Lendenfeld
2025-03-04 10:56:23 +01:00
committed by Christoph Lendenfeld
parent 5cd758368a
commit 39fdbded9a
4 changed files with 17 additions and 23 deletions

View File

@@ -172,6 +172,10 @@ void BKE_pose_backup_restore(const PoseBackup *pbd)
void BKE_pose_backup_free(PoseBackup *pbd)
{
if (!pbd) {
/* Can happen if initialization was aborted. */
return;
}
LISTBASE_FOREACH_MUTABLE (PoseChannelBackup *, chan_bak, &pbd->backups) {
if (chan_bak->oldprops) {
IDP_FreeProperty(chan_bak->oldprops);

View File

@@ -461,14 +461,9 @@ void BLO_library_link_end(Main *mainl, BlendHandle **bh, const LibraryLink_Param
* Struct for temporarily loading datablocks from a blend file.
*/
struct TempLibraryContext {
/** Temporary main used for library data. */
Main *bmain_lib;
/** Temporary main used to load data into (currently initialized from `real_main`). */
Main *bmain_base;
BlendHandle *blendhandle;
BlendFileReadReport bf_reports;
LibraryLink_Params liblink_params;
Library *lib;
/** The ID datablock that was loaded. Is NULL if loading failed. */
ID *temp_id;

View File

@@ -29,33 +29,24 @@ TempLibraryContext *BLO_library_temp_load_id(Main *real_main,
/* Copy the file path so any path remapping is performed properly. */
STRNCPY(temp_lib_ctx->bmain_base->filepath, real_main->filepath);
temp_lib_ctx->blendhandle = BLO_blendhandle_from_file(blend_file_path,
&temp_lib_ctx->bf_reports);
BlendHandle *blendhandle = BLO_blendhandle_from_file(blend_file_path, &temp_lib_ctx->bf_reports);
BLO_library_link_params_init(
&temp_lib_ctx->liblink_params, temp_lib_ctx->bmain_base, 0, ID_TAG_TEMP_MAIN);
LibraryLink_Params lib_link_params;
BLO_library_link_params_init(&lib_link_params, temp_lib_ctx->bmain_base, 0, ID_TAG_TEMP_MAIN);
temp_lib_ctx->bmain_lib = BLO_library_link_begin(
&temp_lib_ctx->blendhandle, blend_file_path, &temp_lib_ctx->liblink_params);
Main *bmain_lib = BLO_library_link_begin(&blendhandle, blend_file_path, &lib_link_params);
temp_lib_ctx->temp_id = BLO_library_link_named_part(temp_lib_ctx->bmain_lib,
&temp_lib_ctx->blendhandle,
idcode,
idname,
&temp_lib_ctx->liblink_params);
temp_lib_ctx->temp_id = BLO_library_link_named_part(
bmain_lib, &blendhandle, idcode, idname, &lib_link_params);
BLO_library_link_end(bmain_lib, &blendhandle, &lib_link_params);
BLO_blendhandle_close(blendhandle);
return temp_lib_ctx;
}
void BLO_library_temp_free(TempLibraryContext *temp_lib_ctx)
{
/* This moves the temporary ID and any indirectly loaded data into `bmain_base`
* only to free `bmain_base`, while redundant this is the typical code-path for library linking,
* it's more convenient to follow this convention rather than create a new code-path for this
* one-off use case. */
BLO_library_link_end(
temp_lib_ctx->bmain_lib, &temp_lib_ctx->blendhandle, &temp_lib_ctx->liblink_params);
BLO_blendhandle_close(temp_lib_ctx->blendhandle);
BKE_main_free(temp_lib_ctx->bmain_base);
MEM_freeN(temp_lib_ctx);
}

View File

@@ -368,6 +368,10 @@ static bool poselib_blend_init_data(bContext *C, wmOperator *op, const wmEvent *
if (pbd->act == nullptr) {
return false;
}
if (pbd->act->wrap().slots().size() == 0) {
BKE_report(op->reports, RPT_ERROR, "This pose asset is empty, and thus has no pose");
return false;
}
pbd->is_flipped = RNA_boolean_get(op->ptr, "flipped");
pbd->blend_factor = RNA_float_get(op->ptr, "blend_factor");