Get all objects in doc [SOLVED]

On 22/10/2014 at 11:53, xxxxxxxx wrote:


Is there a way to get all objects with a filter without having them selected?


That command requires them to be selected.. I currently have a script that calls the command to select all objects, grab the objects I want, the deselect all. But it gets messy when I want to have undos.

Is there a better way?


Heres the code I currently have..

def getAllNulls() :
    doc = c4d.documents.GetActiveDocument()
    c4d.CallCommand(100004766) #select all
    allNulls = doc.GetActiveObjectsFilter(True, type=5140, instanceof=True)
    c4d.CallCommand(100004767) #deselect all
    return allNulls

On 22/10/2014 at 12:07, xxxxxxxx wrote:

If you want your undo function wrapped around your method, it should work fine, I guess.
Like this:

def otherMethod
  do some stuff
  exampleList = getAllNulls()

I have just started with python, so I could be wrong very much, hope it helps.

On 22/10/2014 at 12:37, xxxxxxxx wrote:

The problem is that the select-all and deselect-all adds undo events which are system made, so I cant get around them..

I need to avoid the CallCommands..

On 22/10/2014 at 13:00, xxxxxxxx wrote:

Yea, you should definitely be avoiding CallCommand(), especially for such a trivial task.
You can use a recursive function to collect a list of all objects in the scene, or even write a generator
function which will be far more memory efficient.

There are plenty topics covering recursive and even non-recursive walking of the object hierarchy
here on the forum. Give the search or googles site: filter a try, and link here what helped you
finding the solution.


On 22/10/2014 at 13:06, xxxxxxxx wrote:

Right. I tried getting the top object and walking down the hierarchy. But seems like issues when there are children, then sub children, (and even more children).

If anyone has had luck with looking through a document, please share.

There should really be something in the API for this.

On 22/10/2014 at 13:31, xxxxxxxx wrote:

It's not in the API because only few built-in commands work on all objects in the scene of a specific type.
And another reason could be that its just a few lines, which however often need small adjustments.

This is a very generic approach:

import c4d
def get_all_objects(op, filter, output) :
    while op:
        if filter(op) :
        get_all_objects(op.GetDown(), filter, output)
        op = op.GetNext()
    return output
def main() :
    nulls = get_all_objects(doc.GetFirstObject(), lambda x: x.CheckType(c4d.Onull), [])
    print len(nulls)

On 22/10/2014 at 13:56, xxxxxxxx wrote:

Hmmm.. that's a bit more advanced then I thought. I'm not too familiar with lambda and its functions.

That function doesn't work when theres children.. I'll have to mess around with it.

On 22/10/2014 at 14:00, xxxxxxxx wrote:

Ah I think I got it.

after the while loop, you had the variables switched.

get_all_objects(op.GetDown(), filter, output)

On 22/10/2014 at 16:33, xxxxxxxx wrote:

Uups, that was a mistake of mine. :) fixed