Non-recursive hierarchy iteration

In this article we’ll take a look at how to crawl through a hierarchy of objects in CINEMA 4D, without using a recursion.

Why not use a recursion?

With very deeply nested hierarchies, a recursion can actually hit the stack limit and cause a crash. Normally, it’s not very likely but it may happen in some cases.

Iterating and counting objects

C++

The functions

```BaseObject* GetNextObject(BaseObject* op)
{
if (!op)
return NULL;

if (op->GetDown())
return op->GetDown();

while (!op->GetNext() && op->GetUp())
op = op->GetUp();

return op->GetNext();
}

LONG IterateHierarchy(BaseObject* op)
{
LONG count = 0;

while (op)
{
count++;
GePrint(op->GetName());
op = GetNextObject(op);
}

return count;
}
```

Usage

```void main()
{
BaseDocument* doc = GetActiveDocument();
if (doc)
{
BaseObject* start_object = doc->GetFirstObject();
LONG count = IterateHierarchy(start_object);
GePrint("Iterated " + LongToString(count) + " objects.");
}
}
```

Python

The functions

```def GetNextObject(op):
if op==None:
return None

if op.GetDown():
return op.GetDown()

while not op.GetNext() and op.GetUp():
op = op.GetUp()

return op.GetNext()

def IterateHierarchy(op):
if op is None:
return

count = 0

while op:
count += 1
print op.GetName()
op = GetNextObject(op)

return count
```

Usage

```def main():
start_object = doc.GetFirstObject()
count = IterateHierarchy(start_object)
print "Iterated " + str(count) + " objects."
```

Thanks to

Per-Anders Edwards for the original article at:
http://peranders.com/wiki/Python_Object_Iteration

Frank Willeke

worked with computers since more than 20 years | got hooked on computer graphics back on the AMIGA | started programming at the age of 13 | relesed some successful plugins for cinema 4d | started working for maxon computer gmbh in 2009 | now contributing to cinema 4d as a senior developer making electronic music since 1993 | playing the electric guitar since 1995 age of 14 | first live gigs in 1997 | playing the bass guitar 2005 | playing keyboards and synths since 2012 experimenting with photography since 2003

1. Using Yield
import c4d

def IterateHierarchy(op):

while op:
yield op

if op.GetDown():
op = op.GetDown()
continue

while not op.GetNext() and op.GetUp():
op = op.GetUp()

op = op.GetNext()

def main():
for x in IterateHierarchy(op):
print x.GetName()

if __name__==’__main__’:
main()

2. Riccardo Gigante

Hi Mike, thanks a lot for the insight.

In order to make it more “readable” I’ve reformatted to include space: hope you don’t mind about it.

``` def IterateHierarchy(op):     while op:         yield op         if op.GetDown():             op = op.GetDown()             continue         while not op.GetNext() and op.GetUp():             op = op.GetUp()         op = op.GetNext() def main():     for x in IterateHierarchy(op):         print x.GetName() ```

Best, Riccardo