Cycle through Objects return only Nulls with polys

On 11/02/2014 at 01:45, xxxxxxxx wrote:

Hello everyone,

I need to cycle through a Object tree which consists of Null-Objects and Poly-Objects, nested.

Afterwards the selected "Null" will be merged to one Poly-Object.
But I need only the "deepest" Null Object and want to leave the Nulls in Nulls untouched.

Null-1
-Null-2
--Null-3 <- this should be returned
---Poly
---Poly
---Poly
--Null-4 <- this should be returned
---Poly
---Poly
---Poly
-Null-5
--Null-6 <- this should be returned
---Poly
---Poly
---Poly

Standard Python cycle - how to modify?

  
def GetNextObject(op) :       
    if not op: return   
    if op.GetDown() : return op.GetDown()   
    while op.GetUp() and not op.GetNext() :   
        op = op.GetUp()   
    return op.GetNext()

thanks in advance for any help.
mogh

On 11/02/2014 at 07:17, xxxxxxxx wrote:

Use recursion. You can make the function return True if a Null Object was found in the hierarchy
and False if not. If you get False from a recursive call and are currently at a Null Object, you've found
the Null-Object at the lowest level.

function find_lowest_nullobjects(current, result_list) returns bool
    has_nullobject = false
  
    for each child in current
        has_nullobject = find_lowest_nullobjects(child, result_list)
  
        if has_nullobject is true
            break loop
        endif
    endfor
  
    if current is "Null Object" and has_nullobject is false
        add current to result_list
    endif
  
    return current is "Null Object"
endfunction

-Niklas

Edit: Fixed return value of function in pseudo-code

On 12/02/2014 at 00:27, xxxxxxxx wrote:

Thanks Niklas,

I have trouble reading your code, and it hast lists which I still have trouble implementing into my scripts, guess i need a few weeks to understand what you gave me here.

thanks for your time.

this is the code i want to update to goo deep instead of only ging flat:

Edit_ removed code hence it doesn't contribute to the discussion.

kind regards mogh

On 17/02/2014 at 06:35, xxxxxxxx wrote:

This is my coding so far ...

def GetNextObject(op) :       
    if not op: return   
    if op.GetDown() : return op.GetDown()   
    while op.GetUp() and not op.GetNext() :   
        op = op.GetUp()   
    return op.GetNext()   
  
def find_lowest_nullobjects(op, nullobj_list) :   
    has_nullobject = False   
    all_list = list()          
    opchildren = op.GetChildren()   
       
    for child in opchildren:   
        has_nullobject = find_lowest_nullobjects(child, nullobj_list)   
        if has_nullobject is True:   
            break   
       
    if op.GetType() == 5140 and has_nullobject == False:   
        nullobj_list.append(op)   
       
    while op:          
        all_list.append(op)   
        op = GetNextObject(op)   
    return {'all_objects_list' : all_list, 'null_obj_list' : nullobj_list }

On 17/02/2014 at 08:02, xxxxxxxx wrote:

Give this code a shot.
All of the logic occurs in one single method rather than using several methods.
*Make sure you test it thoroughly though. Because I just whipped it up in 5 minutes. And I haven't fully tested it in battle. :wink:

#This code searches for the last Null object in each tree branch(But not single Null objects)  
#Then stores them in a list array  
  
import c4d  
  
nulls = []  
  
def SearchOM(op) :  
    
  while(op) :  
      if op.GetType()==c4d.Onull and not op.GetDown() and op.GetUp() :   
          nulls.append(op)  
          break  
      SearchOM(op.GetDown())  
      op = op.GetNext()  
  
def main() :  
  SearchOM(doc.GetFirstObject())  
  print nulls  
  
if __name__=='__main__':  
  main()

-ScottA

On 18/02/2014 at 01:26, xxxxxxxx wrote:

Thanks ScottA:

I did remove the "NOT" in your if and i get some Nulls in my list but it discards nulls in the same level.

-Null
--null-a
--null-b
-Null
--null-d
--null-e

In this case it returns (a, d)
any ideas?
kind regards

On 18/02/2014 at 14:12, xxxxxxxx wrote:

This turned out to be  lot harder than I thought it would be.
Targeting the first Null child object of each tree branch is fairly simple.
But the hard part is trying to target the first null object inside of any inner tree branches.
Using break the way I did prevented me from checking those sub branches.

After a lot of trial and error. I came up with this.
It should target the first Null object (even the sub branches of main branches) and put them into a list:

import c4d  
  
nulls = []  
  
def SearchOM(op) :  
    
  while(op) :        
  
    if op.GetUp() :  
        parent = op.GetUp()  
        firstChild = parent.GetDown()  
        #print firstChild.GetName()  
  
        if firstChild.GetType()==c4d.Onull:  
            #print firstChild.GetName()   
            if not firstChild in nulls: nulls.append(firstChild)   
            if firstChild.GetDown() : break                
       
    SearchOM(op.GetDown())  
    op = op.GetNext()        
  
      
def main() :  
  firstObj = doc.GetFirstObject()  
  SearchOM(firstObj)  
  print nulls  
    
  c4d.EventAdd()  
  
if __name__=='__main__':  
  main()

I'm not sure if I got it all correct.
Dealing with those sub branches is pretty tricky stuff.

-ScottA