Loops
With loops you can repeat a set of commands either n-times or until a certain condition is violated.
While Statement
Here is an example that loops as long as the condition is valid. The condition needs to be a Boolean expression, e.g. a > b or a Boolean variable that is either false or true.
while(condition)
echo("do something")
endwhile
A while-condition basically reads like this: “Execute the following lines as long as the given condition is true”.
Similar to the if - statement, the condition needs to be a boolean expression that can be evaluated
as either true or false. If it is true, the lines up until the endwhile-keyword are executed. The condition is then evaluated again. This continues until the condition is no longer true.
Check out this very simple example:
unsigned N(20)
while(N>0)
if(N==10)
echo("N equals 10")
endif
N = N - 1
endwhile
whileThe iterator in the last line inside the body of the while - statement is very important. You need to increment the variable (N) that determine if your entry condition is true or false.
N = N - 1
In the example code above N = N-1 is used to increment the N variable (Alternatively, you could also write N -= 1). This is very important, as the N variable is part of the while ’s condition. If we forget to increment it, the loop will be running forever... Eventually an internal safety net will become active, that allows stopping the loop’s execution after a certain number of times (100000). However, it may take a while before that limit is reached, so make sure to increment the index variable properly.
Loop Statement
For a fixed number N of executions, you can use the loop statement:
loop(N)
echo("do something")
endloop
You can access the current iteration index within a loop by using $$i.
loop(N)
echo("do something in iteration " + $$i )
endloop
In the first iteration, this will give you the index 0, i.e., loops always start with 0.
Foreach Statement
Often you have to iterate through object lists and entity groups for which the foreach statement is useful. In the following example, for all points of a list the x-value is set to 4. Note that if there are other objects in the list, they simply get skipped.
foreach( F3DPoint p in myList )
p.setX(4)
endfor
Here is another example:
objectlist a()
a.add(1.0)
a.add(2.0)
a.add(3.0)
foreach (FDouble d in a)
echo("value = " + d )
endfor
You can also use the following shorter syntax:
for (FDouble d : a)
echo("value = " + d )
endfor
For all loop statements (i.e. while, loop, and foreach), it is possible to leave the current loop by using the leaveloop() command. The continueloop() command can be used to jump to the start of the loop and continue with the next step of the iteration.
Creating Multiple Objects in a Loop
A common scenario for algorithms, especially those that are useful in a geometry-focused system like CAESES, is creating multiple objects within a loop. An example is that you want to create points along a certain path that is calculated in a loop:
unsigned i(0)
while (i < 10)
point p(i, 0, 0)
i += 1
endwhile
This is supposed to create ten points in a loop along a straight line, but it does not work! All points are stored in the variable "p". The value of p from the previous iteration is overwritten each time and in the end we will be left with exactly one point – the last one – at [9, 0, 0].
There are two techniques that can be applied to achieve the desired behavior:
Option 1: Persistent Section
Add two more lines that tell CAESES we are in a persistent section:
unsigned i(0)
while (i < 10)
beginPersistentSection()
point p(i, 0, 0)
endPersistentSection()
i += 1
endwhile
For a persistent (drawable) feature this would achieve the desired result of having ten points displayed in the 3DView in a straight line. However, there is still one problem: After the while-loop has finished you can only interact with the last point that was created. The other nine points still exist, but there is no way to access them. This problem can be solved using option 2:
Option 2: Entity Groups
Entity groups can hold objects so that you can see and access them after the loop has finished:
unsigned i(0)
entitygroup group()
while (i < 10)
point p(i, 0, 0)
group.add(p)
i += 1
endwhile
This solves the problem of option 1 for persistent features, since it is possible to now address each point through the entity group "group".
For this to work, though, the entity group needs to be an accessible member of the feature, the accessibility of the point p does not matter.
For transient execution the behavior is actually the same as in option 1. The only difference here is, that additionally to the ten points an object of type FEntityGroup will be created in your model as well (assuming that it is set to be accessible). Most likely, this is not what you want.
For transient execution use a persistent section for this task, while for persistent creation the entity group offers more flexibility.