Rigify FK to IK is broken (2.78 Pitchipoy and 2.79)
Closed, ResolvedPublic

Description

System Information
Win 8.1 64bit GTX 750M

Blender Version
Broken: 2.78.4 and 2.79
Worked: ---

Short description of error
Going from IK to FK results in some jumping for the bones even when using Snap FK to IK

Exact steps for others to reproduce the error
1.create metarig, generate
2.in IK mode grab right hand move it and rotate it (make sure you affect all axis and the change is pretty large)
3.then Snap FK to IK
4.then change the FK/IK slider to FK (1.0)
5.you will see the hand jiggles a bit

Note: going from IK to FK also results in some bone jiggling.

Rigify works without problem however in 2.78 (none of the above issues)

Thanks

Details

Type
Bug
Maverick (maverick) changed the title from "Pithcipoy FK to IK is broken" to "Pithcipoy FK to IK is broken (2.78 and 2.79 legacy mode)".Jun 29 2017, 9:31 AM
Maverick (maverick) edited the task description. (Show Details)
Maverick (maverick) changed the title from "Pithcipoy FK to IK is broken (2.78 and 2.79 legacy mode)" to "Pithcipoy FK to IK is broken (2.78 and 2.79)".Jun 29 2017, 3:33 PM
Maverick (maverick) edited the task description. (Show Details)

The bug affects 2.79 as well.
It seem the issue came along with Pitchipoy integration.

It appears to be a floating point error due to some successive operations.
At this point the only working rigs are the 2.78 metarig and 2.79 legacy (so basically the ones not influenced from Pitchipoy)

2.78 Rigify - works
2.78 Pitchipoy - BROKEN

2.79 Rigify (Legacy mode) - works
2.79 Rigify (Legacy mode Pitchipoy) - BROKEN
2.79 Rigify - BROKEN

Maverick (maverick) changed the title from "Pithcipoy FK to IK is broken (2.78 and 2.79)" to "Rigify FK to IK is broken (2.78 Pitchipoy and 2.79)".Jun 29 2017, 3:39 PM

I can confirm the issue. Causes are still unclear. We are investigating right now.

Ivan Cappiello (icappiello) raised the priority of this task from "Normal" to "High".Jun 30 2017, 11:28 AM

After a first look it seems something has changed in the way blender handles the snapping functions.

Rigs generated and correctly working in 2.77 are affected by this issue when loaded in blender 2.78.

The snapping functions are written by rigify itself in the rig_ui.py during the generate function and stored there when the rig is saved. When opening a rig file blender reads the snapping functions from there and draw them in the UI. At this stage is clear that the snapping function are the same, the rig structure is the same, but blender handles it in a different way in 2.78.
What's still unclear is which part of blender code is changed and interfering with the snapping code . @Francesco Siddi (fsiddi), @Campbell Barton (campbellbarton) If any blender dev can help us narrowing down the search, the fix will be easier and faster.
In the while we are looking in the code to see if - in a reasonable time frame - we can completely rewrite the snapping functions since right now many sub functions are inherited from really old rigify code and it's not clear who wrote them.

Could someone post a very simple example of a blend file that fails, with steps to redo?

Note: possibly rBe4e21480d6331903c90ab073746484498441e1ac changes behavior since values outside the hard-range are no longer clamped. Posting this just in case its the cause.

Maverick (maverick) added a comment.EditedJun 30 2017, 12:56 PM

With "hand_IK.R" selected change the IK/FK slider from 0 to 1 and back to notice the jiggling

(using 2.78.4 on win64)

This is an example blend. Try to snap FK/IK and then slide IK_FK slider to 1. You'll notice a flicker on hand_fk

Do both the files above work in 2.77 or an older Blender?

Update:

  • moving Rigify folder from 2.78 to blender 2.77 and starting/generating a rig in 2.77 works
  • however opening a .blend/rig from 2.78 with this modified 2.77 is still broken

@Maverick (maverick) I don't agree with the last statement
Follow these steps to clarify:

  • Download blender 2.77 and 2.78
  • Copy/paste Rgify folder from 2.78 to 2.77
  • Make a Pitchipoy Metarig in 2.78, generate it, save the rest pose. Move one ik arm, hit snap Fk/Ik and notice the flicker moving the IK_FK slider.
  • Now open 2.77 "modified". load the same rig with same rig_ui
  • Try the snap and the slider again: NO flickering occurs

Other things I tried:
As you know rig_ui.py is runtime generated, to debug its code I moved it in utils.py.
I debugged it, namely the set_pose_rotation and get_pose_matrix_in_other_space functions that seem affected by the issue.
I checked the generated matrices both in 2.78 and the mod 2.77. The matrix of hand_fk.parent (forearm_fk FYI) is returned differently between the two versions.
This can be related to errors accumulating from the beginning of the chain though, since the first bone to be repositioned is upper_arm_fk then forearm_fk and then hand_fk so I'm still investigating.

