variables and expressions in a MEL script


#1

I’m making a little automated script to link the displacement alpha gain for displacement maps to object scale and I’ve hit a snag since I’m new to MEL and coding in general. I want the expression part in this script to use the float variables, not the set values but when I try and put them in brackets and quotes, it chokes. I’m sure it’s just me not understanding what they do (what do the quotes do?). Anyway, if someone can tell me how to get the expression parts to use the variables, it would help a lot:

string $mySelection[] = `ls -sl`;
float $gainval = `getAttr (($mySelection[0])+".alphaGain")`;
float $gainoffset = `getAttr (($mySelection[0])+".alphaOffset")`;
setAttr (($mySelection[0])+".alphaGain") $gainval;
setAttr (($mySelection[0])+".alphaOffset") $gainoffset;
setAttr (($mySelection[0])+".filterType") 0;
expression -string "ZBrushDispMap.alphaGain = 0.149 * pSphere11.scaleX";
expression -string "ZBrushDispMap.alphaOffset = ZBrushDispMap.alphaGain * -0.5";

edit: I just realized that I’ll need to get the sphere object as a variable too. Is there a way to getAttr on the object’s transform node from the Displacement map selection (which is what’s needed for the script).


#2

if you want an expression to use a variable, it is better to declare it with the expression itself, so that you don’t have to run the script again when you load the scene.

If you want to create an expression that uses a value that is stored in a variable, then you can use this form:

float $sx = 3.141;
expression -s ("float $sx = pPlane1.scaleX;\rfile1.alphaGain = pPlane1.scaleX * " + $sx + “;”) ;

if you want the expression to use the variable, but you want to set the variable in a script, and not in the expression, use

$sx = 2.718;
expression -s “file1.alphaGain = pPlane1.scaleX * $sx ;” ;

The problem of getting the name of the object from the displacement is a bit trickier. Expressions have no way to say “the name of the object that uses this expression” or “me”, so you’ll have to figure that out before you write the expression.

hyperShade -objects displacementShader#;

selects the objects that use displacementShader#, so you could do

// select the displacement Node
hyperShade -objects ls -sl;
string $sl[] = ls -sl;
string $attrName = ($sl[0] + “.scaleX”);


#3

I think I understand what you’re trying to do, and a couple of things pop out at me.

string $mySelection[] = `ls -sl`;
  float $gainval = `getAttr (($mySelection[0])+".alphaGain")`;
  float $gainoffset = `getAttr (($mySelection[0])+".alphaOffset")`;
  setAttr (($mySelection[0])+".alphaGain") $gainval;
  setAttr (($mySelection[0])+".alphaOffset") $gainoffset;
  setAttr (($mySelection[0])+".filterType") 0;
 So far all your script has done is set the filterType of the first selected object to 0. You've stored the values of alpha gain and alpha offset, and then just put those exact same values right back in, making your 3rd and 4th lines essentially do nothing, as the values of $gainval and $gainoffset are not being changed at all.
expression -string "ZBrushDispMap.alphaGain = 0.149 * pSphere11.scaleX";
  expression -string "ZBrushDispMap.alphaOffset = ZBrushDispMap.alphaGain * -0.5";
 These expression commands are missing a key component: what to attach the expression to.
 I imagine what you want is to select an object and run the script. If that's the case, here is code that I would use to do this (I'm assuming 0.149 and -0.5 are constants that you want to use to multiply by scale of the selected objects):
// get the selected object(s)
 string $mySelection[] = `ls -sl`;
 // find the displacement assigned to the first selected object and store it in $dispMap
 
// shaders are assigned to shapes, and you will likely have a transform selected, 
 // so get the shape under that transform
 string $shapes[] = `listRelatives -s $mySelection[0]`;
 // get the shading group assigned to that shape
 string $sGroup[] = `listSets -type 1 -o $shapes[0]`;
 // get the displacement node of that shading group
 string $dNode[] = `listConnections -d 0 -s 1 ($sGroup[0] + ".displacementShader")`;
 // get the texture file assigned to the displacement
 string $file[] = `listConnections -d 0 -s 1 ($dNode[0] + ".displacement")`;
 string $dispMap = $file[0];
 // now that you have everything you need, you can construct your expression:
 expression -string ($dispMap + ".alphaGain = 0.149 * " + $mySelection[0] + ".scaleX;
" + $dispMap + ".alphaOffset = -0.5 * " + $mySelection[0] + ".scaleX;") -o $mySelection[0] -ae 1 -uc all;
 The "-ae 1 -uc all" may not be necessary, but it shouldn't hurt to have them there. "-o $mySelection[0]" is entirely necessary, though.
 Hope this helps!

#4

thanks - just curious. Is the expression in my example not going to “stick” like adding it manually? You said I need to reload the script when I open it again.


#5

I should have stated why those values are duplicated - when you load a displacement map from GoZ and ZBrush, those values are always different. So I don’t want to have to worry about what they are - I just want to copy and paste them into the fields, have the values locked to the scale and have them stored as floats for the expression. Is it still redundant?


#6

sorry - read above (stupid buggy forum put my answer above your post). Those numbers aren’t constants - I want to use variables in their place.

GOD DAMMIT - WHAT IS UP WITH THIS FORUM


#7
The problem with this is that if you have an expression setting the alpha gain and offset, you can't manually enter new values into those fields - they will always be overwritten by the expression. You essentially has three sets of values you're working with:
1. Original alpha gain and alpha offset
2. Scale of object
3. New alpha gain and alpha offset
In the code I posted, there is no distinction between sets 1 & 3 and I was using the constants you put as values for set 1. If you have values in the alpha gain and offset already, you can modify the previous script with the following lines to do what you want.
// now that you have everything you need, you can construct your expression:
   float $gainval = `getAttr ($dispMap+".alphaGain")`;
     float $gainoffset = `getAttr ($dispMap+".alphaOffset")`;
   expression -string ($dispMap + ".alphaGain = " + $gainval + " * " + $mySelection[0] + ".scaleX;
" + $dispMap + ".alphaOffset = " + $gainoffset + " * " + $mySelection[0] + ".scaleX;") -o $mySelection[0] -ae 1 -uc all; 

Keep in mind that you can only run this script on an object once. If you need to manually change the initial gain and offset values, you’ll need to adjust the expression, or delete it, reset the values and re-run the script.


#8

thanks - that works great. I’ll take a closer look later after I read more MEL stuff and get a handle on some of the commands. thx again.


#9

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.