incrementing uValue

Become a member of the CGSociety

Connect, Share, and Learn with our Large Growing CG Art Community. It's Free!

Thread Tools Search this Thread Display Modes
  02 February 2013
incrementing uValue

I'm trying to automate the distribution of objects along a motion path.
I've got 142 objects attached to the path
I've made a quick select set of their motion paths named "mPaths"
I want to assign each motion path a uValue that increases by 0.00715 more than the last.
My $i++ statement isn't incrementing.
???Is this because the ++ functionality can only be used with integer variables???
Declaring $i as a float and assigning it the value of 0.00715 isn't helping.

Here's my MEL:

for ($i = 0.00715 ; $i < 1 ; $i++ )
select -r "mPaths" ;
string $mPaths[ ] ;
$mPaths = `ls -sl` ;
for ($each in $mPaths)
print "setAttr (" + $each + ".uValue " + $i + " ; \n");

The result I'm getting is as follows:

setAttr (motionPath14.uValue 133.00715) ;
setAttr (motionPath15.uValue 134.00715) ;
setAttr (motionPath16.uValue 135.00715) ;
setAttr (motionPath17.uValue 136.00715) ;
setAttr (motionPath18.uValue 137.00715) ;
setAttr (motionPath19.uValue 138.00715) ;
setAttr (motionPath20.uValue 139.00715) ;
setAttr (motionPath21.uValue 140.00715) ;
setAttr (motionPath22.uValue 141.00715) ;

I can't explain the appearance and incrementing of the number before the ".00715".
And, again, the ".00715" fails to increment.

Of course I plan to just select the results of this MEL and execute it in the script editor.

If, in addition to solving my problem, someone could show me a more direct way of applying the results . . . that would be way cool.

  02 February 2013
The for loop works with floats but incrementing via ++ is only usefull for integers because it adds 1 onto the value. But you could write the following loop:

