"""
HB_SelectSame V1.1

Last Modified: 1/1/2016
Works with CINEMA 4D R16.050 and up.
Copyright: Holger Biebrach, www.c4dstuff.com

Name-US: HB_SelectSame
Description-US: Selects same type of Objects as the current selected [SHIFT: Select Same type and same Pointcount, CTRL: Select all objects with same Pointcount]

Usage:
Select one or more Objects. When you run the script the Object and its Childs will be isolated. Also the Camera frames the Object. The same works
for Polygonselections.

Video Tutorial:
https://youtu.be/Ki6I9sRdeUU?t=35m54s

Name-DE: HB_SelectSame
Description-DE: Selektiert Objekte des selben Typs [SHIFT: Select Same type and same Pointcount, CTRL: Select all objects with same Pointcount]

ChangeLog:
1/1/2016 V1.1
- Bugfixes

6/11/2015 Release Version

"""


import c4d
from  c4d import gui 

########   TEMP TRASH   #########
def GetNextObject(op,root):

    op.SetBit(c4d.BIT_ACTIVE) 
    if op==None:
        return None
  
    if op.GetDown():
        return op.GetDown()
  
    while not op.GetNext() and op!=root and op.GetUp()!=root and op.GetUp():
        op = op.GetUp()

    if op !=root:
        return op.GetNext()
    

def IterateChildren(obj):

    root = obj
    while obj:
        if obj.GetDown():
            obj = GetNextObject(obj,root)
        
    if obj is None:
        return
    
    return


####### WALKER  #############
def walker(obj):
    if not obj: return

    elif obj.GetDown():
        return obj.GetDown()
    while obj.GetUp() and not obj.GetNext():
        obj = obj.GetUp()
    return obj.GetNext()


########  POINTCOUNT  #########
def ActivePointCount(obj):
    
    if obj.GetType()==5100 or obj.GetType()==c4d.Ospline:
        ActiveObjectPointCount=obj.GetPointCount()
    else:    
    
        ActiveObjectPointCount=PointCountGenerator(obj)

    return ActiveObjectPointCount


####### POINTCOUNT IF GENERATOR   ################

def PointCountGenerator(obj):

    settings = c4d.BaseContainer()
    settings[c4d.MDATA_CURRENTSTATETOOBJECT_INHERITANCE] = True
    obj_info = obj.GetInfo()
    is_generator = obj_info & c4d.OBJECT_GENERATOR
    

    
    point_obj = c4d.utils.SendModelingCommand(command = c4d.MCOMMAND_CURRENTSTATETOOBJECT, list = [obj.GetClone()], mode = c4d.MODELINGCOMMANDMODE_ALL, bc=settings, doc = doc)
    
    
    if point_obj[0].GetType()== c4d.Onull:
        pointc= 0
        return pointc
    
    if point_obj[0].GetType()== c4d.Opolygon or point_obj[0].GetType()== c4d.Ospline:
        return point_obj[0].GetPointCount()
    else:
        pointc= 0
        return pointc
    
    

         
#######################     SELECT SAME    #######################


def SelectSame(obj, selObj):
    global ACTIVEPOINTCOUNT, MODIFIERKEY
    
    selList = []
    while obj:
       
        
        objpointcount=PointCountGenerator(obj)
        

           
        if MODIFIERKEY == 0:   # No Modifierkey
            if obj.GetType() == selObj.GetType() :
                selList.append(obj)
                obj = walker(obj)
                #print "same selected"
                continue
            
        
        if MODIFIERKEY == 1:    # SHIFT Click
            if objpointcount == ACTIVEPOINTCOUNT and obj.GetType()== selObj.GetType():
                selList.append(obj)
                obj = walker(obj)
                continue
                
        if MODIFIERKEY == 2: # CTRL
            if objpointcount == ACTIVEPOINTCOUNT and objpointcount is not 0:
                selList.append(obj)
                obj = walker(obj)
                continue
  
        
        obj = walker(obj)
        
    for empty in selList:
        
        empty.SetBit(c4d.BIT_ACTIVE)



#############  MAIN    ################################
    
def main():
    global ACTIVEPOINTCOUNT, MODIFIERKEY
    doc.StartUndo()
    
    selObj = doc.GetActiveObject()
    FirstObj = doc.GetFirstObject()
    if not selObj:
        gui.MessageDialog("Please select one Object")
        return
    ACTIVEPOINTCOUNT = ActivePointCount(selObj)
    
    bc = c4d.BaseContainer()
    c4d.gui.GetInputState(c4d.BFM_INPUT_KEYBOARD,c4d.BFM_INPUT_CHANNEL,bc)
    MODIFIERKEY=bc[c4d.BFM_INPUT_QUALIFIER]
     
    SelectSame(FirstObj, selObj)   
    c4d.EventAdd()    
    
    
    doc.EndUndo()
    
    
if __name__=='__main__':
    main()

