"""
HB_OverwriteMaterial V1.2

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

Name-US: HB_OverwriteMaterial
Description-US: Overwrites Selected Objects with selected Material [ALT: Deletes OverwriteMaterials, SHIFT: Apply Modo UV Material]

If no object is selected the script will apply the selected Material to all objects of the scene!!
If no material is selected the Script will create a randomly colored Material.
If you want to get rid of the all Overwritematerial you need to deselect all objects (or select all objects) and run the script while holding „alt“.

Video Tutorials:
https://youtu.be/4pMXC7sY6rs

v2.2:
https://youtu.be/G9XVCcOe6jQ?t=3m40s




Name-DE: HB_OverwriteMaterial
Description-DE: Überschreibt das Material aller selektierter Objekte [ALT: Löscht Überschreibungen]

ChangeLog:
1/1/2016 v1.0 Release Version

10/26/2016 v1.1 
- Loads Modo Material if present in Contentbrowser

6/28/2017 v1.2
- Modo UV Material (by holding SHIFT)

"""


import c4d
from c4d import gui, documents
from random import randint
 
 
def createMaterial():
     newmat = c4d.BaseMaterial(5703)
     doc.InsertMaterial(newmat)
     doc.AddUndo(c4d.UNDOTYPE_NEW, newmat)
     newmat.SetName("HB_OVERWRITEMATERIAL")
     newmat[c4d.MATERIAL_COLOR_COLOR]=randomColor()
     return newmat

def randomColor():
    r = randint(0,255) / 256.0    
    g = randint(0,255) / 256.0    
    b = randint(0,255) / 256.0 
    color = c4d.Vector(r,g,b)
    return color



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()



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


def GetAllObjects(doc):
    

    obj = doc.GetFirstObject()

    liste = list()
    liste.append(obj)
    while obj:
        obj = walker(obj)
        liste.append(obj)
    return liste




def checktype(tags): # List of current Tag Types on Object
    checktypes = []
    for tag in tags:
        checktypes.append(tag.GetType())
    return checktypes



def scantags(obj): # Scan Tags on Object

    #n       = 1 
    #print obj.GetName()
    tags = []
    tags = obj.GetTags()
    

    for tag in tags:
        if not tag: continue
        tagtype = tag.GetType()
        count   = checktype(tags).count(tagtype)       
        #print tagtype
        
        if tagtype==5616:
            doc.AddUndo(c4d.UNDOTYPE_DELETE, tag)
            if tag[c4d.ID_BASELIST_NAME] == "HB_OVERWRITEMATERIAL":
                tag.Remove()
         
            c4d.EventAdd()

            
            


def main():  
  
    doc.StartUndo()
    
    
    
    bc = c4d.BaseContainer()
    if c4d.gui.GetInputState(c4d.BFM_INPUT_KEYBOARD,c4d.BFM_INPUT_CHANNEL,bc):

        print bc[c4d.BFM_INPUT_QUALIFIER]
   
        if bc[c4d.BFM_INPUT_QUALIFIER] ==0 or bc[c4d.BFM_INPUT_QUALIFIER] ==1: # Create Overwritematerial and apply (shift for UV material)
            
            selmat=doc.GetActiveMaterial()
            
            if not selmat:
                MatWasSelected=False
                
                if bc[c4d.BFM_INPUT_QUALIFIER] ==0:
                
                    if not doc.GetFirstMaterial():
                        
                        
                        if c4d.documents.MergeDocument(doc,"preset://HB_RealtimeUtilityShaders.lib4d/modo",2):
                            newmat=doc.GetFirstMaterial()
                            
                        else:
                            newmat=createMaterial()
                           
                        
                        #c4d.EventAdd()
                  
                    if doc.GetFirstMaterial().GetName() != "modo":
                        
                        if c4d.documents.MergeDocument(doc,"preset://HB_RealtimeUtilityShaders.lib4d/modo",2):
                            newmat=doc.GetFirstMaterial()
                            
                            c4d.EventAdd()
     
                            
                    else:
                        if doc.GetFirstMaterial().GetName() == "modo":
                            newmat=doc.GetFirstMaterial()
                        
                        if doc.GetFirstMaterial().GetName() != "HB_OVERWRITEMATERIAL" and doc.GetFirstMaterial().GetName() != "modo":
                            newmat=createMaterial()
                        
                    newmat.SetBit(c4d.BIT_ACTIVE) 
                
                ######SHIFT
                
                if bc[c4d.BFM_INPUT_QUALIFIER] ==1:
                
                    if not doc.GetFirstMaterial():
                        
                        
                        if c4d.documents.MergeDocument(doc,"preset://HB_RealtimeUtilityShaders.lib4d/modo_UV",2):
                            newmat=doc.GetFirstMaterial()
                            
                        else:
                            newmat=createMaterial()
                           
                        
                        #c4d.EventAdd()
                  
                    if doc.GetFirstMaterial().GetName() != "modo_UV":
                        
                        if c4d.documents.MergeDocument(doc,"preset://HB_RealtimeUtilityShaders.lib4d/modo_UV",2):
                            newmat=doc.GetFirstMaterial()
                            
                            c4d.EventAdd()
     
                            
                    else:
                        if doc.GetFirstMaterial().GetName() == "modo_UV":
                            newmat=doc.GetFirstMaterial()
                        
                        if doc.GetFirstMaterial().GetName() != "HB_OVERWRITEMATERIAL" and doc.GetFirstMaterial().GetName() != "modo_UV":
                            newmat=createMaterial()
                        
                    newmat.SetBit(c4d.BIT_ACTIVE) 
               
                
                

            else:
                MatWasSelected=True
                
 
            if len(doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_CHILDREN)): #Objects are selected
                ObjectWasSelected=True
               
                c4d.CallCommand(12169) # Apply
                
            else: #No Objects selected.
                
                ObjectWasSelected=False
                c4d.CallCommand(100004766) # Select All
                c4d.CallCommand(12169) # Apply
                
            mattags=doc.GetActiveTags()
            
            for mattag in mattags:
        
                mattag[c4d.ID_BASELIST_NAME] = "HB_OVERWRITEMATERIAL"
               
        
            if ObjectWasSelected==False:
                c4d.CallCommand(100004767) # Deselect All Objects
            
            if MatWasSelected==False:
                c4d.CallCommand(300001026) # Deselect All Materials 
        
        
        if bc[c4d.BFM_INPUT_QUALIFIER] ==4 : # ALT

            #tagtypes = []             
            
        
            if len(doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_CHILDREN)): #Objects are selected
                
                activeobjects = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_CHILDREN)    
            else: #No Objects selected. Do it on all Objects!
                
                activeobjects = GetAllObjects(doc)


            for obj in activeobjects:

                scantags(obj)
    
    doc.EndUndo()


if __name__=='__main__':
    main()
    c4d.EventAdd()