# MSFBA chapter 3: Looping - perform a task over and over again.

November 18, 2017

1. The power of loop

“Do not pity the dead, Harry. Pity the living and above all, those who live without loop” - Albus Dumbledood

Finally, we hit a chapter that allow us to make a powerful script. First, don’t get too excited. Let us examine what looping is and why it is so useful. Let’s get back to Mike the bot. Actually, let’s get all the way back to the very first example, making Mike eating a bag of chips.

Let’s pretend you have not seen what instructions I wrote there for Mike and start from scratch with everything you have learnt so far. The instructions would look like this:

- take a bag of chips
- open a bag of chips
- take the first chip put it in mouth

- chew the first chip

- swallow the first chip

- take the second chip put it in mouth
- chew the second chip
- swallow the second chip

- take the third chip put it in mouth
- chew the third chip
- swallow the third chip

.....

As you can see, that looks ridiculous for two reason. One, you have to write the same thing over and over again and two, you wouldn’t know how many chips are there in the bag therefore you can’t complete your instructions.

A more sensible way to write an instructions list is the way you have seen in the very first chapter, like this:

- take a bag of chips
- open a bag of chips
- for each chip in the bag:
- take and put it in your mouth
- Chew it
- Swallow it

The third line “for each chip in the bag” telling Mike to repeat the same action below until there are no more chips left in the bag. That is looping, repeating the same action over and over again until a condition is satisfied.

As you can see loop is extremely useful. Being able to execute the same task over and over again on multiple objects, pair with near instantaneous speed of the computer are what make scripting such a powerful thing you can do within Maya. Let us dive into how to loop in MEL. There are three way you can loop within MEL.

- for in loop: allow you to repeat the same action over many objects without the need to know how many objects there are.

- for loop: allow you to repeat the same action over a defined amount of time

- while loop: same as for loop. In my experience, choosing between while loop and for loop is just a matter of taste.

2. For in loop

If you have a set of items you want to perform the same tasks over and over again, this is the loop for you.

To use the for in loop:

1. you would need an array (this is one of the main used of array).

2. Then you can define a bunch of tasks and commands

3. The loop will take your tasks list and perform it on each item, from the first to the last item in the array.

Here is the syntax for the for in loop

for (\$x in \$array)

{

}

In which:

1. \$array is your defined array.(could be any name you want)

2. \$x is what I call a proxy variable (you can also choose a different name than \$x). You don’t have to define \$x before the loop. \$x will also automatically have the same data type as your array \$array. As the loop go through many round of performing the same task on each object within the \$array (technically term is iteration), \$x will represent the current item the loop is working on.

3. Whatever you puts between { } will be executed over each item in \$array.

Example:

string \$nameList[]={"Dave","Steve","Bob"};
for (\$name in \$nameList)
{
print ("hello, " + \$name + "\n");
}

Let’s pretend we are the computer, here is what we will do:

1. string \$nameList[]={"Dave","Steve","Bob"};

Alright, This tells us to make a box type string, named \$nameList with 3 items inside. Item number 0 "Dave" (we count from 0 remember?), item number 1 "Steve", item number 2 "Bob".

2. for (\$name in \$nameList)

This tells us to start a loop with the \$nameList array.

2.1. first loop, we are going to deal with the first item in the \$array "Dave" which, during this loop, proxy variable \$name will refer to. We are going to execute the commands  between the { }. In this case, there is only one command

print ("hello, " + \$name + "\n");

which is equivalent to print ("hello, " + "Dave" + "\n");

therefore the result of this loop is a line printed "hello, Dave" then enter a new line.

"\n" is a sign for MEL to understand you want to go to the new line. Read more here.

2.2 second loop, same as first loop, except \$name will refer to the second item in \$nameList "Steve". The result is "hello, Steve"

2.3  third loop, same as first and second loop, except \$name will refer to the second item in \$nameList "Bob. The result is "hello, Bob". This is also the last item in the array \$nameList so this is where the loop end.

So after all these, the result you see is

"hello, Dave

hello , Steve

hello, Bob"

Please make sure to check out this improved version of the offset group using loop:

offsetGrpsV3

Here are a few more example:

3. For loop

The for in loop above allow you to perform the same tasks over multiple objects without the need to know how many time the loop repeat. The for loop, on the other hand, allow you to control precisely how many time the loop repeat.

For example, if we want Mike to eat exactly 21 chips(given that the bag contain equal or more than 21 chips), our instructions will look like this:

- take a bag of chips
- open a bag of chips
- for 21 times:
- take a chip in the bag and put it in your mouth
- Chew it
- Swallow it

To way to use the for loop is slightly more convoluted than the for in loop (just slightly). Here is the syntax of the for loop:

for (\$x=1;\$x<10;\$x=\$x+1)

{

}

1. \$x (could be of any name) is a proxy variable and it has to be integer or float. You would assign a starting value for \$x at the beginning of your loop. If you assign a whole number without decimal, Maya will automatically make \$x an integer. If you assign a number with decimal, Maya will make \$x a float.

2. \$x < 10 is a condition to continue the loop. as long as this condition is satisfied, the loop goes on.

3. \$x = \$x + 1 is what going to happen to \$x at the end of each loop, also called the counter. This is where it might confuse beginner a little bit so read on the next part carefully.

Let’s pretend you are Mike the bot. Here is my instructions list:

-for 10 times:

-jump up and down

You would count mentally or out loud “one” then do the first jump, “two” do the second jump, “three” do the third jump and so on until you reach “ten”, do the final jump then stop.

I can also make Mike do the same thing with slighly different instructions:

- put up one finger

- for each time you do these folllowing actions, raise one more finger and don’t stop if the amount of raised fingers is less than 10:

- jump up and down.

The second instructions list is way more convoluted, begging the question why we want to use it in the first place. Well, there are a few pros that come with the cons of phrasing the instructions this way:

- you can set the starting number (the number of fingers you want Mike to put up before the loop start)

- you can set the counting step to your liking( instead of raising one more finger every loop, you can raise two or three or any number you want)

- you can use the amount of fingers Mike currently raised as a variable in the current loop.

Now, in our context, these pros seem pretty useless but consider the next scenarior. Let say that we want to make Mike write out all numbers from 1 to 9. We couldn’t write our instructions the easy way like this:

- for 9 times:

- write a number

That wouldn’t make any sense to Mike as he has no idea what number to write. The second, more complicated instruction works perfectly here:

- put up one finger
- for each time you do these folllowing actions, raise one more finger and don’t stop if the amount of raised fingers is less than 10:
- write a number that is equal to the amount of your raised fingers.

This is something Mike can understand and follow.
- First, he put up one finger.
- The amount of raised fingers is 1 which is less than 10, therefore Mike perform the action within the loop. He write down number 1 because he has 1 finger raise.
- This is the end of the first loop so Mike raise one more finger.
- The amount of raised fingers is 2 which is less than 10, therefore Mike perform the action within the loop. He write down number 2 because he has 2 finger raise.
- This is the end of the second loop so Mike raise one more finger.
- ....
- This goes on until Mike has 10 fingers raised which is not less than 10 therefore Mike stop the loop. He completed the instruction and successfully write down 1,2,3,4,5,6,7,8,9.

Following that, I can make Mike write out all the odd number from 1 to 9 by tweaking the instructions just a little bit:

- put up one finger
- for each time you do these folllowing actions, raise TWO more finger and don’t stop if the amount of raised fingers is less than 10:
- write a number that is equal to the amount of your raised fingers.

or I can make Mike write out all the even number:

- put up TWO fingers
- for each time you do these folllowing actions, raise TWO more finger and don’t stop if the amount of raised fingers is less than 10:
- write a number that is equal to the amount of your raised fingers.

As you can see, this way of writing instructions, while complicated, is very flexible in term of controlling what the loop can do. This is how MEL understands the for loop. For comparison let me rewrite the instructions for Mike above into MEL. Since the computers have way more fingers than Mike, let’s make it write out all the numbers between 1 and 1000.

for (\$x=1;\$x<1000;\$x=\$x+1)
{
print \$x;
}

Or write out all the odd number:

for (\$x=1;\$x<1000;\$x=\$x+2)
{
print \$x;
}

Or write out all the even number:

for (\$x=2;\$x<1000;\$x=\$x+2)
{
print \$x;
}

Tips:

- another way to write \$x=\$x+\$anyNumber is \$x+=\$anyNumber. \$x+=7 is the same as \$x=\$x + 7. You can see that this counting method is so useful, programmer had to invent a whole new syntax just to save a bit of effort.

- Talking about saving effort, within this counting method, counting by 1 \$x+=1 or \$x = \$x+1 is far outweighed any other counting step in term of practical usage therefore you can write that in this way too \$x++. \$x++ is the same as \$x+=1 and \$x=\$x+1. This is why C++ is called C++ and MEL is derived from it.

Caution-Infinite loop:

The computer isn’t smart. If you tell it to carry on a task without end, it will carry that task on forever until it crashes itself. Of course, there is no reason for anyone to want to make a script that run forever, at least in MEL. However, accident does happen and it happens most frequently within the use of the loop.

Remember that in the for loop, as long as the condition you set before the loop is satisfied, the loop goes on. You could potentially set a condition that is forever true and the script never stops like this:

for(\$A=5,\$A>3,\$A+=1)
{
print "I'd like to move it move it";
}

We set our condition \$A is greater than 3 which is already satisfied because \$A starting value is 5. Every time a loop is completed, \$A keeps getting bigger and bigger therefore the condition \$A>3 is forever satisfied, the loop will never stop.

Please try it out in Maya, but make sure you save everything and get ready to ctrl-alt-del combo ;)!

4.(optional) while loop

The reason why I put optional for this while loop is because, most of the time, choosing between the while loop and the for loop is just a matter of taste. Of course there are few situation where the while loop is more convenient to use than the for loop but I personally would opt for the for loop almost always.

However, like I said that is a matter of taste. There are lots of people that favour the while loop therefore, it’s good to know this loop so it’s easier for us to study their script.

The while loop can be explained simply like this:
- while the condition is satisfied, carry on the loop.

Here is its MEL syntax:
while (\$A<10)
{
//do something
}

In which, if the variable \$A<10, the loop goes on. So how do we stop the loop? It’s not like the for loop where we can put a increment to \$A so at some point, the loop can stop. Well, in this case, we just have to put that increment to \$A inside the loop. For example:

int \$A = 1; //define starting value
while (\$A<10)
{
print \$A;
\$A+=1; // this is where we put the counter
}

As you can see, the main problem with this loop is it’s easier for you to forget the counter therefore it’s more likely to run into an infinite loop.

However, there are always pros come with cons. The advantage of while loop is:

1. You don’t have to end your loop with a counter, there are some situation where you might want to run a few more commands after the counter before the loop end, for example.

int \$A = 1; //define starting value
while (\$A<10)
{
print \$A;
\$A+=1; // this is where we put the counter
print " the next number is ";
print \$A; // \$A is already increase by 1

print "\n"; //enter newline
}

2. Because you put the counter within loop, it allows you to write a much more complex way of increment than just increase by 1,2 or 3....

For example, let say you want to make a loop that print out a fibonacci sequence from 1 to 100. If you are not familiar with it, here is the rule, the first two number is 0 and 1, the next number is equal to the sum of the two previous number. So it goes like this 0 1 1 2 3 5 8 13 21.... as you can see, the increment rule is more complicated than just increase by a fixed value like 1 or 2. The while loop is suitable for this situation. Here is the script to print out all numbers in a fibonacci sequence from 1 to 100

int \$A = 0; //define the first value

int \$B = 1; //define the next value

int \$N = 1; // this is going to be our counter

while (\$N < 100)

{

print (\$N + " "); //print the next number

\$N=\$A+\$B;// next number is the sum of two previous number

\$A = \$B;

\$B = \$N;

// that is the trick to make this work,

// before we enter the next loop, we dynamically changing \$A and \$B

//value to the two last number of the current sequence. So that,

//the next loop \$N can again be the sum of two previous number.

}

In conclusion, most of the time, if it gets the job done, it doesn’t matter what loop you choose. They are tools and you are the artist.

5. Loop within a loop

The rule for the loop is, whatever you put in between { } will be executed over and over again x amount of times depend on how you set your loop. Because of that, there is nothing wrong about putting a loop inside a loop. You can repeat a loop by using another loop. For example:

for (\$x=0;\$x<10;\$x+=1)
{
for (\$y=0;\$y<10;\$y+=1)
{
print "Yay!";
}
}

If you run this, you’ll see that it will print out “Yay!” 100 times. This is due to the command print being loop 10 times in a loop which is looped 10 times by another loop. In a more practical example, let say we want to make a script that generate 1000 spheres arranged into a cube of 10 spheres on each edge.

for (\$x=0;\$x<10;\$x+=1)

{

for (\$y=0;\$y<10;\$y+=1)

{

for (\$z=0;\$z<10;\$z+=1)

{

move \$x \$y \$z;

}

}

}

In conclusion, loop is a powerful tool in scripting. Make sure you understand it really well before we are moving on to the next chapter. After this chapter you should be able to start automating some of your tasks whether in animation, modelling or rigging...

Check out the examples and exercises page to have a better grip of everything we have learned so far. See ya there!

Recent Posts

Archive