Discussion:
[Maya-Python] Cycle Warning with ikHandle and getAttr(time=1)
Marcus Ottosson
2018-08-14 13:28:58 UTC
Permalink
Hi all,

TLDR; In Maya 2015-2018, getAttr returns stale value when used in
conjunction with an ikHandle

I’ve ventured into the depths of querying attributes at an arbitrary time..

# Examplefrom maya import cmds
cmds.getAttr("myNode.translateX", time=5)

And it has worked well so far, except for when IK is involved.

from maya import cmds
# Build Scene# o o# \ /# \ /# o#
cmds.file(new=True, force=True)
a = cmds.joint(name="Root")
cmds.move(0, 0, 20)
cmds.joint()
cmds.move(0, 0, 0)
b = cmds.joint()
cmds.move(0, 10, -20)
handle, eff = cmds.ikHandle(
solver="ikRPsolver",
startJoint=a,
endEffector=b,
)
assert cmds.getAttr(a + ".rx") == 0.0assert cmds.getAttr(a + ".rx",
time=1) == 0.0 # Cycle warning!

Suddenly, Maya throws a cycle warning. Why is that?

Furthermore, the value returned isn’t right anymore.

# Move handle
cmds.move(0, 15, -10, "|ikHandle1")
assert round(cmds.getAttr(a + ".rx"), 0) == -14.0assert cmds.getAttr(a
+ ".rx", time=1) == 0.0 # Bad value, no warning..

Where I should see -14.0 I get the previous value, 0.0. Why is that?

And so the story goes, until..

# Move root
cmds.move(0, 0, 21, a)
assert round(cmds.getAttr(a + ".rx"), 0) == -14.0assert
round(cmds.getAttr(a + ".rx", time=1), 0) == -14.0 # Correct

Viola, all values are correct. Why is that?? :O

This happens consistently across all versions of Maya, except 2015 doesn’t
throw a Cycle Warning.

Anyone stumbled upon this before?
--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+***@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/CAFRtmODV_eKp2%3DJ3AdUufuDfBe2qojSWFjNpT9gJO1A6e9OLhg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.
Joe Weidenbach
2018-08-14 20:13:05 UTC
Permalink
I call it a bug, but it's been around a loooong time.

Maya updates the ikHandles in a separate pass (there's just one solver for
multiple handles), and I don't believe that script mode forces an update on
the solver, where moving the root updates the DAG directly.

