"""
HB_ReProject V1.1

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

Name-US: HB_ReProject/SlideMode Off
Description-US: Reproject the current Retopoobject [CTRL: Enable Live update (slower)]

Usage:
Use this Script frequently when you do retopo. This will project the current retopomesh to the Highresmesh. When you hold CTRL
it will keep the shrinkwrap active. The Mesh will be projected constantly than.

Video Tutorials:
https://youtu.be/Ki6I9sRdeUU?t=53m16s
https://youtu.be/Xo1qMmVSQ-Q?t=3m59s

ChangeLog:
11/5/2015 v1.1
- Correction Deformer OFF
- Slidemode Exit


6/11/2015 v1.0
Release Version

"""

import c4d
from c4d import gui, utils


def deletetags(obj): # Scan Tags on Object
    
    n       = 1 
    
    tags    = obj.GetTags()

    for tag in tags:
        if not tag: continue
        tagtype = tag.GetType()
        #count   = checktype(tags).count(tagtype)       
        
        
        if tagtype==c4d.Tdisplay and tag.GetName()=="TEMPDISPLAY":
            doc.AddUndo(c4d.UNDOTYPE_DELETE, tag)
            tag.Remove()
            c4d.EventAdd()


def main():
    doc.StartUndo()
    if not doc.GetActiveObject():
        gui.MessageDialog("Select Retopo Mesh!")
        return
    
    selobj=doc.GetActiveObject()

    if not selobj.GetDown():
        gui.MessageDialog("No RetopoProjector found!")
        return
    
    if selobj.GetDown().GetName() == "HB_RetopoProjector" or selobj.GetDown().GetName() == "HB_SlideDeformer":

        RetopoProjector=selobj.GetDown()
        doc.AddUndo(c4d.UNDOTYPE_CHANGE_SMALL, RetopoProjector)
        RetopoProjector[c4d.ID_BASEOBJECT_GENERATOR_FLAG]=True
    else:
  
        
        gui.MessageDialog("No RetopoProjector found!")
        return
    
    
    if selobj.GetDown().GetName() == "HB_SlideDeformer":
        SlideMode=True
    else:
        SlideMode=False
        
        
    selobjpos=selobj.GetMg()
    
    CSsettings = c4d.BaseContainer()                 
    NewObj=utils.SendModelingCommand(command = c4d.MCOMMAND_CURRENTSTATETOOBJECT,
                            list = [selobj],
                            mode = c4d.MODELINGCOMMANDMODE_EDGESELECTION,
                            bc = CSsettings,
                            doc = doc,
                            )
                            
    
    if NewObj[0].GetDown():
        NewObjChild=NewObj[0].GetDown()
        NewObjChild.InsertAfter(selobj)
        doc.AddUndo(c4d.UNDOTYPE_NEW, NewObjChild)
    else:
        NewObjChild=NewObj[0]
        NewObjChild.InsertAfter(selobj)
        doc.AddUndo(c4d.UNDOTYPE_NEW, NewObjChild)
    
    doc.AddUndo(c4d.UNDOTYPE_DELETE, selobj)
    selobj.Remove()
    
    
    if SlideMode == False:
        
        RetopoProjector.InsertUnder(NewObjChild)
        doc.AddUndo(c4d.UNDOTYPE_NEW, RetopoProjector)
        
        doc.AddUndo(c4d.UNDOTYPE_CHANGE_SMALL, RetopoProjector)
        RetopoProjector[c4d.ID_BASEOBJECT_VISIBILITY_EDITOR]=1
        
        bc = c4d.BaseContainer()
        c4d.gui.GetInputState(c4d.BFM_INPUT_KEYBOARD,c4d.BFM_INPUT_CHANNEL,bc)
        
        
        if bc[c4d.BFM_INPUT_QUALIFIER] ==2 :
            #doc.AddUndo(c4d.UNDOTYPE_CHANGE_SMALL, RetopoProjector)
            RetopoProjector[c4d.ID_BASEOBJECT_GENERATOR_FLAG]=True
        else:
            #doc.AddUndo(c4d.UNDOTYPE_CHANGE_SMALL, RetopoProjector)
            RetopoProjector[c4d.ID_BASEOBJECT_GENERATOR_FLAG]=False
        

    doc.AddUndo(c4d.UNDOTYPE_BITS, NewObjChild)
    NewObjChild.SetBit(c4d.BIT_ACTIVE)
    
    doc.AddUndo(c4d.UNDOTYPE_CHANGE, NewObjChild)
    NewObjChild.SetMg(selobjpos)
    
    if SlideMode == True:
          
        deletetags(NewObjChild)
        
        SlideProxy=doc.SearchObject("HB_SlideProxy")
        doc.AddUndo(c4d.UNDOTYPE_DELETE, SlideProxy)
        SlideProxy.Remove()
    
    c4d.EventAdd()
    doc.EndUndo()



if __name__=='__main__':
    main()
