Jump to content
Info News:
  • C4D Cafe 2.0 COMING SOON!

Sign in to follow this  
thunderdoc

Put multiple objects selected under null

Recommended Posts

Hi, I'm starting to learn Python inside C4D and got some exciting progress, but I'm struggling with a small detail.

 

It's a simple script to create a null object and then move the selected objects under the null. The null object has its visibility in viewport and render turned off.

it does work well when selecting one object and running the script, but when I select more than one object and try to run, the script return an error.

 

Here's a GIF showing what happens:

HTqZCID.gif

 

I suspect I have to create a list of the selected objects and for each of the selected objects I should to assign a InsertUnder command, but I'm not getting how it could be done or if it's the solution.

 

Here's the code, I suspect the error is in the line 27 / 28.

 

import c4d


def checknull():
    nullexist = doc.SearchObject('FD Backup')
    if nullexist == None:
        insertfdbackupnull()



def insertfdbackupnull():
    fdbackup = c4d.BaseObject(c4d.Onull) #Assign the FDBackup null object to a name: fdbackup.
    doc.InsertObject(fdbackup) #inset the FDBackup null object in the current document.
    fdbackupcolor = c4d.Vector(0.875, 0.2461, 0.3203) #The color of the FDBackup null object
    fdbackup[c4d.ID_BASELIST_NAME]='FD Backup' #Rename the FDBackup null Object.
    fdbackup[c4d.ID_BASEOBJECT_VISIBILITY_EDITOR]=1 #Set the viewport visibility of the FDBackup null object to off.
    fdbackup[c4d.ID_BASEOBJECT_VISIBILITY_RENDER]=1 #Set the render visibility of the FDBackup null object to off.
    fdbackup[c4d.ID_BASEOBJECT_USECOLOR]=2 #Enable FDBackup null color.
    fdbackup[c4d.NULLOBJECT_ICONCOL]=True #Enable FDBackup null icon color.
    fdbackup[c4d.ID_BASEOBJECT_COLOR]= fdbackupcolor


def tonull():
    nullexist = doc.SearchObject('FD Backup') #check if the FDBackup null object exists.
    if nullexist != None: #if the FDBackup null object is foundo, then...
        fdnull = doc.SearchObject('FD Backup') #get the FDBackup null object.
        objselected = doc.GetActiveObject() #get the active selected object
        objselected.InsertUnder(fdnull) #insert under the FBDackup null object.

if __name__=='__main__':
    checknull()
    tonull()
    c4d.EventAdd()

Error returned when selected more than one object:

Quote

Traceback (most recent call last):
  File "'scriptmanager'", line 32, in <module>
  File "'scriptmanager'", line 28, in tonull
AttributeError: 'NoneType' object has no attribute 'InsertUnder'

 

 

I have tried to change the lines 27 and 28 to the following, but no success...

        fdnull = doc.SearchObject('FD Backup') #get the FDBackup null object.
        objselected = doc.GetActiveObject() #get the active selected object
        for obj in objselected: #for each object selected
            objselected.InsertUnder(fdnull) #insert under the FBDackup null object.

error returned:

Quote

Traceback (most recent call last):
File "'scriptmanager'", line 33, in <module>
File "'scriptmanager'", line 29, in tonull
AttributeError: 'list' object has no attribute 'InsertUnder'

 

 

Does anyone have any hint of what is happening and how to solve it ?

 

 

 

 

 

Share this post


Link to post
Share on other sites

I didn't read the whole code, but using GetActiveObject does only work when a single object is selected.

When multiple are selected it returns None.

You should be using the GetActiveObjects(flag)

 

Try following script with one and then two objects selected, and notice the difference.

 

import c4d

def main():

    obj = doc.GetActiveObject()
    print obj

    objs = doc.GetActiveObjects(flags=c4d.GETACTIVEOBJECTFLAGS_0)
    print objs
   

if __name__=='__main__':
    main()

 

Share this post