PS: here is a script that could speed up your work. It basically divides a distance by a value and creates locators at the division locations. You could use the replace object options from the modify menu to get your objects to the positions. The script works with either two selected points (components, locators, whatever) or a selected nurbsCurve (it does not attach objects to the curve). Because the given value is meant as desired spans, the amount of locators in mode "start/end" is n+1, while in mode "between" it adds a half span as offset so the resulting locators are located in the middle of a span. The amount of locators then is identical to the value you set.
Call the script with cDivisionOptions()

   global proc cDivisionOptions()
   	string $windowName = "divisionOptions";
   	if(`window -exists $windowName`) deleteUI $windowName;
   	window -title "division options" -width 340 -height 100 -sizeable 0 -resizeToFitChildren 1 $windowName;
   		columnLayout -adjustableColumn 1 -columnAlign "left";
   		separator -h 15 -style "none";
   		rowColumnLayout -numberOfColumns 4 -cw 1 80 -cw 2 40 -cw 3 20 -cw 4 180;
   		text -label "spans:   " -align "right";
   		string $cntrl[] = {};
   		$cntrl[0] = `intField -value 1 -enable 1`;
   		text -l "";
   		$cntrl[1] = `radioButtonGrp
   				-numberOfRadioButtons 2
   				-labelArray2 "start/end" "between"
   				-columnAlign2 "left" "left"
   				-select 1`;
   		separator -h 15 -style "none";
   		rowColumnLayout -numberOfColumns 3 -cw 1 106 -cw 2 107 -cw 3 106  -cs 1 5 -cs 2 0 -cs 3 0;
   		button -label "OK" -command ("cCreateDivisionLocators (`intField -q -v " + $cntrl[0] + "`) (`radioButtonGrp -q -select " + $cntrl[1] + "`); deleteUI " + $windowName + "; windowPref -remove " + $windowName);
   		button -label "Apply" -command ("cCreateDivisionLocators (`intField -q -v " + $cntrl[0] + "`) (`radioButtonGrp -q -select " + $cntrl[1] + "`)");
   		button -label "Cancel" -command ("deleteUI " + $windowName + "; windowPref -remove " + $windowName);
   		separator -h 6 -style "none";
   	showWindow $windowName;
   global proc float[] cGetDivisionPositions(int $divisions, int $mode)
   	float $res[] = {};
   	string $sel[] = `ls -long -fl -sl`;
   	if(`size $sel` == 1){
   		string $curve[] = `ls -ni -dag -long -type "nurbsCurve" $sel[0]`;
   		if(! `size $curve[0]`){
   			return {};
   			string $arcLen = `createNode arcLengthDimension`;
   			connectAttr -f ($curve[0] + ".worldSpace[0]") ($arcLen + ".nurbsGeometry");
   			float $minMaxParam[] = `getAttr ($curve[0] + ".minMaxValue")`;
   			setAttr ($arcLen + ".uParamValue") $minMaxParam[1];
   			float $curveLength = `getAttr ($arcLen + ".arcLength")`;
   			float $span = $curveLength / $divisions;
   			float $start = $mode == 1 ? 0 : ($span / 2);
   			float $bounds[] = $minMaxParam;
   			for($i=0;$i<($divisions + ($mode == 1 ? 1 : 0));$i++){
   				if(($i == 0 || $i == $divisions) && $mode == 1){
   					float $pos[] = `pointOnCurve -pr $minMaxParam[(int($i == 0 ? 0 : 1))] -p $curve[0]`;
   					string $loc[] = `spaceLocator -name ("p_" + $i)`;
   					move $pos[0] $pos[1] $pos[2] $loc[0];
   				float $currentLength = $mode == 1 ? ($i * $span) : ($span / 2 + $i * $span);
   				float $recursiveLength = 0;
   				float $param;
   				int $loops = 0;
   				while(! equivalentTol(0.0, ($currentLength - $recursiveLength), 0.0001)){	
   					$param = ($bounds[0] + $bounds[1]) * .5;
   					setAttr ($arcLen + ".uParamValue") $param;
   					$recursiveLength = `getAttr ($arcLen + ".arcLength")`;
   					if($recursiveLength < $currentLength)
   						$bounds[0] = $param;
   						$bounds[1] = $param;
   				$bounds = {$param,$minMaxParam[1]};
   				float $pos[] = `pointOnCurve -pr $param -p $curve[0]`;
   				$res[`size $res`] = $pos[0];
   				$res[`size $res`] = $pos[1];
   				$res[`size $res`] = $pos[2];
   			delete `listRelatives -parent -fullPath $arcLen`;
   		vector $start = `xform -q -ws -translation $sel[0]`;
   		vector $end = `xform -q -ws -translation $sel[1]`;
   		vector $step = ($end - $start) / $divisions;
   		vector $positions[] = {};
   		if($mode == 1){
   			$positions[0] = $start;
   				$positions[$i] = $start + $step * $i;
   			$positions[$divisions] = $end;
   			$positions[0] = $start + $step * .5;
   				$positions[$i] = $start + $step * .5 + $step * $i;
   		for($i=0;$i<`size $positions`;$i++){
   			vector $pos = $positions[$i];
   			$res[`size $res`] = $pos.x;
   			$res[`size $res`] = $pos.y;
   			$res[`size $res`] = $pos.z;
   	return $res;
   global proc cCreateDivisionLocators(int $divisions, int $mode)
   	float $pos[] = cGetDivisionPositions($divisions, $mode);
   	for($i=0;$i<(`size $pos` / 3);$i++){
   		string $loc[] = `spaceLocator -name ("p_" + $i)`;
   		move $pos[$i * 3] $pos[$i * 3 + 1] $pos[$i * 3 + 2] $loc[0];

Last edited by zaskar : 02 February 2013 at 11:21 AM.
  02 February 2013

Your assistance is appreciated.

I'll save out that procedure and give it a go.

ha ha plus equals instead of plus plus

I was tired. It was late.

Thanks again!

cDivisionOptions is going to be handy for something.

But it is not helping me increment the uValues of motion paths.

I'm so close!

float $i = 0 ;
while ($i < 1)
$i = $i+=0.00713;
string $mPaths[ ] ;
$mPaths = `ls -sl` ;
for ($each in $mPaths)

print ("setAttr (" + $each + ".uValue " + $i+=0.00713 + ") ; \n");


The above,
rather than looping through and increasing the uValue of each motion path by 0.00713,
is looping through, adding 0.00713 to EVERY motion path at once, again and again, until ALL uValues are ~1.

Someone please help!

Last edited by farcue : 02 February 2013 at 03:15 AM. Reason: Need more help
  02 February 2013
Well, that's precisely what you're telling it to do, while $i<1 is going to make it loop until $i=1. Your for loop is where the issue lies, you keep telling it do add .00713 or so to every value each time it goes through the while loop. This is not the proper code. Your code could be more like this to work:

float $i = 0 ;
int $j;
int $k=0;
int $num; 
while ($i < 1)
     $i = $i+=0.00713;
     string $mPaths[ ] ;
     $mPaths = `ls -sl` ;
     $num= size($mPaths);                    //Number of elements in $mPaths
     for ($j=$k;$j<$num;$j++) {
          print ("setAttr (" + $each + ".uValue " + $i+=0.00713 + ") ; \n");

There's a few optimizations you can make here, I didn't because I just felt like adding a few lines to what you had. Anyway, you needed your for loop not to run through each object in the array, otherwise you wouldn't get that staggered look. Also, out of curiosity, are you doing this to rig a chain/tread by any chance?

Lastly, I was just coding in C++, so there's a solid chance there may be some syntax issues with what I added, so make sure you fix any spots where there should be a $ or ; in the code I added.
  02 February 2013
I am very grateful for your assistance.

Your code looks good to me.

But when I run it I get the following errors:


// Error: $each=$mPaths[j];
// Error: Invalid use of Maya object "j". //
// Error: print ("setAttr (" + $each + ".uValue " + $i+=0.00713 + ") ; \n");
// Error: "$each" is an undeclared variable. //

Declaring all variables inside the while-block does not change the result.

I thought it might help Maya recognize the functions of $j and $each but no.

So, yes I see what you are trying to do.
AND it is exactly what I want to do.
But it's not working. Yet.

Yes it is for a tread.
Seems the equivalent of building a light-saber to me.
Wish I found it easier.

Last edited by farcue : 02 February 2013 at 07:18 AM.
  02 February 2013
Hehe, the errors tell you exactly the problem.

Look at the use of the variable $j in the for loop, you'll see I forgot a $. Generally, I find that the invalid use of Maya object ___ is due to me forgetting a $. Without the $, maya thinks you're trying to use one of its included functions or objects, instead of a variable (which is declared as a variable because of the $).

The variable $each was, literally, never declared.

Add the following line outside the while loop to declare the variable $each (in fact, all the variable declarations can be outside the while loop.if you're setting them equal to something, however, they probably need to be inside, except for a couple, don't worry about it though):

string $each;

Voila, the variable has been declared. Should be the last thing you need. Out of curiosity, have you had to do any programming before? It seems you have the general ideas of what you need to do Maya-wise, but it's just a few things script-wise that you're getting hung up on.

Good luck!

Last edited by VB2341 : 02 February 2013 at 07:34 AM.
  02 February 2013
Thank you so much for your time.
Declaring $each as a string variable fixes it.
One of the $j variables was lacking a "$" as well.
The semi-colons aren't showing up at line ends but I can fix that.

I'm a generalist with Maya. I know how all the blocks fit together and the techniques that will achieve desired outcomes it's the minutia that escapes me as I move from one aspect of the software to another. Keeping thorough documentation is essential!!!
Someone should hire me as a supervisor.

I really appreciate your patient guidance.
Thank you for helping me with this!

How about you?
"Just working in 'C' "
And a new-ish member here.
How does one skip right to programming, grip it, and rip it?
Looks like magic from my POV.

Last edited by farcue : 02 February 2013 at 08:25 AM.
  02 February 2013
Maybe you could try this:

string $mopaths[] = `ls -sl`;
int $coverAllCurve = 1;
int $numMopaths = size($mopaths);
float $inc = 1.0/($numMopaths-$coverAllCurve);
for ($i=0; $i<$numMopaths;  $i++)
    setAttr ($mopaths[$i]+ ".uValue") ($i*$inc);
  02 February 2013
Hey Nico,

Thanks for your input.

Just so you know when I run your code I get:

//Error: float $inc = 1.0($numMopaths-$coverAllCurve);
// Error: Syntax error //

I appreciate the sentiment.
It would be nice to have a script that acts directly on the scene objects without further input.
But I don't know what to think of your function:

setAttr ($mopaths[$i]+ ".uValue") ($i*$inc);

It just mystifies me.
  02 February 2013
Strange, because in the code box, the line is:

float $inc = 1.0/($numMopaths-$coverAllCurve);

Given the fact that 0.00713 seems to be very close to 1/142, I assumed you were trying to spread all the objects over the entire curve.
So this script should compute the proper uValue for each mopath selected to achieve this...
Then, if you want the last one to be positionned at the end of the curve or not, you just alter the value of the variable $coverAllCurve accordingly.

To make a very short description of the script:

It gets all the mopaths selected, computes the proper uValue increment ($inc), then the for loop modifies the uValue of each one with:
setAttr ($mopaths[$i]+ ".uValue") ($i*$inc);

The $i*$inc behaves this way in the loop:
$i=0 --> ($mopaths[$i]+ ".uValue") = 0 // first motionPath
$i=1 --> ($mopaths[$i]+ ".uValue") = 0.00713 // second motionPath
$i=2 --> ($mopaths[$i]+ ".uValue") = 0,01426 // third motionPath
  02 February 2013
That is strange!

All I did was copy & paste so don't know how that happened.

Your explanation of the script is super useful.

It is very enlightening to experience different people's solutions.

Thank you for sharing. And for helping me to understand.
  03 March 2013
I have a solution for you, Farcue.
maya and zbrush training
creating CG3D since 2001

3D Models
@ Turbosquid

my Scripts
  03 March 2013
Thank You

Very nice.

And super prompt.

I haven't played with it yet.

But I'm going to get into it right quick.

Thanks so much for automating the whole process.
  03 March 2013
I have a follow-up article for you.
maya and zbrush training
creating CG3D since 2001

3D Models
@ Turbosquid

my Scripts
  03 March 2013
Thread automatically closed

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.
CGTalk Policy/Legalities
Note that as CGTalk Members, you agree to the terms and conditions of using this website.
Thread Closed share thread

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Society of Digital Artists

Powered by vBulletin
Copyright 2000 - 2006,
Jelsoft Enterprises Ltd.
Minimize Ads
Forum Jump

All times are GMT. The time now is 10:10 PM.

Powered by vBulletin
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.