diff options
-rw-r--r-- | source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc | 6 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_convert_armature.c | 66 |
2 files changed, 52 insertions, 20 deletions
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc index 6fe9a3c2a00..d05385a7d7c 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc @@ -68,6 +68,12 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *object, bConstraint *con, RootPChanMap *root_map) { + if ((con->flag & CONSTRAINT_DISABLE) != 0) { + /* Do not add disabled IK constraints to the relations. If these needs to be temporarly + * enabled, they will be added as temporary constraints during transform. */ + return; + } + bKinematicConstraint *data = (bKinematicConstraint *)con->data; /* Attach owner to IK Solver to. */ bPoseChannel *rootchan = BKE_armature_ik_solver_find_root(pchan, data); diff --git a/source/blender/editors/transform/transform_convert_armature.c b/source/blender/editors/transform/transform_convert_armature.c index e52bd15b0d5..481198ea88c 100644 --- a/source/blender/editors/transform/transform_convert_armature.c +++ b/source/blender/editors/transform/transform_convert_armature.c @@ -58,6 +58,34 @@ typedef struct BoneInitData { float zwidth; } BoneInitData; +static void add_temporary_ik_constraint(bPoseChannel *pchan, bKinematicConstraint *targetless_con) +{ + bConstraint *con = BKE_constraint_add_for_pose( + NULL, pchan, "TempConstraint", CONSTRAINT_TYPE_KINEMATIC); + + /* for draw, but also for detecting while pose solving */ + pchan->constflag |= (PCHAN_HAS_IK | PCHAN_HAS_TARGET); + + bKinematicConstraint *temp_con_data = con->data; + + if (targetless_con) { + /* if exists, use values from last targetless (but disabled) IK-constraint as base */ + *temp_con_data = *targetless_con; + } + else { + temp_con_data->flag = CONSTRAINT_IK_TIP; + } + + temp_con_data->flag |= CONSTRAINT_IK_TEMP | CONSTRAINT_IK_AUTO | CONSTRAINT_IK_POS; +} + +static void update_deg_with_temporary_ik(Main *bmain, Object *ob) +{ + BIK_clear_data(ob->pose); + /* TODO(sergey): Consider doing partial update only. */ + DEG_relations_tag_update(bmain); +} + static void add_pose_transdata( TransInfo *t, bPoseChannel *pchan, Object *ob, TransDataContainer *tc, TransData *td) { @@ -200,8 +228,16 @@ static void add_pose_transdata( } td->loc = data->grabtarget; copy_v3_v3(td->iloc, td->loc); + data->flag |= CONSTRAINT_IK_AUTO; + /* Add a temporary auto IK constraint here, as we will only temporarly active this targetless + * bone during transform. (Targetless IK constraints are treated as if they are disabled + * unless they are transformed) */ + add_temporary_ik_constraint(pchan, data); + Main *bmain = CTX_data_main(t->context); + update_deg_with_temporary_ik(bmain, ob); + /* only object matrix correction */ copy_m3_m3(td->mtx, omat); pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON); @@ -221,7 +257,8 @@ bKinematicConstraint *has_targetless_ik(bPoseChannel *pchan) bConstraint *con = pchan->constraints.first; for (; con; con = con->next) { - if (con->type == CONSTRAINT_TYPE_KINEMATIC && (con->enforce != 0.0f)) { + if (con->type == CONSTRAINT_TYPE_KINEMATIC && (con->flag & CONSTRAINT_OFF) == 0 && + (con->enforce != 0.0f)) { bKinematicConstraint *data = con->data; if (data->tar == NULL) { @@ -278,8 +315,6 @@ static short pose_grab_with_ik_add(bPoseChannel *pchan) } } } - - return 0; } } @@ -289,20 +324,7 @@ static short pose_grab_with_ik_add(bPoseChannel *pchan) } } - con = BKE_constraint_add_for_pose(NULL, pchan, "TempConstraint", CONSTRAINT_TYPE_KINEMATIC); - - /* for draw, but also for detecting while pose solving */ - pchan->constflag |= (PCHAN_HAS_IK | PCHAN_HAS_TARGET); - - data = con->data; - if (targetless) { - /* if exists, use values from last targetless (but disabled) IK-constraint as base */ - *data = *targetless; - } - else { - data->flag = CONSTRAINT_IK_TIP; - } - data->flag |= CONSTRAINT_IK_TEMP | CONSTRAINT_IK_AUTO | CONSTRAINT_IK_POS; + add_temporary_ik_constraint(pchan, targetless); copy_v3_v3(data->grabtarget, pchan->pose_tail); /* watch-it! has to be 0 here, since we're still on the @@ -415,9 +437,7 @@ static short pose_grab_with_ik(Main *bmain, Object *ob) /* iTaSC needs clear for new IK constraints */ if (tot_ik) { - BIK_clear_data(ob->pose); - /* TODO(sergey): Consider doing partial update only. */ - DEG_relations_tag_update(bmain); + update_deg_with_temporary_ik(bmain, ob); } return (tot_ik) ? 1 : 0; @@ -585,6 +605,12 @@ void pose_transform_mirror_update(TransInfo *t, TransDataContainer *tc, Object * /* TODO(germano): Realitve Mirror support */ } data->flag |= CONSTRAINT_IK_AUTO; + /* Add a temporary auto IK constraint here, as we will only temporarly active this targetless + * bone during transform. (Targetless IK constraints are treated as if they are disabled + * unless they are transformed) */ + add_temporary_ik_constraint(pchan, data); + Main *bmain = CTX_data_main(t->context); + update_deg_with_temporary_ik(bmain, ob); } if (pid) { |