Link to post
Share on other sites
  • Topic Author
  •  

    14 hours ago, C4DS said:

    I didn't read the whole code, but using GetActiveObject does only work when a single object is selected.

    When multiple are selected it returns None.

    You should be using the GetActiveObjects(flag)

     

    Try following script with one and then two objects selected, and notice the difference.

     

    <code>

     

     

     

    Thank for your reply, C4DS, but it didn't work,

    Yesterday I tried the same thing you told me... using GetActiveObjects and using custom flags, but it gave the same error...

    The command InsertUnder seems to be not recognized anymore when I switch from GetActiveObject to GetActiveObjects..

     

    NySyac4.png

     

    Is correct to use objselected (active objects) before .InsertUnder or i'm making a sintaxe error ?

     

     

    Thanks again :-)

     

    Share this post


    Link to post
    Share on other sites

    The error you get in the console should help you understand what is going wrong.

    You are trying to call "InsertUnder" on the wrong object.

     

    When you used "GetActiveObject" the function returned you a c4d.BaseObject.

    By switching to "GetActiveObjects" the function then returns you a c4d.BaseList2D of c4d.BaseObject. The function "InsertUnder" is not available on the c4d.BaseList.

    As such, you need to iterate over each c4d.BaseObject in the returned list

    objs = doc.GetActiveObjects(flags=c4d.GETACTIVEOBJECTS_0)
    for obj in objs:
      obj.InsertUnder(pred)

    where "pred" is your null, or preferably the last child inside the null (so to provide appropriate ordered children inside the null)

    Share this post


    Link to post
    Share on other sites
  • Topic Author
  • 10 hours ago, C4DS said:

    The error you get in the console should help you understand what is going wrong.

    You are trying to call "InsertUnder" on the wrong object.

     

    When you used "GetActiveObject" the function returned you a c4d.BaseObject.

    By switching to "GetActiveObjects" the function then returns you a c4d.BaseList2D of c4d.BaseObject. The function "InsertUnder" is not available on the c4d.BaseList.

    As such, you need to iterate over each c4d.BaseObject in the returned list

    
    objs = doc.GetActiveObjects(flags=c4d.GETACTIVEOBJECTS_0)
    for obj in objs:
      obj.InsertUnder(pred)

    where "pred" is your null, or preferably the last child inside the null (so to provide appropriate ordered children inside the null)

     

    I didn't know I could use obj instead of the variable which get the active objects, worked very well!
    I just had to change the flags for GETACTIVEOBJECTFLAGS_CHILDREN, so the children of the selected objects are also grabbed !

     

    I need to get used to some terms used in python/c4d, like, c4d.  doc.  obj.  op. , etc...

     

    Thank you very much and sorry for bothering with that silly question xD

     

     

     

    Share this post


    Link to post
    Share on other sites
    59 minutes ago, thunderdoc said:

    I didn't know I could use obj instead of the variable which get the active objects

     I don't think obj has any special meaning (like doc, op etc) - it's more of a convention. Could have been

     

    for thing in mylist:
    	<perform task on thing>

     

    Share this post


    Link to post
    Share on other sites
  • Topic Author
  • On 11/05/2018 at 1:55 PM, jed said:

     I don't think obj has any special meaning (like doc, op etc) - it's more of a convention. Could have been

     

    
    for thing in mylist:
    	<perform task on thing>

     

    ah, yes, I learned this recently!

    for obj in mylist...  this assign a variable to each object in the list, obj can be any name :-)

    thanks!

     

    Share this post


    Link to post
    Share on other sites

    Join the conversation

    You can post now and register later. If you have an account, sign in now to post with your account.
    Note: Your post will require moderator approval before it will be visible.

    Guest
    Reply to this topic...

    ×   Pasted as rich text.   Paste as plain text instead

      Only 75 emoji are allowed.

    ×   Your link has been automatically embedded.   Display as a link instead

    ×   Your previous content has been restored.   Clear editor

    ×   You cannot paste images directly. Upload or insert images from URL.

    Sign in to follow this  

    ×
    ×
    • Create New...