Fix #147978: Missed conversion to SystemProperties for children bones.

Forgot that the Armature's bones list only contain root bones...

Fix the versioning code.

Also adding a 'recovery' extra versioning step for files that may have
already been opened and re-saved in Blender 5.0 (though this step is
not 100% handling all cases, in case some script or add-on already
created some system properties in a bone in 5.0, the existing user
properties from 4.5 and before won't be copied over anymore).

Pull Request: https://projects.blender.org/blender/blender/pulls/148125
This commit is contained in:
Bastien Montagne
2025-10-15 15:09:30 +02:00
committed by Bastien Montagne
parent bbf40d214c
commit 40e61d4240
4 changed files with 39 additions and 2 deletions

View File

@@ -27,7 +27,7 @@
/* Blender file format version. */ /* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION #define BLENDER_FILE_VERSION BLENDER_VERSION
#define BLENDER_FILE_SUBVERSION 109 #define BLENDER_FILE_SUBVERSION 110
/* Minimum Blender version that supports reading file written with the current /* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and cancel loading the file, showing a warning to * version. Older Blender versions will test this and cancel loading the file, showing a warning to

View File

@@ -3501,6 +3501,11 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
* later during 5.0 development process. */ * later during 5.0 development process. */
version_system_idprops_nodes_generate(main); version_system_idprops_nodes_generate(main);
} }
if (!MAIN_VERSION_FILE_ATLEAST(main, 500, 110)) {
/* Same as above, but children bones were missed by initial versioning code, attempt to
* transfer idprops data still in case they have no system properties defined yet. */
version_system_idprops_children_bones_generate(main);
}
if (G.debug & G_DEBUG) { if (G.debug & G_DEBUG) {
char build_commit_datetime[32]; char build_commit_datetime[32];

View File

@@ -130,8 +130,16 @@ void version_system_idprops_generate(Main *bmain)
for (BoneCollection *bcoll : armature->collections_span()) { for (BoneCollection *bcoll : armature->collections_span()) {
idprops_process(bcoll->prop, &bcoll->system_properties); idprops_process(bcoll->prop, &bcoll->system_properties);
} }
LISTBASE_FOREACH (Bone *, bone, &armature->bonebase) { /* There is no way to iterate directly over all bones of an armature currently, use a recursive
* approach instead. */
auto process_bone_recursive = [](const auto &process_bone_recursive, Bone *bone) -> void {
idprops_process(bone->prop, &bone->system_properties); idprops_process(bone->prop, &bone->system_properties);
LISTBASE_FOREACH (Bone *, bone_it, &bone->childbase) {
process_bone_recursive(process_bone_recursive, bone_it);
}
};
LISTBASE_FOREACH (Bone *, bone_it, &armature->bonebase) {
process_bone_recursive(process_bone_recursive, bone_it);
} }
} }
} }
@@ -145,6 +153,29 @@ void version_system_idprops_nodes_generate(Main *bmain)
} }
FOREACH_NODETREE_END; FOREACH_NODETREE_END;
} }
/* Separate callback for non-root bones, because they were missed in the initial implementation. */
void version_system_idprops_children_bones_generate(Main *bmain)
{
LISTBASE_FOREACH (bArmature *, armature, &bmain->armatures) {
/* There is no way to iterate directly over all bones of an armature currently, use a recursive
* approach instead. */
auto process_bone_recursive = [](const auto &process_bone_recursive, Bone *bone) -> void {
/* Do not overwrite children bones' system properties if they were already defined by some
* scripts or add-on e.g. */
if (bone->system_properties == nullptr) {
idprops_process(bone->prop, &bone->system_properties);
}
LISTBASE_FOREACH (Bone *, bone_it, &bone->childbase) {
process_bone_recursive(process_bone_recursive, bone_it);
}
};
LISTBASE_FOREACH (Bone *, bone_it, &armature->bonebase) {
LISTBASE_FOREACH (Bone *, bone_child_it, &bone_it->childbase) {
process_bone_recursive(process_bone_recursive, bone_child_it);
}
}
}
}
static CustomDataLayer *find_old_seam_layer(CustomData &custom_data, const blender::StringRef name) static CustomDataLayer *find_old_seam_layer(CustomData &custom_data, const blender::StringRef name)
{ {

View File

@@ -218,6 +218,7 @@ bNode *version_eevee_output_node_get(bNodeTree *ntree, int16_t node_type);
*/ */
void version_system_idprops_generate(Main *bmain); void version_system_idprops_generate(Main *bmain);
void version_system_idprops_nodes_generate(Main *bmain); void version_system_idprops_nodes_generate(Main *bmain);
void version_system_idprops_children_bones_generate(Main *bmain);
bool all_scenes_use(Main *bmain, const blender::Span<const char *> engines); bool all_scenes_use(Main *bmain, const blender::Span<const char *> engines);