Fix: handle bone collections in the object join operator

Pull Request: https://projects.blender.org/blender/blender/pulls/109976
This commit is contained in:
Alexander Gavrilov
2023-08-27 11:57:22 +03:00
committed by Gitea
parent a1f081c212
commit fc8c8da885

View File

@@ -17,6 +17,7 @@
#include "BLI_blenlib.h"
#include "BLI_ghash.h"
#include "BLI_map.hh"
#include "BLI_math_matrix.h"
#include "BLI_math_vector.h"
@@ -293,6 +294,17 @@ int ED_armature_join_objects_exec(bContext *C, wmOperator *op)
* See #object_join_exec for detailed comment on why the safe version is used. */
invert_m4_m4_safe_ortho(oimat, ob_active->object_to_world);
/* Index bone collections by name. This is also used later to keep track
* of collections added from other armatures. */
blender::Map<std::string, BoneCollection *> bone_collection_by_name;
LISTBASE_FOREACH (BoneCollection *, bcoll, &arm->collections) {
bone_collection_by_name.add(bcoll->name, bcoll);
}
/* Used to track how bone collections should be remapped after merging
* other armatures. */
blender::Map<BoneCollection *, BoneCollection *> bone_collection_remap;
/* Get edit-bones of active armature to add edit-bones to */
ED_armature_to_edit(arm);
@@ -315,7 +327,27 @@ int ED_armature_join_objects_exec(bContext *C, wmOperator *op)
afd.names_map = BLI_ghash_str_new("join_armature_adt_fix");
/* Make a list of edit-bones in current armature */
ED_armature_to_edit(static_cast<bArmature *>(ob_iter->data));
ED_armature_to_edit(curarm);
/* Move new bone collections, and store their remapping info.
* TODO: armatures can potentially have multiple users, so these should
* actually be copied, not moved. However, the armature join code is
* already broken in that situation. When that gets fixed, this should
* also get fixed. Note that copying the collections should include
* copying their custom properties. (Nathan Vegdahl) */
LISTBASE_FOREACH_MUTABLE (BoneCollection *, bcoll, &curarm->collections) {
BoneCollection *mapped = bone_collection_by_name.lookup_default(bcoll->name, nullptr);
if (!mapped) {
BLI_remlink(&curarm->collections, bcoll);
BLI_addtail(&arm->collections, bcoll);
bone_collection_by_name.add(bcoll->name, bcoll);
mapped = bcoll;
}
bone_collection_remap.add(bcoll, mapped);
}
/* Get Pose of current armature */
opose = ob_iter->pose;
@@ -377,6 +409,11 @@ int ED_armature_join_objects_exec(bContext *C, wmOperator *op)
BLI_addtail(&pose->chanbase, pchan);
BKE_pose_channels_hash_free(opose);
BKE_pose_channels_hash_free(pose);
/* Remap collections. */
LISTBASE_FOREACH (BoneCollectionReference *, bcoll_ref, &curbone->bone_collections) {
bcoll_ref->bcoll = bone_collection_remap.lookup(bcoll_ref->bcoll);
}
}
/* Armature ID itself is not freed below, however it has been modified (and is now completely