2

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."

Further notes

Also read the article about recursive hierarchy iteration.

Thanks to

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

Avatar

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

2 Comments

  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. 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

Comments are closed.