Ok, I'm narrowing down the issue step by step:

open the attached file with 2.78 and 2.77 (modified with 2.78 rigify). You'll notice a scale difference between the upper_arm_ik bones.

I want to underline that, at this stage NO snapping was applied. It is just a stretched arm

The problems, I guess, start from this point because the first matrix retrieved is from bone upper_arm_ik and it is used to calculate all the matrices of the FK chain starting from the first bone (upper_arm_fk)

I did also some logging of the matrices while applying the SNAP FK/IK operator. You will notice in the files that the starting matrix "mat" is different between the two versions (that's [upper_arm_ik].matrix)
these are the matices calculations performed in get_pose_matrix_in_other_space function, starting from the first bone of the chain upper_arm_fk for trans-rot-scale and then for all the others down the fk chain

this is the situation in 2.78

this is the situation in 2.77

It is possible that those two versions of blender evaluate the ik stretch in different ways, here is a basic IK setup behaving differently between 2.77 and 2.78

2.78 scales only on the Y axis, which might even be more correct by the way.

If the IK solver has been changed we will have to change something in the switch function as well. It would be interesting to know if the IK behaviour has really been changed this drastically

So, the non uniform scale set by the new solver is skewing the space where the child bone rotation happens. Apparently, it is not possible to set the bone matrices to irregular spaces: not only the fk2ik switch, but also the copy attribute addon and the visual transform to pose button will fail at setting the pose given by the ik constraint.

One possible way out at the moment is to snap the fk chain with a uniform scale, a very simple example

import bpy
from mathutils import Vector, Matrix


ctx = bpy.context
rig = bpy.data.objects['rig']

ik_chain = (rig.pose.bones["upper_arm_ik.L"],
            rig.pose.bones["MCH-upper_arm_ik.L"],
            rig.pose.bones["hand_ik.L"])

fk_chain = (rig.pose.bones["upper_arm_fk.L"],
            rig.pose.bones["forearm_fk.L"],
            rig.pose.bones["hand_fk.L"])


for ik_bone, fk_bone in zip(ik_chain, fk_chain):
    # match rotation
    ctx.scene.update()
    norm_mat = ik_bone.matrix.normalized()
    fk_bone.matrix = norm_mat
    
    # match length (uniform scale)
    ctx.scene.update()
    scale_fac = ik_bone.length / fk_bone.length

    for i in range(3):
        fk_bone.scale[i] *= scale_fac

This way the fk chain will have a different scale, but the correct length and rotation. Since we are not using the chains for the thickness (we use the tweak control for that) the difference in scale is not a problem, even if it is suboptimal

Bisected from 2.77 to 2.78 using Rigify folder from 2.78.

Commit a92fc348f46755c34023eff4fc1d7f467241c616 is at fault.

"Fix/Workaround non-uniform scaled bones failing w/ IK solver

Scaling a bone on the Y axis (for a stretch effect), wasn't supported by the IK solver.

Support this by solving as uniform scaled bones by matching the X,Z axis to the Y."

@Campbell Barton (campbellbarton) is there a reason why non-uniform scale cannot be made an option of the solver? I can see the benefit of it, but having a way to revert to the old costume would help a lot here

Reverting a92fc348f46755c34023eff4fc1d7f467241c616 does not fix rigs already generated by 2.78 using new Rigify (non legacy)

Of course not, we need a script that fixes rig_ui at least. Functions and operators definitions should be moved out of this runtime generated file as well.

@Maverick (maverick) no need to revert: you can comment the line #define USE_NONUNIFORM_SCALE inside file iksolver_plugin.c and revert to the old behaviour. Rigs generated in 2.78 work as well in my tests when non uniform scale is disabled. They should also work in 2.78 if you change the IK solver to itasc, which keeps the scale uniform.

This is not limited to rigify anymore: native operators like apply visual transform to pose or any addon using matrix assignment like copy attribute will not work correctly in blender 2.78 when the IK solver is involved

The next steps depend on how the issues related to non uniform IK are tackled by the BF, so we have to wait for Campbell's reply. I can see three possible outcomes:

  1. bones will accept the assignment of non uniform matrices: we won't have to do anything, the script should work as it is
  2. non uniform scale becomes optional: we use a different formula when enabled, match rotations than length
  3. everything stays as it is: we use a different formula when version > 2.77

I haven't looked in the matrix assignment so I don't know how the supplied matrix is checked and why a non uniform transformation won't make it through. The ik solver code is kind of nice, so it should be no problem to make the uniform scale optional, after all it is optional if you are keen to build blender, but iterative constraints can hide all kind of pitfalls so I might be overlooking something.

hi, can we test this is fixed by D2743
thanks

It is, IK behaviour is back to uniform scale. A quick test confirmed it is fixed, marked as resolved. Please reopen if still buggy

Paolo Acampora (pkrime) closed this task as "Resolved".Jul 18 2017, 9:45 AM
Paolo Acampora (pkrime) claimed this task.