Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2017-07-05 18:52:42 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2017-07-06 13:15:30 +0300
commita7a5c20fbc8de036992e50f6e399fa041dab7328 (patch)
treee24a49340e66b2bc783ea259365c4a1ce3f1b89f /source/blender/editors/transform/transform_conversions.c
parentbdd814d87da3374c008cb3a7f808d8c51cf00707 (diff)
Fix T51955: Changing Auto-IK length crashes Blender (with new-depsgraph)
New dependency graph is tacking root bone into account when building the graph. This is required in order to get proper dependencies between bones. so we can reliably use bones as targets from the same rig (and even indirect relations via external objects). This forces us to tag relations for update when we change root IK chain bone. Since relations rebuild is not fully trivial operation, we only do it for the new dependency graph. In the future it'll be nice to avoid whole graph rebuild for such cases, but that's mentioned as a TODO.
Diffstat (limited to 'source/blender/editors/transform/transform_conversions.c')
-rw-r--r--source/blender/editors/transform/transform_conversions.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 1eb9b3caa3e..b7a42121e92 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -771,34 +771,43 @@ int count_set_pose_transflags(int *out_mode, short around, Object *ob)
/* -------- Auto-IK ---------- */
/* adjust pose-channel's auto-ik chainlen */
-static void pchan_autoik_adjust(bPoseChannel *pchan, short chainlen)
+static bool pchan_autoik_adjust(bPoseChannel *pchan, short chainlen)
{
bConstraint *con;
+ bool changed = false;
/* don't bother to search if no valid constraints */
- if ((pchan->constflag & (PCHAN_HAS_IK | PCHAN_HAS_TARGET)) == 0)
- return;
+ if ((pchan->constflag & (PCHAN_HAS_IK | PCHAN_HAS_TARGET)) == 0) {
+ return changed;
+ }
/* check if pchan has ik-constraint */
for (con = pchan->constraints.first; con; con = con->next) {
if (con->type == CONSTRAINT_TYPE_KINEMATIC && (con->enforce != 0.0f)) {
bKinematicConstraint *data = con->data;
-
+
/* only accept if a temporary one (for auto-ik) */
if (data->flag & CONSTRAINT_IK_TEMP) {
/* chainlen is new chainlen, but is limited by maximum chainlen */
- if ((chainlen == 0) || (chainlen > data->max_rootbone))
+ const int old_rootbone = data->rootbone;
+ if ((chainlen == 0) || (chainlen > data->max_rootbone)) {
data->rootbone = data->max_rootbone;
- else
+ }
+ else {
data->rootbone = chainlen;
+ }
+ changed |= (data->rootbone != old_rootbone);
}
}
}
+
+ return changed;
}
/* change the chain-length of auto-ik */
void transform_autoik_update(TransInfo *t, short mode)
{
+ const short old_len = t->settings->autoik_chainlen;
short *chainlen = &t->settings->autoik_chainlen;
bPoseChannel *pchan;
@@ -812,13 +821,29 @@ void transform_autoik_update(TransInfo *t, short mode)
if (*chainlen > 0) (*chainlen)--;
}
+ /* IK length did not change, skip any updates. */
+ if (old_len == *chainlen) {
+ return;
+ }
+
/* sanity checks (don't assume t->poseobj is set, or that it is an armature) */
if (ELEM(NULL, t->poseobj, t->poseobj->pose))
return;
/* apply to all pose-channels */
+ bool changed = false;
for (pchan = t->poseobj->pose->chanbase.first; pchan; pchan = pchan->next) {
- pchan_autoik_adjust(pchan, *chainlen);
+ changed |= pchan_autoik_adjust(pchan, *chainlen);
+ }
+
+#ifdef WITH_LEGACY_DEPSGRAPH
+ if (!DEG_depsgraph_use_legacy())
+#endif
+ {
+ if (changed) {
+ /* TODO(sergey): Consider doing partial update only. */
+ DAG_relations_tag_update(G.main);
+ }
}
}