getAttr worldMatrix time argument problem

109 προβολές
Παράβλεψη και μετάβαση στο πρώτο μη αναγνωσμένο μήνυμα

j op

μη αναγνωσμένη,
6 Νοε 2021, 6:06:29 μ.μ.6/11/21
ως Python Programming for Autodesk Maya
Hello, animator here. I really can't figure out this problem for several weeks so hopefully someone can help me.

I am trying to get a worldMatrix of a controller at different frames WITHOUT moving in the timeline. I am using getAttr() with the time argument but it gives me wrong result on some specific controllers. I am not good enough in rigging to understand what is so specific about these controllers.

Here is my code where I compare the matrices translations of a single selection, obtained by different method. xform(ws = True) that gives me always the correct result. And Funny enough, getAttr() without the time argument give me the correct result as well. Why on earth just adding the time argument make the result all wrong?

import maya.cmds as mc
import random

#Get selection
ctrl = mc.ls(sl=True)[0]

#Get a random frame
frameNr = random.randint(1,100)
#Set the current time to test xform
mc.currentTime(frameNr)

print ('Frame: %s'%mc.currentTime(q=True))

#Get the matrix with getAttr with the Time argument - bad result
getAttr_matrix_time = mc.getAttr('%s.worldMatrix[0]'%ctrl, time = frameNr)
print (getAttr_matrix_time[12],getAttr_matrix_time[13],getAttr_matrix_time[14], ' -> getAttr(time) ')

#Get the matrix with getAttr without the time argument - good result
getAttr_matrix = mc.getAttr('%s.worldMatrix[0]'%ctrl)
print (getAttr_matrix[12],getAttr_matrix[13],getAttr_matrix[14], ' -> getAttr() ')

#Get the matrix with xform - good result
xform_mat = mc.xform(ctrl , matrix = True, q = True, ws = True)
print (xform_mat[12],xform_mat[13],xform_mat[14], ' -> xform() ')


My bug comes on this rig free rig for example: https://agora.community/content/bulbasaur
On the controller "C_big_vine_mid_ctrl".

Peter Scott

μη αναγνωσμένη,
7 Νοε 2021, 9:43:27 μ.μ.7/11/21
ως Python Programming for Autodesk Maya
Hello! I believe your method is working properly, however, it looks like there are some local rotate pivots on the control you are querying the worldMatrix from, that are making the world matrix appear to be in the incorrect location. If you place a locator under the "C_big_vine_mid_ctrl" and zero it out, you will see the offset.

In this case, instead of running the getAttr on the control itself, you should be able to get the worldMatrix of the 'C_big_vine_mid_DrvJ' joint that is parented under the control instead. That joint seems to have the proper translation values to compensate for the offset, and should return the proper world translate values of the controller location.

Hope that does the trick, though I'm sure there are probably a bunch of different ways to return a worldMatrix that takes local rotation pivots into account.

j op

μη αναγνωσμένη,
8 Νοε 2021, 12:13:11 μ.μ.8/11/21
ως Python Programming for Autodesk Maya
Thank you Peter to checking that out.

I forgot to mention that my bug comes up inconsistently but definitely when the i put some random keys on the master controller of the rig. It seems that getAttr(time) get the world matrix but with a certain kind of Offset (different from the local rotate pivot ) and does not consider his parent matrix.

Here is a link to the rig with simple keys on the master. When select the "C_big_vine_mid_ctrl" then run the script, you can see that the world matrix result from getAttr() and getAttr(time)/ xform are different.
https://drive.google.com/file/d/1X7MEMpyi51g9QY50fZHPtvmzd8bgvNIg/view?usp=sharing

Peter Scott

μη αναγνωσμένη,
9 Νοε 2021, 6:41:32 π.μ.9/11/21
ως Python Programming for Autodesk Maya
Hey!

Yes, you are correct, the behavior is inconsistent and wasn't related to the rotation pivot of the control, definitely getting different results from the getAttr() and getAttr(time). It seems like the issue lies with any controls that are a child of a group parented to joints that are driven by follicles connected to weighted nurbs surfaces. I presume there is some issue with the way getAttr(time) is evaluating the components of the deforming surface, but don't have sufficient understanding to really say what's going on.

In the case of the spine on the Bulbasaur rig, anything under the 'C_big_vine_master_ctrl_offs' has issues as that group is parented to a series of joints being controlled by follicles on 'C_spine_Ribbon'. I tried an API method to get the  value of the worldMatrix[0] plug at a specific time but ran into the same issue with objects that were children of the ''C_big_vine_master_ctrl_offs' group. The only workaround I could see was to parent an object in world space to the control, then bake simulation on it, before using getAttr(time)... but that's probably even less ideal than just setting the time, using getAttr(), and returning to the current time..

Anyways, that's about at the limit of my understanding of the issue, sorry I couldn't provide a better solution! Perhaps someone else in the group might have a better grasp of the problem!

In case it's of any use, here's the API method I tried to get the world matrix at different time, that ran into the same issue as the getAttr(time) python command.

###################################
import maya.api.OpenMaya as om2
import maya.cmds as cmds

new_time_value = 24.0  # frame to set as context
mTime = om2.MTime()
mTime.value = new_time_value
mDGContext = om2.MDGContext(mTime)

node = 'C_vine_grp'  # Name of Maya node to query
mSelList = om2.MSelectionList()
mSelList.add(node)
mObject2 = mSelList.getDependNode(0)
mFnDepNode2 = om2.MFnDependencyNode(mObject2)

mPlug = mFnDepNode2.findPlug('worldMatrix', False)
mPlugAttr = mFnDepNode2.findPlug('worldMatrix', False).attribute()
mPlug.selectAncestorLogicalIndex(0, mPlugAttr)

mPlugFuture = mPlug.asMObject(mDGContext)
mFnMatrixData = om2.MFnMatrixData(mPlugFuture)

mMatrix = om2.MMatrix(mFnMatrixData.matrix())
mTransformationMatrix = om2.MTransformationMatrix(mMatrix)
transforms = mTransformationMatrix.translation(4)
world_translation = [transforms[0], transforms[1], transforms[2]]

print('World translation of "{}" at frame {} is: {}'.format(node, new_time_value, world_translation))
###################################

j op

μη αναγνωσμένη,
9 Νοε 2021, 10:36:02 π.μ.9/11/21
ως python_in...@googlegroups.com
Thank you so much for the insight and helping pinpoint where the problem is coming from.
It's a really strange bug.... I also had a go with the api but since I'm new to it I was hoping I was doing something wrong hehe.

Anyway, my problem with setting the time is the slowness of it, even without refreshing the viewport, the speed of getAttr(time) is way better.
Or is there a faster way than mc.refresh(suspend = true) mc.currentTime(frame) to set the time in maya?

--
You received this message because you are subscribed to a topic in the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/python_inside_maya/4sSiJiJiVh4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/7b807de8-f9ca-433e-a721-934d3c1e276an%40googlegroups.com.
Απάντηση σε όλους
Απάντηση στον συντάκτη
Προώθηση
0 νέα μηνύματα