A new version of Cineversity has been launched. This legacy site and its tutorials will remain accessible for a limited transition period

Visit the New Cineversity
   
 
Writing a Python Selection Script for Children in a Hierarchy
Posted: 24 June 2014 11:59 AM   [ Ignore ]  
Total Posts:  16
Joined  2014-06-17

Hello,

We are wondering if anyone has any ideas as to how we might select only the children of a parent that is in a nested hierarchy using Python for Cinema 4D?

The children we want to select using Python are grouped under a null that is two levels deep (the null has a parent that has a parent).  We are also hoping to be able to select this null by the name “_cpk”.

I appreciate the help!

Thanks,

Profile
 
 
Posted: 24 June 2014 02:04 PM   [ Ignore ]   [ # 1 ]  
Avatar
Total Posts:  15
Joined  2006-05-17

Does it need to be python? If you know the null you could just Middle Mouse click on it to select it’s children.

If it does need to be python, you can try something like this:

def GetAllObjects(objobjList):
    if 
obj is None: return

    
#Actions can go here
    
objList.append(obj)
    
#End Actions
    
if (obj.GetDown()):
        
GetAllObjects(obj.GetDown(), objList)
    if (
obj.GetNext()):
        
GetAllObjects(obj.GetNext(), objList)
    return 
objList

def GoDownHierarchy
(objstopobjList):
    if 
obj is None: return
    if 
obj==stop: return
    
    
#Actions can go here
    
objList.append(obj)
    
#End Actions
    
if (obj.GetDown()):
        
GoDownHierarchy(obj.GetDown(), stopobjList)
    if (
obj.GetNext()):
        
GoDownHierarchy(obj.GetNext(), stopobjList)

    return 
objList


def main
():
    
emptyList=[]
    allObjs
=GetAllObjects(doc.GetFirstObject(), emptyList)
    
null=None
    
for obj in allObjs:
        
name=obj.GetName()
        if 
len(name.split('_')>0:
            if 
name.split('_')[-1]=='cpk':
                
null=obj
                
break

    if 
null != None:
        
emptyList2=[]
        children
=GoDownHierarchy(nullnull.GetNext(), emptyList2)

    if 
len(children)>0:
        for 
idchild in children:
            if 
id==0:
                
doc.SetSelection(childrenc4d.SELECTION_NEW)
            else:
                
doc.SetSelection(childrenc4d.SELECTION_ADD

So, the idea here is if you need to manage to find the null through python, we have to get all of the objects in our scene and look for it. So the first function gets every object in the scene when you pass in doc.GetFirstObject(). The function actually gets every object underneath whatever you pass in (child or siblings included). So starting at the top of the OM gets all of the objects.

So then we loop through those objects and look for an object that ends with _cpk. Once we have that, we run the second function which gets all of the children of the object you pass in. Then we just loop through all those children and set them to be selected.

I can’t guarantee this works properly as is because I wrote it from memory and this link on my website http://bretbays.com/2011/02/11/a-useful-python-snippet-addendum/ but conceptually that should work. Someone else might know of a better way to do it than this.

Hope this helps.

~Bret

 Signature 

http://www.bretbays.com

Profile
 
 
Posted: 24 June 2014 04:48 PM   [ Ignore ]   [ # 2 ]  
Total Posts:  16
Joined  2014-06-17

Bret,

I looked through your script and fixed some parenthesis and tried to tinker with some things, but I cannot get this script to actually select anything.  The console says that c4d.BaseObject is not iterable, so if you know what that means, that would help out a lot.

Also, I just wanted to make sure you knew that “_cpk” is only part of the null object’s name, not the entire name.

Could you explain what actions could/should be inserted where you say that I can “insert actions”?

If you have any suggestions, I would like to hear them.  I’m still new at Python in Cinema 4D, and I really appreciate your help!

Profile
 
 
Posted: 24 June 2014 07:41 PM   [ Ignore ]   [ # 3 ]  
Avatar
Total Posts:  15
Joined  2006-05-17

yeah, I know. What the script is doing is splitting the name of the object on underscores and it checks to see if the last split is cpk. The Actions depend on what you wanted to do. It was copied from a script on my website where it said that. Nothing needs to go there as I’m just using those functions as a way to gather objects.

I’d have to know more about the error to figure it out. I can try it when I am home and have CINEMA in front of me.

 Signature 

http://www.bretbays.com

Profile
 
 
Posted: 25 June 2014 03:44 PM   [ Ignore ]   [ # 4 ]  
Total Posts:  16
Joined  2014-06-17

Bret, I looked at what you had, and I tried to use what you wrote to come up with something that might work, but it’s still not quite there.  Right now, this script will select the name of the null that I need, but I just need to modify it slightly so that it selects the children of that null as well, and that is where I am getting stuck.  Could you take a look at it?

import c4d
from c4d import gui
#Welcome to the world of Python


def main():
    
c4d.CallCommand(100004766)
    
allObjs doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_CHILDREN)
    
atoms "A_cpk"
    
for obj in allObjs:
        if 
obj.GetName().find(atoms) == int(-1):
            
doc.SetSelection(objc4d.SELECTION_SUB)
            

if 
__name__=='__main__':
    
main() 

Thanks!

-Nate

Profile
 
 
Posted: 25 June 2014 04:01 PM   [ Ignore ]   [ # 5 ]  
Avatar
Total Posts:  15
Joined  2006-05-17

Can you upload a scene file so I can test a script and make sure it’s working properly?

 Signature 

http://www.bretbays.com

Profile
 
 
Posted: 26 June 2014 12:17 AM   [ Ignore ]   [ # 6 ]  
Avatar
Total Posts:  15
Joined  2006-05-17
import c4d

def GetAllObjects
(objobjList):
    if 
obj is None: return

    
#Actions can go here
    
objList.append(obj)
    
#End Actions
    
if (obj.GetDown()):
        
GetAllObjects(obj.GetDown(), objList)
    if (
obj.GetNext()):
        
GetAllObjects(obj.GetNext(), objList)
    return 
objList

def GoDownHierarchy
(objstopobjList):
    if 
obj is None: return
    if 
obj==stop: return
    
    
#Actions can go here
    
objList.append(obj)
    
#End Actions
    
if (obj.GetDown()):
        
GoDownHierarchy(obj.GetDown(), stopobjList)
    if (
obj.GetNext()):
        
GoDownHierarchy(obj.GetNext(), stopobjList)

    return 
objList


def main
():
    
emptyList=[]
    allObjs
=GetAllObjects(doc.GetFirstObject(), emptyList)
    
null=None
    
for obj in allObjs:
        
name=obj.GetName()
        if 
len(name.split('_'))>0:
            if 
name.split('_')[-1]=='cpk':
                
null=obj
                
    
print null      
    
if null != None:
        
emptyList2=[]
        children
=GoDownHierarchy(nullnull.GetNext(), emptyList2)

    if 
len(children)>0:
        for 
idchild in enumerate(children):
            if 
id==0:
                
doc.SetSelection(childc4d.SELECTION_NEW)
            else:
                
doc.SetSelection(childc4d.SELECTION_ADD)
                
    
c4d.EventAdd()
if 
__name__=='__main__':
    
main() 

Tried this, and that works. There was some syntax problems on the first code, but apart from a ), adding enumerate() and changing children to child in two spots it was the same as the initial code.

 Signature 

http://www.bretbays.com

Profile
 
 
Posted: 26 June 2014 11:46 AM   [ Ignore ]   [ # 7 ]  
Total Posts:  16
Joined  2014-06-17

Thank you so much! That really helps. 

Also, I tried uploading my scene file, but I’m not exactly sure in what format it needed to be uploaded because the forum wouldn’t accept .c4d files.

Anyways, thank you.

-Nate

Profile