Commit: 6e416b6bdf283f2337b962c05f93781eac00ff18
Author: Joshua Leung
Date:   Fri May 20 19:08:48 2016 +1200
Branches: master
https://developer.blender.org/rB6e416b6bdf283f2337b962c05f93781eac00ff18

Fix T48470: Bendy Bones: Custom Handle References not being cleared when bone 
deleted

In addition to the original bug report, I've gone through cleaning up a range of
related bugs which only became clear when hunting around the code...

* Custom Handle References weren't getting cleared when the bones they used got
  deleted.  But, neither was the custom bone shape location/transform reference.

* Various places where posebone settings are copied around were also missing 
code
  to handle the new Bendy Bone properties.

  (WHY DO WE HAVE SO MANY VARIATIONS OF COPYING POSE DATA!?!?)

* If duplicating a Bendy Bone with custom references, and the custom references
  are also selected/duplicated, the new Bendy Bones will use the corresponding
  duplicated bones

===================================================================

M       source/blender/blenkernel/intern/action.c
M       source/blender/editors/armature/armature_add.c

===================================================================

diff --git a/source/blender/blenkernel/intern/action.c 
b/source/blender/blenkernel/intern/action.c
index 3a31e4c..df9b968 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -598,7 +598,16 @@ void BKE_pose_copy_data(bPose **dst, bPose *src, const 
bool copy_constraints)
        outPose = MEM_callocN(sizeof(bPose), "pose");
        
        BLI_duplicatelist(&outPose->chanbase, &src->chanbase);
-
+       
+       /* Rebuild ghash here too, so that name lookups below won't be too 
bad...
+        * BUT this will have the penalty that the ghash will be built twice
+        * if BKE_pose_rebuild() gets called after this...
+        */
+       if (outPose->chanbase.first != outPose->chanbase.last) {
+               outPose->chanhash = NULL;
+               BKE_pose_channels_hash_make(outPose);
+       }
+       
        outPose->iksolver = src->iksolver;
        outPose->ikdata = NULL;
        outPose->ikparam = MEM_dupallocN(src->ikparam);
@@ -610,10 +619,16 @@ void BKE_pose_copy_data(bPose **dst, bPose *src, const 
bool copy_constraints)
                        id_us_plus(&pchan->custom->id);
                }
 
-               /* warning, O(n2) here, but it's a rarely used feature. */
+               /* warning, O(n2) here, if done without the hash, but these are 
rarely used features. */
                if (pchan->custom_tx) {
                        pchan->custom_tx = BKE_pose_channel_find_name(outPose, 
pchan->custom_tx->name);
                }
