diff options
author | Campbell Barton <ideasman42@gmail.com> | 2011-05-04 09:52:14 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2011-05-04 09:52:14 +0400 |
commit | ea5b43d862a4004280660405d50560d576f6fed9 (patch) | |
tree | 00c3419ef8a7f3af173b18ce5a4729fb3693e910 /source | |
parent | b5c2598a6b31f63ee6d52c61d6ab5195a576ec56 (diff) |
fix [#26920] working with bones causes segmetation fault.
ITASC IK solver data wasn't being cleared when constraints were removed, would access freed memory and crash.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/intern/constraint.c | 4 | ||||
-rw-r--r-- | source/blender/editors/object/object_constraint.c | 14 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_pose.c | 19 |
3 files changed, 29 insertions, 8 deletions
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index d2e48edc7ce..d3c14a9dd12 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -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) { diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index b0f931fac35..450bd70a568 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -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"; diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index 9b8b23e3c47..7c5c4882253 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -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) |