It's one of the several places where the maya internals bypass the DAG so
that they can work (IK handles don't put input connections on the joint
rotations as that _would_ be a cycle, so the update needs to live in a
callback somewhere, which isn't triggered by your code). Another place
where things get weird is with editable animation curves (the ones where
you've got an editable curve in the scene that updates the animation
curves).

Long story short, querying an attribute at a given time only works for
direct DAG evaluation. Anything which operates outside of the DAG won't be
updated when you call ```getAttr```. For those cases, you actually have to
set the time and refresh the evaluation prior to the ```getAttr``` call:

```
from maya import cmds

# Build Scene
# o o
# \ /
# \ /
# o
#
cmds.file(new=True, force=True)
a = cmds.joint(name="Root")
cmds.move(0, 0, 20)
cmds.joint()
cmds.move(0, 0, 0)
b = cmds.joint()
cmds.move(0, 10, -20)
handle, eff = cmds.ikHandle(
solver="ikRPsolver",
startJoint=a,
endEffector=b,
forceSolver=True,
)

assert cmds.getAttr(a + ".rx") == 0.0
cmds.refresh(force=True) # Side note, this means your scene actually has to
play through
assert cmds.getAttr(a + ".rx") == 0.0 # No Cycle warning anymore!

# Move handle
cmds.move(0, 15, -10, "|ikHandle1")
cmds.refresh(force=True)

assert round(cmds.getAttr(a + ".rx"), 0) == -14.0
assert cmds.getAttr(a + ".rx") == 0.0 # Correct value now, assertion is
thrown
```
Post by Marcus Ottosson
Hi all,
TLDR; In Maya 2015-2018, getAttr returns stale value when used in
conjunction with an ikHandle
I’ve ventured into the depths of querying attributes at an arbitrary time..
# Examplefrom maya import cmds
cmds.getAttr("myNode.translateX", time=5)
And it has worked well so far, except for when IK is involved.
from maya import cmds
# Build Scene# o o# \ /# \ /# o#
cmds.file(new=True, force=True)
a = cmds.joint(name="Root")
cmds.move(0, 0, 20)
cmds.joint()
cmds.move(0, 0, 0)
b = cmds.joint()
cmds.move(0, 10, -20)
handle, eff = cmds.ikHandle(
solver="ikRPsolver",
startJoint=a,
endEffector=b,
)
assert cmds.getAttr(a + ".rx") == 0.0assert cmds.getAttr(a + ".rx", time=1) == 0.0 # Cycle warning!
Suddenly, Maya throws a cycle warning. Why is that?
Furthermore, the value returned isn’t right anymore.
# Move handle
cmds.move(0, 15, -10, "|ikHandle1")
assert round(cmds.getAttr(a + ".rx"), 0) == -14.0assert cmds.getAttr(a + ".rx", time=1) == 0.0 # Bad value, no warning..
Where I should see -14.0 I get the previous value, 0.0. Why is that?
And so the story goes, until..
# Move root
cmds.move(0, 0, 21, a)
assert round(cmds.getAttr(a + ".rx"), 0) == -14.0assert round(cmds.getAttr(a + ".rx", time=1), 0) == -14.0 # Correct
Viola, all values are correct. Why is that?? :O
This happens consistently across all versions of Maya, except 2015 doesn’t
throw a Cycle Warning.
Anyone stumbled upon this before?
--
You received this message because you are subscribed to the Google Groups
"Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an
To view this discussion on the web visit
https://groups.google.com/d/msgid/python_inside_maya/CAFRtmODV_eKp2%3DJ3AdUufuDfBe2qojSWFjNpT9gJO1A6e9OLhg%40mail.gmail.com
<https://groups.google.com/d/msgid/python_inside_maya/CAFRtmODV_eKp2%3DJ3AdUufuDfBe2qojSWFjNpT9gJO1A6e9OLhg%40mail.gmail.com?utm_medium=email&utm_source=footer>
.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+***@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/CAM33%3Da6tf1W%2BXP2ew936ZMmPnRtNQceVZg4ZVuiM67dvv9TCPg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.
Joe Weidenbach
2018-08-14 20:14:41 UTC
Permalink
Helps to format :)

I call it a bug, but it’s been around a loooong time.

Maya updates the ikHandles in a separate pass (there’s just one solver for
multiple handles), and I don’t believe that script mode forces an update on
the solver, where moving the root updates the DAG directly.

It’s one of the several places where the maya internals bypass the DAG so
that they can work (IK handles don’t put input connections on the joint
rotations as that *would* be a cycle, so the update needs to live in a
callback somewhere, which isn’t triggered by your code). Another place
where things get weird is with editable animation curves (the ones where
you’ve got an editable curve in the scene that updates the animation
curves).

Long story short, querying an attribute at a given time only works for
direct DAG evaluation. Anything which operates outside of the DAG won’t be
updated when you call getAttr. For those cases, you actually have to set
the time and refresh the evaluation prior to the getAttr call:


from maya import cmds

# Build Scene
# o o
# \ /
# \ /
# o
#
cmds.file(new=True, force=True)
a = cmds.joint(name="Root")
cmds.move(0, 0, 20)
cmds.joint()
cmds.move(0, 0, 0)
b = cmds.joint()
cmds.move(0, 10, -20)
handle, eff = cmds.ikHandle(
solver="ikRPsolver",
startJoint=a,
endEffector=b,

forceSolver=True,

)

assert cmds.getAttr(a + ".rx") == 0.0