+               if (pchan->bbone_prev) {
+                       pchan->bbone_prev = BKE_pose_channel_find_name(outPose, 
pchan->bbone_prev->name);
+               }
+               if (pchan->bbone_next) {
+                       pchan->bbone_next = BKE_pose_channel_find_name(outPose, 
pchan->bbone_next->name);
+               }
 
                if (copy_constraints) {
                        BKE_constraints_copy(&listb, &pchan->constraints, 
true);  // BKE_constraints_copy NULLs listb
@@ -728,7 +743,7 @@ void BKE_pose_channels_remove(
         Object *ob,
         bool (*filter_fn)(const char *bone_name, void *user_data), void 
*user_data)
 {
-       /*  First erase any associated pose channel */
+       /* Erase any associated pose channel, along with any references to them 
*/
        if (ob->pose) {
                bPoseChannel *pchan, *pchan_next;
                bConstraint *con;
@@ -737,6 +752,7 @@ void BKE_pose_channels_remove(
                        pchan_next = pchan->next;
 
                        if (filter_fn(pchan->name, user_data)) {
+                               /* Bone itself is being removed */
                                BKE_pose_channel_free(pchan);
                                if (ob->pose->chanhash) {
                                        BLI_ghash_remove(ob->pose->chanhash, 
pchan->name, NULL, NULL);
@@ -744,6 +760,7 @@ void BKE_pose_channels_remove(
                                BLI_freelinkN(&ob->pose->chanbase, pchan);
                        }
                        else {
+                               /* Maybe something the bone references is being 
removed instead? */
                                for (con = pchan->constraints.first; con; con = 
con->next) {
                                        const bConstraintTypeInfo *cti = 
BKE_constraint_typeinfo_get(con);
                                        ListBase targets = {NULL, NULL};
@@ -767,6 +784,20 @@ void BKE_pose_channels_remove(
                                                        
cti->flush_constraint_targets(con, &targets, 0);
                                        }
                                }
+                               
+                               if (pchan->bbone_prev) {
+                                       if (filter_fn(pchan->bbone_prev->name, 
user_data))
+                                               pchan->bbone_prev = NULL;
+                               }
+                               if (pchan->bbone_next) {
+                                       if (filter_fn(pchan->bbone_next->name, 
user_data))
+                                               pchan->bbone_next = NULL;
+                               }
+                               
+                               if (pchan->custom_tx) {
+                                       if (filter_fn(pchan->custom_tx->name, 
user_data))
+                                               pchan->custom_tx = NULL;
+                               }
                        }
                }
        }
@@ -880,6 +911,15 @@ static void copy_pose_channel_data(bPoseChannel *pchan, 
const bPoseChannel *chan
        copy_m4_m4(pchan->pose_mat, (float(*)[4])chan->pose_mat);
        pchan->flag = chan->flag;
        
+       pchan->roll1 = chan->roll1;
+       pchan->roll2 = chan->roll2;
+       pchan->curveInX = chan->curveInX;
+       pchan->curveInY = chan->curveInY;
+       pchan->curveOutX = chan->curveOutX;
+       pchan->curveOutY = chan->curveOutY;
+       pchan->scaleIn = chan->scaleIn;
+       pchan->scaleOut = chan->scaleOut;
+       
        con = chan->constraints.first;
        for (pcon = pchan->constraints.first; pcon && con; pcon = pcon->next, 
con = con->next) {
                pcon->enforce = con->enforce;
@@ -890,7 +930,7 @@ static void copy_pose_channel_data(bPoseChannel *pchan, 
const bPoseChannel *chan
 /**
  * Copy the internal members of each pose channel including constraints
  * and ID-Props, used when duplicating bones in editmode.
- * (unlike copy_pose_channel_data which only).
+ * (unlike copy_pose_channel_data which only does posing-related stuff).
  *
  * \note use when copying bones in editmode (on returned value from 
#BKE_pose_channel_verify)
  */
@@ -913,6 +953,11 @@ void BKE_pose_channel_copy_data(bPoseChannel *pchan, const 
bPoseChannel *pchan_f
        pchan->ikstretch = pchan_from->ikstretch;
        pchan->ikrotweight = pchan_from->ikrotweight;
        pchan->iklinweight = pchan_from->iklinweight;
+       
+       /* bbone settings (typically not animated) */
+       pchan->bboneflag = pchan_from->bboneflag;
+       pchan->bbone_next = pchan_from->bbone_next;
+       pchan->bbone_prev = pchan_from->bbone_prev;
 
        /* constraints */
        BKE_constraints_copy(&pchan->constraints, &pchan_from->constraints, 
true);
@@ -1353,8 +1398,13 @@ void BKE_pose_rest(bPose *pose)
                unit_qt(pchan->quat);
                unit_axis_angle(pchan->rotAxis, &pchan->rotAngle);
                pchan->size[0] = pchan->size[1] = pchan->size[2] = 1.0f;
-
-               pchan->flag &= ~(POSE_LOC | POSE_ROT | POSE_SIZE);
+               
+               pchan->roll1 = pchan->roll2 = 0.0f;
+               pchan->curveInX = pchan->curveInY = 0.0f;
+               pchan->curveOutX = pchan->curveOutY = 0.0f;
+               pchan->scaleIn = pchan->scaleOut = 1.0f;
+               
+               pchan->flag &= ~(POSE_LOC | POSE_ROT | POSE_SIZE | 
POSE_BBONE_SHAPE);
        }
 }
 
@@ -1389,9 +1439,19 @@ bool BKE_pose_copy_result(bPose *to, bPose *from)
                        copy_v3_v3(pchanto->pose_head, pchanfrom->pose_head);
                        copy_v3_v3(pchanto->pose_tail, pchanfrom->pose_tail);
                        
+                       pchanto->roll1 = pchanfrom->roll1;
+                       pchanto->roll2 = pchanfrom->roll2;
+                       pchanto->curveInX = pchanfrom->curveInX;
+                       pchanto->curveInY = pchanfrom->curveInY;
+                       pchanto->curveOutX = pchanfrom->curveOutX;
+                       pchanto->curveOutY = pchanfrom->curveOutY;
+                       pchanto->scaleIn = pchanfrom->scaleIn;
+                       pchanto->scaleOut = pchanfrom->scaleOut;
+                       
                        pchanto->rotmode = pchanfrom->rotmode;
                        pchanto->flag = pchanfrom->flag;
                        pchanto->protectflag = pchanfrom->protectflag;
+                       pchanto->bboneflag = pchanfrom->bboneflag;
                }
        }
        return true;
diff --git a/source/blender/editors/armature/armature_add.c 
b/source/blender/editors/armature/armature_add.c
index 847b45d..559d93c 100644
--- a/source/blender/editors/armature/armature_add.c
+++ b/source/blender/editors/armature/armature_add.c
@@ -348,6 +348,12 @@ void postEditBoneDuplicate(struct ListBase *editbones, 
Object *ob)
                                        if (pchan_src->custom_tx) {
                                                pchan_dst->custom_tx = 
pchan_duplicate_map(ob->pose, name_map, pchan_src->custom_tx);
                                        }
+                                       if (pchan_src->bbone_prev) {
+                                               pchan_dst->bbone_prev = 
pchan_duplicate_map(ob->pose, name_map, pchan_src->bbone_prev);
+                                       }
+                                       if (pchan_src->bbone_next) {
+                                               pchan_dst->bbone_next = 
pchan_duplicate_map(ob->pose, name_map, pchan_src->bbone_next);
+                                       }
                                }
                        }
                }

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to