fix [#26920] working with bones causes segmetation fault.
authorCampbell Barton <ideasman42@gmail.com>
Wed, 4 May 2011 05:52:14 +0000 (05:52 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 4 May 2011 05:52:14 +0000 (05:52 +0000)
ITASC IK solver data wasn't being cleared when constraints were removed, would access freed memory and crash.

source/blender/blenkernel/intern/constraint.c
source/blender/editors/object/object_constraint.c
source/blender/makesrna/intern/rna_pose.c

index d2e48edc7ced4680606de6e37c05fea81c8a9165..d3c14a9dd12c57f3f836b4f9e94578ae98a5709d 100644 (file)
@@ -4019,7 +4019,9 @@ bConstraintTypeInfo *constraint_get_typeinfo (bConstraint *con)
  
 /* ---------- Data Management ------- */
 
-/* Free data of a specific constraint if it has any info */
+/* Free data of a specific constraint if it has any info.
+ * be sure to run BIK_clear_data() when freeing an IK constraint,
+ * unless DAG_scene_sort is called. */
 void free_constraint_data (bConstraint *con)
 {
        if (con->data) {
index b0f931fac3530d8e214c0f08fccfd478df68711c..450bd70a568f18e3644d1ea9c8720e4138421505 100644 (file)
@@ -844,7 +844,8 @@ static int constraint_delete_exec (bContext *C, wmOperator *UNUSED(op))
        Object *ob= ptr.id.data;
        bConstraint *con= ptr.data;
        ListBase *lb = get_constraint_lb(ob, con, NULL);
-       
+       const short is_ik= ELEM(con->type, CONSTRAINT_TYPE_KINEMATIC, CONSTRAINT_TYPE_SPLINEIK);
+
        /* free the constraint */
        if (remove_constraint(lb, con)) {
                /* there's no active constraint now, so make sure this is the case */
@@ -852,6 +853,11 @@ static int constraint_delete_exec (bContext *C, wmOperator *UNUSED(op))
                
                ED_object_constraint_update(ob); /* needed to set the flags on posebones correctly */
 
+               /* ITASC needs to be rebuilt once a constraint is removed [#26920] */
+               if(is_ik) {
+                       BIK_clear_data(ob->pose);
+               }
+
                /* notifiers */
                WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT|NA_REMOVED, ob);
                
@@ -993,6 +999,8 @@ static int pose_constraints_clear_exec(bContext *C, wmOperator *UNUSED(op))
        /* force depsgraph to get recalculated since relationships removed */
        DAG_scene_sort(bmain, scene);           /* sort order of objects */     
        
+       /* note, calling BIK_clear_data() isnt needed here */
+
        /* do updates */
        DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
        WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob);
@@ -1003,7 +1011,7 @@ static int pose_constraints_clear_exec(bContext *C, wmOperator *UNUSED(op))
 void POSE_OT_constraints_clear(wmOperatorType *ot)
 {
        /* identifiers */
-       ot->name = "Clear Constraints";
+       ot->name = "Clear Pose Constraints";
        ot->idname= "POSE_OT_constraints_clear";
        ot->description= "Clear all the constraints for the selected bones";
        
@@ -1038,7 +1046,7 @@ static int object_constraints_clear_exec(bContext *C, wmOperator *UNUSED(op))
 void OBJECT_OT_constraints_clear(wmOperatorType *ot)
 {
        /* identifiers */
-       ot->name = "Clear Constraints";
+       ot->name = "Clear Object Constraints";
        ot->idname= "OBJECT_OT_constraints_clear";
        ot->description= "Clear all the constraints for the active Object only";
        
index 9b8b23e3c471e210ec61ca32db232e88a7fb6a59..7c5c4882253639509597610bcc3ee11142a2e04c 100644 (file)
@@ -470,11 +470,22 @@ static void rna_PoseChannel_constraints_remove(ID *id, bPoseChannel *pchan, Repo
                BKE_reportf(reports, RPT_ERROR, "Constraint '%s' not found in pose bone '%s'.", con->name, pchan->name);
                return;
        }
+       else {
+               Object *ob= (Object *)id;
+               const short is_ik= ELEM(con->type, CONSTRAINT_TYPE_KINEMATIC, CONSTRAINT_TYPE_SPLINEIK);
+
+               remove_constraint(&pchan->constraints, con);
+
+               ED_object_constraint_update(ob);
+
+               constraints_set_active(&pchan->constraints, NULL);
 
-       // TODO
-       //ED_object_constraint_set_active(id, NULL);
-       WM_main_add_notifier(NC_OBJECT|ND_CONSTRAINT, id);
-       remove_constraint(&pchan->constraints, con);
+               if (is_ik) {
+                       BIK_clear_data(ob->pose);
+               }
+
+               WM_main_add_notifier(NC_OBJECT|ND_CONSTRAINT|NA_REMOVED, id);
+       }
 }
 
 static int rna_PoseChannel_proxy_editable(PointerRNA *ptr)