Expressions - Setting attributes on many objects through a loop. Feedback pls...

Expressions - Setting attributes on many objects through a loop. Feedback pls...

dkrelina
Advocate Advocate
1,321 Views
1 Reply
Message 1 of 2

Expressions - Setting attributes on many objects through a loop. Feedback pls...

dkrelina
Advocate
Advocate

Hi,

 

I am trying to make an expression that loops through a set of nodes and sets an attribute on each of them. I have been able to write something that does the trick. I have some questions, generally about cleanliness of code and efficiency. I'd love some feedback on this...

 

The expression does the following:

 

  • Looks at a set of file nodes based on name. (The file nodes read image sequences.)
  • Sets the frameExtension attribute on each of the file nodes so that:
    • When we reach the end of the sequence, we loop back to the beginning.
    • Each file node has the option to have a custom frame offset.
    • The sequence can be slowed down by a given (integer) rate.

Here is the expression:

 

string $objList[5] = { "file1", "file2", "file3", "file4", "file5" };
int $offset[5] = { 0, 7, 11, 4, 18 };
$seqLength = 31;
$seqBase = 1;
$frameHold = 3;

$i = 0;
for ( $obj in $objList ){

	$val = floor ( ( frame / 3) + $offset[$i] ) % $seqLength + $seqBase;
	setAttr ($obj + ".frameExtension") $val;
	$i += 1;
	
}

My questions:

  • The expression above has caused Maya to become unstable. I have a blank scene with only a few objects, file nodes, materials and this expression and Maya has been crashing much more than usual. What is causing it to become unstable?
  • I have noticed that the attributes of the affected channels are not colored purple, despite the fact that there is an expression on those channels. Why is this? Is it because I am setting the attributes using setAttr rather than with the equals sign "=" ? What is the difference between the two? And how would I use the equals sign in a for loop?
  • When doing a for loop (like above), is it better to use:
    • "for ($a in $b)" and initialize $i before the loop.
    • or
    • "for( $i=0; $i<6; ++$i )" and use $objList[$i] in place of $obj.
    • I tried running the expression below but I was given the error: "// Error: An execution error occured in the expression expression1."
string $objList[] = { "file1", "file2", "file3", "file4", "file5" };
int $offset[5] = { 0, 7, 11, 4, 18 };
$seqLength = 31;
$seqBase = 1;
$frameHold = 3;

for ( $i=0; $i<6; ++$i ){

	$val = floor ( ( frame / 3) + $offset[$i] ) % $seqLength + $seqBase;
	setAttr ($objList[$i] + ".frameExtension") $val;
	
}
  • How do I get the length of a given array?
  • When defining the string array, is it necessary to include the length inside the square brackets? Or can I leave this empty? Ex. "string $objList[] = ..."
  • I was required to create all of the 5 file nodes manually in order for the expression to work. If I had many more nodes (10, 20 or 50) it would be tedious to set all of them up. So I am wondering whether it possible to create the file nodes also through code? I suspect I would need to do this through mel/python (not through an expression). Is this correct?

I thank you very much for your help!!

 

David

0 Likes
1,322 Views
1 Reply
Reply (1)
Message 2 of 2

mcw0
Advisor
Advisor

It's been almost a year!  So you probably have answered all of your questions.  But in case you haven't...

 

Seems like you are only going through this process once, not every frame.   So just run this as a mel script and not an expression.  To automatically populate your array, you can use string $array[] = `ls -type file "file*"`;.  And then to find out how many files are in your array, size($array).

 

Now if you have specific offset values for each file node, then it gets tricky.  You would have to devise a system to identify the file node and set a corresponding offset value.

 

And yes, the reason the attribute is not colored is because when using "setAttr" you are not creating a connection.  To make a connection, you would have to set the attribute equal to something in your expression.

 

As far as I know, there's no efficiency difference between for($node in $array) and for($i=0;$i<size($array);$i++).  The only difference is that $i gives you a counter.