View Full Version : Basic understanding of the Expression Editor
rhythmone 04-13-2003, 01:06 AM I don't think that I understand the Expression Editor.
I have created 3 locators. On two of them I have created a custom attribute that will store the 3rd locator's worldspace z value. The script is something like this:
float $unit_val = `unitiZe "core_unit" "core_zero"`;
default_pose_scaled.Unit_Val = $unit_val;
target1_pose_scaled.Unit_Val = $unit_val;
unitiZe is a little script basically returning the worldspace z value.
Now, if I move the 3rd locator the other attributes do not update? I have checked "Always Evaluate" but that only updates them once.
1 - Are expressions supposed to be tied (attached somehow) to attributes? Is that why it says "selected obj & attr"?
2 - If they are supposed to be tied to an attribute, to which one should I create it from in the above example? Do I have to duplicate it for all these attrs, or somehow split it up?
3 - Else, how do I get a value to continuously update (just like as if you tied the ty of one obj to the ty of another, and moved the first, the other updates in real time)
|
|
dmcgrath
04-13-2003, 06:47 AM
If they are only connected in the expression editor, that might be a problem. Expressions are evaluated over time. That means you need an animation or a time change to see the update. Have you tried hitting play and then seeing if the values have updated? If you want something to update "on the fly" you have to connect them some other way. Via the Connection editor, or connectAttr MEL or even set driven keys, might be possible.
mark_wilkins
04-13-2003, 10:41 AM
rhythmone:
Expressions are not exactly like MEL scripts because they rely on being connected to other nodes' attributes to execute at the right times.
If you get information that your expression needs by calling a MEL command (including getAttr or setAttr) or by calling a global procedure that uses these commands, you're outwitting Maya's ability to discern what data dependencies your expression has, and it may not know when to execute.
The way Maya knows to create an input or output connection for an expression is that you use the attribute name directly in an assignment. For example:
float $x_val = nurbsSphere1.tx;
When Maya sees an expression containing this line, it knows to make an input connection from nurbsSphere1.tx to your expression.
Alternatively, if you assign a value to an attribute in an expression:
nurbsSphere1.tx = sin(frame);
that becomes an output connection from your expression to nurbsSphere1.tx.
Maya relies on these connections to know when to properly execute your expression. If you have no input connections, your expression will not execute.
It is possible to execute arbitrary MEL commands inside an expression, but you have to be careful. In some instances, doing so can be VERY slow, such as when they create nodes or alters connections in the dependency graph.
Or, in some cases, Maya may not evaluate the expression correctly because it doesn't know when the input data changes. This is what's going on in your script.
The best way to do what you're trying to do in an expression is to get the world space matrix from the locators in the expression by assigning the value that's in the worldMatrix attribute to a matrix variable and grabs the tz attribute the same way. Then, write a procedure that will use this matrix with the local Z parameter to find the world space Z coordinate.
This way, the data you're depending on will come from expression connections rather than from a getAttr command wrapped up in a script, and your expression will work fine.
-- Mark
rhythmone
04-16-2003, 03:14 AM
Mark
Thanks, your comments are always great. I have been reading and re-reading your post trying to assimilate all the details. The part about the connection helps clarify.
Here is what I did:
float $tranZ = core_unit.translateZ;
float $unit_val = `unitiZe "core_unit" "core_zero"`;
default_pose_position.Unit_Val = $unit_val;
target1_pose_position.Unit_Val = $unit_val;
... and this works, I assumed it was because of the designated call to the "translateZ" even though it isn't used.
The best way to do what you're trying to do in an expression is to get the world space matrix from the locators in the expression by assigning the value that's in the worldMatrix attribute to a matrix variable and grabs the tz attribute the same way. Then, write a procedure that will use this matrix with the local Z parameter to find the world space Z coordinate.
Can you elaborate or show some mock code as an example?
-Is "worldMatrix" an actual callable value? I couldn't find it in the help docs (or is that more underworld stuff/)
-When is it preferable to use a matrix vs. an array? and is there a quick way to put things into a matrix, cause this doesn't work:
matrix $test = `xform -q -t -ws my_object`
mark_wilkins
04-16-2003, 04:16 AM
Hi again!
I gave you bad instructions.
As it turns out (and I apologize for not remembering this off the top of my head, as it doesn't come up much) it's not possible to connect matrices to expression nodes in this way at all. Also, it's not the worldMatrix that you want, it's parentMatrix. (The reason, and you'll have to bear with me on this, is that multiplying parentMatrix by the object's local transform gives you the object's position in world space. Multiplying worldMatrix by the local transform of a child of this object gives you that child's position in world space.)
There is a solution that avoids using a getAttr or using backticks to run a script that does a getAttr, however.
First off, I found the parentMatrix attribute by looking in the Node and Attribute Reference under the "transform" node type, which Maya uses for most things that have a position in space. (joints are a notable exception.)
The transform node type, according to that page, is a kind of "dagNode," which if you look at the documentation for THAT has a matrix-valued attribute called parentMatrix.
Generally, when you multiply the parentMatrix of an object by its local transform values, you get its world space position.
Since an expression can't directly connect to a matrix (as I found out in researching the answer to this, and as I misstated before) you'll need a different way to use the parentMatrix to find the world space value.
As it turns out, Maya offers a utility node called vectorProduct that will multiply two vector-valued attributes or multiply a matrix by a vector. You simply plug its inputs into other nodes' attributes and plug its outputs into whatever you need.
So, here's the MEL that creates a vectorProduct node and hooks it up. I just typed this into the script editor and hit enter. I'm assuming your locator is called locator1 but you can use any name you like in its place. Make sure to group locator1 under a few other transforms so that you can experiment with making sure it's really giving you world space values:
string $vectorProd = `createNode vectorProduct`;
connectAttr locator1.parentMatrix ($vectorProd + ".matrix");
connectAttr locator1.tx ($vectorProd + ".input1X");
connectAttr locator1.ty ($vectorProd + ".input1Y");
connectAttr locator1.tz ($vectorProd + ".input1Z");
setAttr ($vectorProd + ".operation") 4;
print $vectorProd;
This makes a new vector product node, hooks up the world matrix attribute of locator1 to its input matrix attribute, and hooks up tx, ty, and tz for the locator to the X, Y, and Z inputs.
The setAttr on the "operation" attribute tells the vectorProduct node exactly what to do with the inputs... when operation is set to 4, the node does a full matrix multiplication between the matrix and the input X, Y, and Z values, which is what you want.
Now, just for a hands-on demonstration, make another locator. (I'll assume it's called locator2.) We'll use an expression to force this locator's tz to follow the world space Z value for the first locator, so that we can see that it's doing the right thing. I'll assume it's called locator2:
Now, open the expression editor and enter this expression;
float $z = vectorProduct1.outputZ;
// This is the world space Z value you were
// looking for
locator2.tz = $z;
So now you've made one locator (locator1), a vectorProduct node that's multiplying its parentMatrix by its local tx, ty, and tz, and an expression that drives the local tz of a second locator (locator2) based on the output of the vectorProduct, which should be the world space value in Z.
Move locator1 around either by manipulating it directly or manipulating its parents, and you'll see that locator2 follows in Z.
I recommend that you pick the locator and look at its connections in the hypergraph to see how the locator connects to the vectorProduct, and that in turn connects to the expression, which drives the other locator.
Why go to all this trouble? Because
(1) getting and setting attributes in expressions makes them hard to debug. For example, if you look at the expression node in the hypergraph, and you've used getAttr or setAttr in the expression, you can't necessarily tell what the expression depends on.
(2) Often, calling MEL commands using backticks, or even getAttr, can cause Maya to recalculate large parts of the scene graph that it may not have to recalculate because it knows it can't foresee the implications of the command. Using utility nodes makes this less likely.
(3) Using attribute connections wherever possible greatly reduces the chance that Maya will fail to recalculate your expression as the things it depends on change.
(4) utility nodes are usually faster than expressions for operations like this. In this instance it doesn't make a big difference, but if you were making thousands of these expressions in a scene you'd be happy you did it this way.
I hope that all makes sense.
-- Mark
rhythmone
04-16-2003, 06:56 AM
Mark
This is really great stuff:bounce:
It takes a couple of readings but IS sinking in, and I totally get your points at the bottom. I will try this tomorrow in a hands on approach and am going to fORCE myself to start WATCHING THE HYPERGRAPH!! I know there's good stuff there.
It your interested, here is a thread that I am trying to contribute to:
http://www.cgtalk.com/showthread.php?s=&postid=525203#post525203
I am going to re-write some of those files using this approach, but feel free to chime in and contribute (only if your interested of course)... the facial rig that I am working on has me very optimistic.
Thank you so much.... you :airguitar
rhythmone
04-16-2003, 06:46 PM
Mark
I have spent this morning reading through the nodes sections that you mentioned.
The setAttr on the "operation" attribute tells the vectorProduct node exactly what to do with the inputs... when operation is set to 4, the node does a full matrix multiplication between the matrix and the input X, Y, and Z values, which is what you want.
Forgive me but my brain is full.... What does the matrix do in this situation?
I assume that the matrix typically holds mulitple vectors in order to define a shape (vertice points). Since this is a locator, it does have a shape, but why does this attribute need to be connected? What is the matrix in this situation. Since we are not dealing with any "shape" stuff in this expression, why ????
And secondly, where did you find the definition of setting the operation to "4"? I didn't see any numbers defined in the vectorProduct node doc.
mark_wilkins
04-16-2003, 07:25 PM
What does the matrix do in this situation?
I assume that the matrix typically holds mulitple vectors in order to define a shape (vertice points). Since this is a locator, it does have a shape, but why does this attribute need to be connected? What is the matrix in this situation. Since we are not dealing with any "shape" stuff in this expression, why ????
What is the matrix? -- The Wachowski Brothers
Without getting too wrapped up in linear algebra, matrices are used whenever you have to apply an affine spatial transformation to a bunch of points.
Affine spatial transformations are any combination of translation, rotation, scaling, and shear. So, all the transformations you can perform by fiddling with the parameters in a transform node can be combined into a single affine transformation.
You can take all of these operations (translate, rotate, scale, shear) and boil them down to a 4 x 4 matrix that you can multiply by a point's local tx, ty, and tz values to give you the location after applying the matrix's operation.
So, if your position is <<tx, ty, tz>>, you multiply the transformation matrix T by <<tx, ty, tz, 1>> to get the transformed location.
The way we're using it, vectorProduct with an operation value of 4 (called the Point Matrix Product in its documentation) takes the locator's tx, ty, and tz in as inputs and performs the matrix transform operation defined by the parentMatrix of the locator. The parentMatrix is the transformation you need to apply to a point in the locator's local space to get to world space.
And secondly, where did you find the definition of setting the operation to "4"? I didn't see any numbers defined in the vectorProduct node doc.
In the docs, it describes the operation attribute as an "enum" variable. The way these work in Maya, if you go into the attribute editor and pick one of those operations off the list, Maya will set the operation variable to a number that corresponds to the choice you've made.
It's not obvious from the documentation but if you do it by hand in the attribute editor you'll see that when you pick "Point Matrix Product" you get a message in the script editor that says
setAttr vectorProduct1.operation 4;
I just noted that this was the attribute value corresponding to the point matrix product when I chose that choice by hand and used it in the MEL commands I gave you.
-- Mark
rhythmone
04-17-2003, 07:41 PM
Mark
This is really great stuff:bounce:
It takes a couple of readings but IS sinking in, and I totally get your points at the bottom. I will try this tomorrow in a hands on approach and am going to fORCE myself to start WATCHING THE HYPERGRAPH!! I know there's good stuff there.
It your interested, here is a thread that I am trying to contribute to:
http://www.cgtalk.com/showthread.php?s=&postid=525203#post525203
I am going to re-write some of those files using this approach, but feel free to chime in and contribute (only if your interested of course)... the facial rig that I am working on has me very optimistic.
Thank you so much.... you :airguitar
CGTalk Moderation
01-14-2006, 09:00 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.
vBulletin v3.0.5, Copyright ©2000-2012, Jelsoft Enterprises Ltd.