cmds.refresh(force=True) # Side note, this means your scene actually
has to play through
assert cmds.getAttr(a + ".rx") == 0.0 # No Cycle warning anymore!

# Move handle
cmds.move(0, 15, -10, "|ikHandle1")

cmds.refresh(force=True)

assert round(cmds.getAttr(a + ".rx"), 0) == -14.0

assert cmds.getAttr(a + ".rx") == 0.0 # Correct value now, assertion is thrown

​
Post by Joe Weidenbach
I call it a bug, but it's been around a loooong time.
Maya updates the ikHandles in a separate pass (there's just one solver for
multiple handles), and I don't believe that script mode forces an update on
the solver, where moving the root updates the DAG directly.
It's one of the several places where the maya internals bypass the DAG so
that they can work (IK handles don't put input connections on the joint
rotations as that _would_ be a cycle, so the update needs to live in a
callback somewhere, which isn't triggered by your code). Another place
where things get weird is with editable animation curves (the ones where
you've got an editable curve in the scene that updates the animation
curves).
Long story short, querying an attribute at a given time only works for
direct DAG evaluation. Anything which operates outside of the DAG won't be
updated when you call ```getAttr```. For those cases, you actually have to
```
from maya import cmds
# Build Scene
# o o
# \ /
# \ /
# o
#
cmds.file(new=True, force=True)
a = cmds.joint(name="Root")
cmds.move(0, 0, 20)
cmds.joint()
cmds.move(0, 0, 0)
b = cmds.joint()
cmds.move(0, 10, -20)
handle, eff = cmds.ikHandle(
solver="ikRPsolver",
startJoint=a,
endEffector=b,
forceSolver=True,
)
assert cmds.getAttr(a + ".rx") == 0.0
cmds.refresh(force=True) # Side note, this means your scene actually has
to play through
assert cmds.getAttr(a + ".rx") == 0.0 # No Cycle warning anymore!
# Move handle
cmds.move(0, 15, -10, "|ikHandle1")
cmds.refresh(force=True)
assert round(cmds.getAttr(a + ".rx"), 0) == -14.0
assert cmds.getAttr(a + ".rx") == 0.0 # Correct value now, assertion is
thrown
```
Post by Marcus Ottosson
Hi all,
TLDR; In Maya 2015-2018, getAttr returns stale value when used in
conjunction with an ikHandle
I’ve ventured into the depths of querying attributes at an arbitrary time..
# Examplefrom maya import cmds
cmds.getAttr("myNode.translateX", time=5)
And it has worked well so far, except for when IK is involved.
from maya import cmds
# Build Scene# o o# \ /# \ /# o#
cmds.file(new=True, force=True)
a = cmds.joint(name="Root")
cmds.move(0, 0, 20)
cmds.joint()
cmds.move(0, 0, 0)
b = cmds.joint()
cmds.move(0, 10, -20)
handle, eff = cmds.ikHandle(
solver="ikRPsolver",
startJoint=a,
endEffector=b,
)
assert cmds.getAttr(a + ".rx") == 0.0assert cmds.getAttr(a + ".rx", time=1) == 0.0 # Cycle warning!
Suddenly, Maya throws a cycle warning. Why is that?
Furthermore, the value returned isn’t right anymore.
# Move handle
cmds.move(0, 15, -10, "|ikHandle1")
assert round(cmds.getAttr(a + ".rx"), 0) == -14.0assert cmds.getAttr(a + ".rx", time=1) == 0.0 # Bad value, no warning..
Where I should see -14.0 I get the previous value, 0.0. Why is that?
And so the story goes, until..
# Move root
cmds.move(0, 0, 21, a)
assert round(cmds.getAttr(a + ".rx"), 0) == -14.0assert round(cmds.getAttr(a + ".rx", time=1), 0) == -14.0 # Correct
Viola, all values are correct. Why is that?? :O
This happens consistently across all versions of Maya, except 2015
doesn’t throw a Cycle Warning.
Anyone stumbled upon this before?
--
You received this message because you are subscribed to the Google Groups
"Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an
To view this discussion on the web visit
https://groups.google.com/d/msgid/python_inside_maya/CAFRtmODV_eKp2%3DJ3AdUufuDfBe2qojSWFjNpT9gJO1A6e9OLhg%40mail.gmail.com
<https://groups.google.com/d/msgid/python_inside_maya/CAFRtmODV_eKp2%3DJ3AdUufuDfBe2qojSWFjNpT9gJO1A6e9OLhg%40mail.gmail.com?utm_medium=email&utm_source=footer>
.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+***@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/CAM33%3Da4_ZRZS5VCzh1o8hgcJMLXOEvvgh0PWLv4YcMid9VntSQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.
Marcus Ottosson
2018-08-15 06:43:46 UTC
Permalink
Thanks Joe, that confirms my own research into this. I'm seeing traces of
this all the way back in Maya 6.0, and not just related to IK, but
time-related queries in general.

- http://forums.cgsociety.org/archive/index.php?t-188420.html
- https://forum.highend3d.com/t/non-correct-result-in-mdgcontext/38047/12

Challenging, to say the least..
--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+***@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/CAFRtmOA-17B4vF5UUfpSp8VruqKc8gAqDRLnFZh5cEfi_1XnGQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.
Marcus Ottosson
2018-08-17 08:17:59 UTC
Permalink
Ok, I’ve got a workaround.

- Whenever you query an attribute at a given time, query it at time - 1
first

Now the result is always correct, with or without IK, at the expense of one
more query.

*Example*

One quick way of achieving the effect is wrapping any call to getAttr with
this.

def getAttr(attr, time):
cmds.getAttr(attr, time=time - 1)
return cmds.getAttr(attr, time=time)

*Full working example*

from maya import cmds
# Build Scene# o o# \ /# \ /# o#
cmds.file(new=True, force=True)
a = cmds.joint(name="Root", position=(0, 0, 20))
b = cmds.joint(position=(0, 0, 0), relative=False)
c = cmds.joint(position=(0, 10, -20), relative=False)
handle, eff = cmds.ikHandle(
solver="ikRPsolver",
startJoint=a,
endEffector=c,
)
def getAttr(attr, time):
cmds.getAttr(attr, time=time - 1)
return cmds.getAttr(attr, time=time)
assert cmds.getAttr(a + ".rx") == 0.0assert cmds.getAttr(a + ".rx",
time=1) == 0.0
# Move handle
cmds.move(0, 15, -10, "|ikHandle1")
assert round(cmds.getAttr(a + ".rx"), 0) == -14.0assert
round(getAttr(a + ".rx", time=1), 0) == -14.0
# The above call also enables this other node to evaluate properly#
Which means we only need to call the special function once# per IK
node.assert round(cmds.getAttr(b + ".rx", time=1), 0) == 49.0

cmds.move(0, 15, -15, "|ikHandle1")
assert round(getAttr(a + ".rx", time=1), 0) == -4.0

This (luckily) works consistently across all current versions of Maya.

- https://github.com/mottosso/maya-test/pull/1/files
- https://travis-ci.org/mottosso/maya-test/builds/416763142
<https://travis-ci.org/mottosso/maya-test/builds/416763142?utm_source=github_status&utm_medium=notification>

It doesn’t quite jive with my understanding of IK and what Joe mentioned,
that it uses this internal callback. This workaround *shouldn’t* work, so
I’m a little weary still. Finally, I found that the Cycle Warning only
happens on Maya 2018, no other version; not even 2019. So I’m tempted to
just ignore it.
Post by Marcus Ottosson
Thanks Joe, that confirms my own research into this. I'm seeing traces of
this all the way back in Maya 6.0, and not just related to IK, but
time-related queries in general.
- http://forums.cgsociety.org/archive/index.php?t-188420.html
- https://forum.highend3d.com/t/non-correct-result-in-mdgcontext/38047/12
Challenging, to say the least..
--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+***@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/CAFRtmOBt5p3jBZhFzfgVdJDnYfQ8N9fn019m8CtqL51pR_vYDQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.
Marcus Ottosson
2018-08-17 08:18:56 UTC
Permalink
Oh, I should have added, this also applies to querying attributes via the
API and the MDGContext
<http://help.autodesk.com/view/MAYAUL/2017/ENU/?guid=__py_ref_class_open_maya_1_1_m_d_g_context_html>.
Phew!
Post by Marcus Ottosson
Ok, I’ve got a workaround.
- Whenever you query an attribute at a given time, query it at time - 1
first
Now the result is always correct, with or without IK, at the expense of
one more query.
*Example*
One quick way of achieving the effect is wrapping any call to getAttr
with this.
cmds.getAttr(attr, time=time - 1)
return cmds.getAttr(attr, time=time)
*Full working example*
from maya import cmds
# Build Scene# o o# \ /# \ /# o#
cmds.file(new=True, force=True)
a = cmds.joint(name="Root", position=(0, 0, 20))
b = cmds.joint(position=(0, 0, 0), relative=False)
c = cmds.joint(position=(0, 10, -20), relative=False)
handle, eff = cmds.ikHandle(
solver="ikRPsolver",
startJoint=a,
endEffector=c,
)
cmds.getAttr(attr, time=time - 1)
return cmds.getAttr(attr, time=time)
assert cmds.getAttr(a + ".rx") == 0.0assert cmds.getAttr(a + ".rx", time=1) == 0.0
# Move handle
cmds.move(0, 15, -10, "|ikHandle1")
assert round(cmds.getAttr(a + ".rx"), 0) == -14.0assert round(getAttr(a + ".rx", time=1), 0) == -14.0
# The above call also enables this other node to evaluate properly# Which means we only need to call the special function once# per IK node.assert round(cmds.getAttr(b + ".rx", time=1), 0) == 49.0
cmds.move(0, 15, -15, "|ikHandle1")
assert round(getAttr(a + ".rx", time=1), 0) == -4.0
This (luckily) works consistently across all current versions of Maya.
- https://github.com/mottosso/maya-test/pull/1/files
- https://travis-ci.org/mottosso/maya-test/builds/416763142
<https://travis-ci.org/mottosso/maya-test/builds/416763142?utm_source=github_status&utm_medium=notification>
It doesn’t quite jive with my understanding of IK and what Joe mentioned,
that it uses this internal callback. This workaround *shouldn’t* work, so
I’m a little weary still. Finally, I found that the Cycle Warning only
happens on Maya 2018, no other version; not even 2019. So I’m tempted to
just ignore it.
Post by Marcus Ottosson
Thanks Joe, that confirms my own research into this. I'm seeing traces of
this all the way back in Maya 6.0, and not just related to IK, but
time-related queries in general.
- http://forums.cgsociety.org/archive/index.php?t-188420.html
- https://forum.highend3d.com/t/non-correct-result-in-mdgcontext/38047/12
Challenging, to say the least..
--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+***@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/CAFRtmOAQpKQaB8FxFKkQpMup5qhu4KnoU5ATHT-_w%2BT1%3DT7TjA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.
Joe Weidenbach
2018-08-17 10:42:23 UTC
Permalink
Interesting. I should note, the callback is an assumption on my part.
There's no connection on the dependency graph, so there has to be an
internal system evaluating the handle, else it wouldn't work. Glad you
found a workaround though, I'll have to have a play with that.
Post by Marcus Ottosson
Oh, I should have added, this also applies to querying attributes via the
API and the MDGContext
<http://help.autodesk.com/view/MAYAUL/2017/ENU/?guid=__py_ref_class_open_maya_1_1_m_d_g_context_html>.
Phew!
Post by Marcus Ottosson
Ok, I’ve got a workaround.
- Whenever you query an attribute at a given time, query it at time -
1 first
Now the result is always correct, with or without IK, at the expense of
one more query.
*Example*
One quick way of achieving the effect is wrapping any call to getAttr
with this.
cmds.getAttr(attr, time=time - 1)
return cmds.getAttr(attr, time=time)
*Full working example*
from maya import cmds
# Build Scene# o o# \ /# \ /# o#
cmds.file(new=True, force=True)
a = cmds.joint(name="Root", position=(0, 0, 20))
b = cmds.joint(position=(0, 0, 0), relative=False)
c = cmds.joint(position=(0, 10, -20), relative=False)
handle, eff = cmds.ikHandle(
solver="ikRPsolver",
startJoint=a,
endEffector=c,
)
cmds.getAttr(attr, time=time - 1)
return cmds.getAttr(attr, time=time)
assert cmds.getAttr(a + ".rx") == 0.0assert cmds.getAttr(a + ".rx", time=1) == 0.0
# Move handle
cmds.move(0, 15, -10, "|ikHandle1")
assert round(cmds.getAttr(a + ".rx"), 0) == -14.0assert round(getAttr(a + ".rx", time=1), 0) == -14.0
# The above call also enables this other node to evaluate properly# Which means we only need to call the special function once# per IK node.assert round(cmds.getAttr(b + ".rx", time=1), 0) == 49.0
cmds.move(0, 15, -15, "|ikHandle1")
assert round(getAttr(a + ".rx", time=1), 0) == -4.0
This (luckily) works consistently across all current versions of Maya.
- https://github.com/mottosso/maya-test/pull/1/files
- https://travis-ci.org/mottosso/maya-test/builds/416763142
<https://travis-ci.org/mottosso/maya-test/builds/416763142?utm_source=github_status&utm_medium=notification>
It doesn’t quite jive with my understanding of IK and what Joe mentioned,
that it uses this internal callback. This workaround *shouldn’t* work,
so I’m a little weary still. Finally, I found that the Cycle Warning only
happens on Maya 2018, no other version; not even 2019. So I’m tempted to
just ignore it.
Post by Marcus Ottosson
Thanks Joe, that confirms my own research into this. I'm seeing traces
of this all the way back in Maya 6.0, and not just related to IK, but
time-related queries in general.
- http://forums.cgsociety.org/archive/index.php?t-188420.html
-
https://forum.highend3d.com/t/non-correct-result-in-mdgcontext/38047/12
Challenging, to say the least..
--
You received this message because you are subscribed to the Google Groups
"Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an
To view this discussion on the web visit
https://groups.google.com/d/msgid/python_inside_maya/CAFRtmOAQpKQaB8FxFKkQpMup5qhu4KnoU5ATHT-_w%2BT1%3DT7TjA%40mail.gmail.com
<https://groups.google.com/d/msgid/python_inside_maya/CAFRtmOAQpKQaB8FxFKkQpMup5qhu4KnoU5ATHT-_w%2BT1%3DT7TjA%40mail.gmail.com?utm_medium=email&utm_source=footer>
.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+***@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/CAM33%3Da6YmeXBz%3DNT_Usr7gpUxKsjNsMXbsuaGrXxM-n0JMtKvQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.
Marcus Ottosson
2018-08-17 10:54:15 UTC
Permalink
I would make that assumption too. There’s one more thing hinting towards it
being outside of the overall DAG loop, which is that changes happening in
response to IK don’t trigger callbacks, in particular the
maya.api.MDagMessage.addWorldMatrixModifiedCallback.
Post by Joe Weidenbach
Interesting. I should note, the callback is an assumption on my part.
There's no connection on the dependency graph, so there has to be an
internal system evaluating the handle, else it wouldn't work. Glad you
found a workaround though, I'll have to have a play with that.
Post by Marcus Ottosson
Oh, I should have added, this also applies to querying attributes via the
API and the MDGContext
<http://help.autodesk.com/view/MAYAUL/2017/ENU/?guid=__py_ref_class_open_maya_1_1_m_d_g_context_html>.
Phew!
Post by Marcus Ottosson
Ok, I’ve got a workaround.
- Whenever you query an attribute at a given time, query it at time
- 1 first
Now the result is always correct, with or without IK, at the expense of
one more query.
*Example*
One quick way of achieving the effect is wrapping any call to getAttr
with this.
cmds.getAttr(attr, time=time - 1)
return cmds.getAttr(attr, time=time)
*Full working example*
from maya import cmds
# Build Scene# o o# \ /# \ /# o#
cmds.file(new=True, force=True)
a = cmds.joint(name="Root", position=(0, 0, 20))
b = cmds.joint(position=(0, 0, 0), relative=False)
c = cmds.joint(position=(0, 10, -20), relative=False)
handle, eff = cmds.ikHandle(
solver="ikRPsolver",
startJoint=a,
endEffector=c,
)
cmds.getAttr(attr, time=time - 1)
return cmds.getAttr(attr, time=time)
assert cmds.getAttr(a + ".rx") == 0.0assert cmds.getAttr(a + ".rx", time=1) == 0.0
# Move handle
cmds.move(0, 15, -10, "|ikHandle1")
assert round(cmds.getAttr(a + ".rx"), 0) == -14.0assert round(getAttr(a + ".rx", time=1), 0) == -14.0
# The above call also enables this other node to evaluate properly# Which means we only need to call the special function once# per IK node.assert round(cmds.getAttr(b + ".rx", time=1), 0) == 49.0
cmds.move(0, 15, -15, "|ikHandle1")
assert round(getAttr(a + ".rx", time=1), 0) == -4.0
This (luckily) works consistently across all current versions of Maya.
- https://github.com/mottosso/maya-test/pull/1/files
- https://travis-ci.org/mottosso/maya-test/builds/416763142
<https://travis-ci.org/mottosso/maya-test/builds/416763142?utm_source=github_status&utm_medium=notification>
It doesn’t quite jive with my understanding of IK and what Joe
mentioned, that it uses this internal callback. This workaround
*shouldn’t* work, so I’m a little weary still. Finally, I found that
the Cycle Warning only happens on Maya 2018, no other version; not even
2019. So I’m tempted to just ignore it.
Post by Marcus Ottosson
Thanks Joe, that confirms my own research into this. I'm seeing traces
of this all the way back in Maya 6.0, and not just related to IK, but
time-related queries in general.
- http://forums.cgsociety.org/archive/index.php?t-188420.html
-
https://forum.highend3d.com/t/non-correct-result-in-mdgcontext/38047/12
Challenging, to say the least..
--
You received this message because you are subscribed to the Google Groups
"Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an
To view this discussion on the web visit
https://groups.google.com/d/msgid/python_inside_maya/CAFRtmOAQpKQaB8FxFKkQpMup5qhu4KnoU5ATHT-_w%2BT1%3DT7TjA%40mail.gmail.com
<https://groups.google.com/d/msgid/python_inside_maya/CAFRtmOAQpKQaB8FxFKkQpMup5qhu4KnoU5ATHT-_w%2BT1%3DT7TjA%40mail.gmail.com?utm_medium=email&utm_source=footer>
.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups
"Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an
To view this discussion on the web visit
https://groups.google.com/d/msgid/python_inside_maya/CAM33%3Da6YmeXBz%3DNT_Usr7gpUxKsjNsMXbsuaGrXxM-n0JMtKvQ%40mail.gmail.com
<https://groups.google.com/d/msgid/python_inside_maya/CAM33%3Da6YmeXBz%3DNT_Usr7gpUxKsjNsMXbsuaGrXxM-n0JMtKvQ%40mail.gmail.com?utm_medium=email&utm_source=footer>
.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+***@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/CAFRtmOBqRvk3BCsOwypxMe6j_%2BeqMP_BAYL8UCfEZ0s26YY6Rw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.
Loading...