Setting an overlapping IK constraint to zero influence/disabled gives weird behavior #88752

Closed
opened 2021-06-02 20:07:55 +02:00 by Kinouti Takahiro · 16 comments

System Information
Operating system: Windows-10-10.0.19041-SP0 64 Bits
Graphics card: Radeon(TM) RX 460 Graphics ATI Technologies Inc. 4.5.13596 Core Profile Context 20.10.35.02 27.20.1034.6

Blender Version
Broken: version: 2.93.0, branch: master, commit date: 2021-06-01 14:46, hash: 383bc8d9bc
Worked: (the newest version of Blender that worked as expected)

Short description of error
Zero influence IK gives wired behavior when other IK moved the bone.

Exact steps for others to reproduce the error
I have elbow IK and arm IK. Moving elbow IK gives wired behavior when the influence of arm IK is zero. Follow is a movie.
ik_bug.gif

A file is here.
rig_elbow_ik.blend

**System Information** Operating system: Windows-10-10.0.19041-SP0 64 Bits Graphics card: Radeon(TM) RX 460 Graphics ATI Technologies Inc. 4.5.13596 Core Profile Context 20.10.35.02 27.20.1034.6 **Blender Version** Broken: version: 2.93.0, branch: master, commit date: 2021-06-01 14:46, hash: `383bc8d9bc` Worked: (the newest version of Blender that worked as expected) **Short description of error** Zero influence IK gives wired behavior when other IK moved the bone. **Exact steps for others to reproduce the error** I have elbow IK and arm IK. Moving elbow IK gives wired behavior when the influence of arm IK is zero. Follow is a movie. ![ik_bug.gif](https://archive.blender.org/developer/F10154597/ik_bug.gif) A file is here. [rig_elbow_ik.blend](https://archive.blender.org/developer/F10154596/rig_elbow_ik.blend)

Added subscriber: @dskjal-1

Added subscriber: @dskjal-1
Member

Added subscriber: @OmarEmaraDev

Added subscriber: @OmarEmaraDev
Member

Changed status from 'Needs Triage' to: 'Confirmed'

Changed status from 'Needs Triage' to: 'Confirmed'
Member

One would expect a constrain with zero influence to be equivalent to no constraint, yet this is not the case.

One would expect a constrain with zero influence to be equivalent to no constraint, yet this is not the case.
Philipp Oeser removed the
Interest
Animation & Rigging
label 2023-02-09 14:35:35 +01:00
Nathan Vegdahl added
Type
Bug
and removed
Type
Report
labels 2023-06-09 12:22:50 +02:00
Member

Confirmed that this is still an issue on latest main (884b1e8cc3). This definitely looks like a bug to me.

It's also interesting that if instead of setting the influence to zero, you just set it to something really small (e.g. 0.000000001) it gives the expected behavior. So that's a workaround for now, at least.

EDIT: also, the same buggy behavior happens when simply disabling the constraint as well.

Confirmed that this is still an issue on latest main (884b1e8cc3b3899cddbf944f34ce6a95300e6a7c). This definitely looks like a bug to me. It's also interesting that if instead of setting the influence to zero, you just set it to something *really* small (e.g. 0.000000001) it gives the expected behavior. So that's a workaround for now, at least. EDIT: also, the same buggy behavior happens when simply disabling the constraint as well.
Nathan Vegdahl self-assigned this 2023-06-13 10:40:37 +02:00
Member

Upon further investigating, for this bug to trigger you have to have bones that are directly affected by more than one IK constraint. For example, if you have the bone chain A -> B -> C, with IK constraints on B and C, the constraint on C would need to have a chain length of at least 2, so that both it and the IK constraint on B affect B.

This situation is also easy to run into with a tree of bones with multiple IK targets. E.g. if you have:

   /-> B
A -
   \-> C

And have IK constraints on both B and C with chain length >= 2, so they both affect A.

Upon further investigating, for this bug to trigger you have to have bones that are directly affected by more than one IK constraint. For example, if you have the bone chain `A -> B -> C`, with IK constraints on B and C, the constraint on C would need to have a chain length of at least 2, so that both it and the IK constraint on B affect B. This situation is also easy to run into with a tree of bones with multiple IK targets. E.g. if you have: ``` /-> B A - \-> C ``` And have IK constraints on both B and C with chain length >= 2, so they both affect A.
Member

I went through and tested old Blender versions from here:

https://download.blender.org/release/

The bug was introduced some time between version 2.79 and 2.81. 2.79 has the correct behavior, and 2.81 has the buggy behavior.

(The 2.80 binary refuses to run on my workstation for some reason, and compiling it isn't straightforward due to needing old library versions, so I couldn't verify what behavior it has).

I went through and tested old Blender versions from here: https://download.blender.org/release/ The bug was introduced some time between version 2.79 and 2.81. 2.79 has the correct behavior, and 2.81 has the buggy behavior. (The 2.80 binary refuses to run on my workstation for some reason, and compiling it isn't straightforward due to needing old library versions, so I couldn't verify what behavior it has).
Nathan Vegdahl changed title from Zero influence IK gives wired behavior when other IK moved the bone to Setting an overlapping IK constraint to zero influence/disabled gives weird behavior 2023-06-16 11:14:51 +02:00
Member

Just a quick note: I also stumbled across #100594, which from the title sounds like a duplicate. But in fact, these are two different issues and are only superficially similar. #100594 is a dependency cycle issue, whereas this appears to be an IK solver issue or something along those lines.

Just a quick note: I also stumbled across #100594, which from the title *sounds* like a duplicate. But in fact, these are two different issues and are only superficially similar. #100594 is a dependency cycle issue, whereas this appears to be an IK solver issue or something along those lines.
Nathan Vegdahl removed their assignment 2023-07-04 14:40:55 +02:00
Member

At this point I'm just spinning my wheels, and I think that's at least partly because I'm just not familiar enough with the IK code. So I'm unassigning myself.

@brecht Could you take a look at this when you get the chance? It's kind of a corner case, so not high priority.

Some notes that might help narrow things down:

  • Completely deleting the constraint doesn't, of course, trigger the bug. Whereas setting it to zero influence or disabling does. So it's probably related to something erroneously treating the bone like it does have an IK constraint when it shouldn't.
  • One of the places I looked was initialize_posetree() in iksolver_plugin.c. However, both looking at the code and stepping through with a debugger, it appears to correctly omit bones with zero-influence/disabled constraints. Additionally, and to me counterintuitively, altering the code so that it doesn't omit zero-influence (but enabled) constraints actually makes things behave correctly for those bones.
  • Another place I looked was iksolver_execute_tree(), also in iksolver_plugin.c. Based on stepping through with a debugger, it also appears to properly omit bones with zero-influence/disabled constraints. Which makes sense because they weren't added to the tree in initialize_posetree(). So it doesn't seem like the bug is there, at least.

Of course, I'm obviously missing something, so take all that with a grain of salt.

At this point I'm just spinning my wheels, and I think that's at least partly because I'm just not familiar enough with the IK code. So I'm unassigning myself. @brecht Could you take a look at this when you get the chance? It's kind of a corner case, so not high priority. Some notes that might help narrow things down: - Completely deleting the constraint doesn't, of course, trigger the bug. Whereas setting it to zero influence or disabling does. So it's *probably* related to something erroneously treating the bone like it does have an IK constraint when it shouldn't. - One of the places I looked was `initialize_posetree()` in `iksolver_plugin.c`. However, both looking at the code and stepping through with a debugger, it appears to correctly omit bones with zero-influence/disabled constraints. Additionally, and to me counterintuitively, altering the code so that it *doesn't* omit zero-influence (but enabled) constraints actually makes things behave correctly for those bones. - Another place I looked was `iksolver_execute_tree()`, also in `iksolver_plugin.c`. Based on stepping through with a debugger, it also appears to properly omit bones with zero-influence/disabled constraints. Which makes sense because they weren't added to the tree in `initialize_posetree()`. So it doesn't *seem* like the bug is there, at least. Of course, I'm obviously missing something, so take all that with a grain of salt.

Note the same issue happens when disabling the constraint and setting influence to 1.0.

I think the issue is the following. The depsgraph relations are built assuming all IK constraints are enabled, so that both enabled and influence properties can be animated and driven. When the constraint gets disabled at runtime, for some bones BKE_pose_where_is_bone is not called in time for other bones to read the resulting values.

I've attached a patch that solves this bug, but also changes behavior. Currently disabling and setting influence to zero changes the IK tree topology. So with this change, if you have an IK tree with multiple targets and disable the constraint for one of the targets, it will still solve for all targets but then only apply the result to one enabled branch of the tree.

For influence this seems desirable to have continuity between 0 and 0.001. For disabling the constraint it's less clear. Not sure if animators or riggers have an opinion on this.

If this change in behavior is undesirable, I guess we can store a list of bones in the IK tree that do not need IK solving but still need to get BKE_pose_where_is_bone called.

Note the same issue happens when disabling the constraint and setting influence to 1.0. I think the issue is the following. The depsgraph relations are built assuming all IK constraints are enabled, so that both enabled and influence properties can be animated and driven. When the constraint gets disabled at runtime, for some bones `BKE_pose_where_is_bone` is not called in time for other bones to read the resulting values. I've attached a patch that solves this bug, but also changes behavior. Currently disabling and setting influence to zero changes the IK tree topology. So with this change, if you have an IK tree with multiple targets and disable the constraint for one of the targets, it will still solve for all targets but then only apply the result to one enabled branch of the tree. For influence this seems desirable to have continuity between 0 and 0.001. For disabling the constraint it's less clear. Not sure if animators or riggers have an opinion on this. If this change in behavior is undesirable, I guess we can store a list of bones in the IK tree that do not need IK solving but still need to get `BKE_pose_where_is_bone` called.
Member

Thanks @brecht! That's super helpful. I'll look into what the most appropriate solution is.

Thanks @brecht! That's super helpful. I'll look into what the most appropriate solution is.
Nathan Vegdahl self-assigned this 2023-07-10 11:42:55 +02:00
Member

(Updated patch after the recent conversion to C++: zero_influence_ik_fix.patch)

So, the ideal behavior would be for all of the following things to have identical (user-facing) behavior:

  1. Setting the IK constraint to have zero influence.
  2. Disabling the IK constraint.
  3. Removing the IK constraint.

Additionally, we want the influence slider to blend poses smoothly between 0.0 and 1.0 influence.

With @brecht's fix we achieve all of these for most IK setups, including the rig_elbow_ik.blend test file provided in the report. And we achieve all except for item 3 for all IK setups.

The exception for item 3 is a tree IK setup. For example, in ik_tree.blend, setting the left IK constraint to 0.0 influence or disabling it have the same behavior as each other, but significantly different behavior than removing the constraint entirely. Specifically, zero-influence and disabled still behave like there's a kind of "virtual" IK target, which is bizarre.

However, that bizarre behavior was already the case with influence set extremely low (e.g. 0.000001) even before the current bug was introduced. And this fix at least keeps behavior consistent between nearly zero influence and actual zero influence/disabled, which seems desirable.

With that in mind, I think @brecht's fix is the one to move forward with. And in the future we can look into making zero-influence/disabled IK constraints fully consistent with removing the constraint, while still preserving a smooth transition when changing the influence.

I'll prepare a PR with @brecht's fix.

(Updated patch after the recent conversion to C++: [zero_influence_ik_fix.patch](/attachments/76a5bf27-d60d-4e08-bc8d-3929e9e596f3)) So, the ideal behavior would be for all of the following things to have identical (user-facing) behavior: 1. Setting the IK constraint to have zero influence. 2. Disabling the IK constraint. 3. Removing the IK constraint. Additionally, we want the influence slider to blend poses smoothly between 0.0 and 1.0 influence. With @brecht's fix we achieve all of these for most IK setups, including the `rig_elbow_ik.blend` test file provided in the report. And we achieve all except for item 3 for *all* IK setups. The exception for item 3 is a tree IK setup. For example, in [ik_tree.blend](/attachments/3947744b-7cd0-4502-b016-932f8da7d01e), setting the left IK constraint to 0.0 influence or disabling it have the same behavior as each other, but significantly different behavior than removing the constraint entirely. Specifically, zero-influence and disabled still behave like there's a kind of "virtual" IK target, which is bizarre. However, that bizarre behavior was already the case with influence set extremely low (e.g. 0.000001) even before the current bug was introduced. And this fix at least keeps behavior consistent between nearly zero influence and actual zero influence/disabled, which seems desirable. With that in mind, I think @brecht's fix is the one to move forward with. And in the future we can look into making zero-influence/disabled IK constraints fully consistent with removing the constraint, while still preserving a smooth transition when changing the influence. I'll prepare a PR with @brecht's fix.

Personally I think it may be better to have different behavior between those cases, even in the ideal case. It's not obvious to me that there exists a sensible way of telling the IK solver to partially reach a target.

Personally I think it may be better to have different behavior between those cases, even in the ideal case. It's not obvious to me that there exists a sensible way of telling the IK solver to partially reach a target.
Blender Bot added
Status
Resolved
and removed
Status
Confirmed
labels 2023-07-25 16:45:44 +02:00
Member

It's not obvious to me that there exists a sensible way of telling the IK solver to partially reach a target.

That's fair, it may indeed be infeasible. Nevertheless, I think the current behavior is likely unexpected/unintuitive to most users, as well as not being especially useful. So if we can figure out a way to make it work in the future, I think that would be desirable. But not a high priority, since this is pretty niche already.

> It's not obvious to me that there exists a sensible way of telling the IK solver to partially reach a target. That's fair, it may indeed be infeasible. Nevertheless, I think the current behavior is likely unexpected/unintuitive to most users, as well as not being especially useful. So if we can figure out a way to make it work in the future, I think that would be desirable. But not a high priority, since this is pretty niche already.

Hello. I'm currently writing an addon for Blender which requires a lot of constraints targeting bones. I tested in 4.0, and still getting weird dependency graph errors with my copylocation/copy rotation constraints, etc. I am working around it by deleting the constraints when needed, but it still creates a lot of unnecessary overhead and limits what I can do.

I was wondering if this fix for IK constraints could be extended to other constraints? At the very least, when it comes to constraints that are entirely muted, I believe they ought not be accounted for in the dependency graph.

Hello. I'm currently writing an addon for Blender which requires a lot of constraints targeting bones. I tested in 4.0, and still getting weird dependency graph errors with my copylocation/copy rotation constraints, etc. I am working around it by deleting the constraints when needed, but it still creates a lot of unnecessary overhead and limits what I can do. I was wondering if this fix for IK constraints could be extended to other constraints? At the very least, when it comes to constraints that are entirely muted, I believe they ought not be accounted for in the dependency graph.
Member

@Isaac-Burke Can you please file another issue for that, with a clear example and minimal demo .blend file? That will make it easier to track, and will also let us figure out more easily if your issue is actually a bug or not. It's possible that's just a limitation of the current system.

@Isaac-Burke Can you please file another issue for that, with a clear example and minimal demo .blend file? That will make it easier to track, and will also let us figure out more easily if your issue is actually a bug or not. It's possible that's just a limitation of the current system.
Sign in to join this conversation.
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
5 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender#88752
No description provided.