"""
HB_SendToRenderQueue V1.0

Last Modified: 6/28/2017
Works with CINEMA 4D R16.050 and up.

Copyright: Holger Biebrach, www.c4dstuff.com

Name-US: HB_SendToRenderQueue

Description-US: Send incremental version to Renderqueue [CTRL: Setup Options, SHIFT: Render Preview Range, ALT: Render Half Resolution ]

Usage:
The Script will create a Folderstructure in you Scenefolder. It saves an Incremental Version of your current Scene and puts 
it on the Renderqueue. The Queue will instantly start rendering. 

CTRL-Click: This will open the Setip for the Script. It will ask you if you use Teamrender and if you use Global Texture Paths.
I recommend to use Global Texture Paths as the Script will move the File to another folder and relative Paths will break. 
If you want to use relative Paths choose "NO". The Script will now save all Files into the Same folder as your Scene.

Tip: With the Texture-Manager you can change all Texture paths to Global or Local (relative).

The Last Dialog ask you how many Seconds you want a Frame to Render.
Note: This only works with Progessive Rendermode.
Note: The actual Rendertime can differ as preparing times can take longer

Simple Click: Renders Current Frame
SHIFT-Click: Renders Preview Range
ALT-Click: Renders Half Resolution
SHFT & ALT-Click: Render HalfRes and Preview Range


Video Tutorial:
https://youtu.be/G9XVCcOe6jQ?t=7m5s

ChangeLog:

6/28/2017 v1.0
Release Version

"""

import os
import re
pattern = re.compile(r'(?:[^\d]*(\d+)[^\d]*)+')

import c4d
from c4d import gui
from c4d import documents
from c4d import storage



def main():


    
    doc = documents.GetActiveDocument()
    fileLocation = os.path.join(doc.GetDocumentPath(), doc.GetDocumentName())
    rdMP= doc.GetActiveRenderData()
    rd= doc.GetActiveRenderData()
    OldRenderWidth= rd[c4d.RDATA_XRES]
    OldRenderHeight= rd[c4d.RDATA_YRES]
    HalfRenderWidth = OldRenderWidth/2
    HalfRenderHeight = OldRenderHeight/2
    
    vp = rd.GetFirstVideoPost()
    while vp:
        if vp.GetType() == c4d.VPxmbsampler:    #If type is a Physical render PostEffect
            #vp[c4d.VP_XMB_RAYTRACING_SAMPLER] = 2
            OldRendertime = vp[c4d.VP_XMB_RAYTRACING_INTERACTIVE_TIME]
            
        vp = vp.GetNext()

    STOREFILE_1 = 9328442386023487
    
    StoredFile_BC = c4d.BaseContainer()
    
    bc = c4d.BaseContainer()
    
    if c4d.gui.GetInputState(c4d.BFM_INPUT_KEYBOARD,c4d.BFM_INPUT_CHANNEL,bc):      # Modifier Key Pressed?

        if bc[c4d.BFM_INPUT_QUALIFIER] == 0 or bc[c4d.BFM_INPUT_QUALIFIER] == 4:     # No Modifier or ALT
            
            if not (c4d.plugins.GetWorldPluginData(STOREFILE_1)):
                gui.MessageDialog("No Settings found: Please CTRL-Click on Script-Icon to run Setup")
                return
             
             
            StoredFile_BC = c4d.plugins.GetWorldPluginData(STOREFILE_1)
            TEAMRENDER = StoredFile_BC.GetData(1)
            GlobalPaths = StoredFile_BC.GetData(2)
            Rendertime = StoredFile_BC.GetData(3)
            
            Sequence = False
            
            vp = rd.GetFirstVideoPost()
            while vp:
                if vp.GetType() == c4d.VPxmbsampler:    #If type is a Physical render PostEffect
                    if vp[c4d.VP_XMB_RAYTRACING_SAMPLER] == 2 and vp[c4d.VP_XMB_RAYTRACING_INTERACTIVE_MODE]==2: #is progresive mode on?
                        vp[c4d.VP_XMB_RAYTRACING_INTERACTIVE_TIME] = float(Rendertime)/60
                        
                vp = vp.GetNext()
             
            if bc[c4d.BFM_INPUT_QUALIFIER] == 4 : #ALT
        
                rd[c4d.RDATA_XRES]=HalfRenderWidth
                rd[c4d.RDATA_YRES]=HalfRenderHeight
                

            rd[c4d.RDATA_FRAMESEQUENCE]=1 # Current Frame
    

            
        if bc[c4d.BFM_INPUT_QUALIFIER] == 1 or bc[c4d.BFM_INPUT_QUALIFIER] == 5: # SHIFT or ALTSHIFT
            StoredFile_BC = c4d.plugins.GetWorldPluginData(STOREFILE_1)
            TEAMRENDER = StoredFile_BC.GetData(1)
            GlobalPaths = StoredFile_BC.GetData(2)
            Rendertime = StoredFile_BC.GetData(3)
            Sequence =True
           
            rd[c4d.RDATA_FRAMESEQUENCE]=3 # Preview Range
            if bc[c4d.BFM_INPUT_QUALIFIER] == 5 : #ALT + SHIFT

        
                rd[c4d.RDATA_XRES] = HalfRenderWidth
                rd[c4d.RDATA_YRES] = HalfRenderHeight
                vp = rd.GetFirstVideoPost()
                while vp:
                    if vp.GetType() == c4d.VPxmbsampler:    #If type is a Physical render PostEffect
                        if vp[c4d.VP_XMB_RAYTRACING_SAMPLER] == 2 and vp[c4d.VP_XMB_RAYTRACING_INTERACTIVE_MODE]==2: #is progresive mode on?
                            vp[c4d.VP_XMB_RAYTRACING_INTERACTIVE_TIME] = float(Rendertime)/60
                           
                    vp = vp.GetNext()



    if bc[c4d.BFM_INPUT_QUALIFIER] == 2 : #CTRL (Settup options)

        
        StoredFile_BC.SetData(1, gui.QuestionDialog("Use TEAMRENDER?"))
        StoredFile_BC.SetData(2, gui.QuestionDialog("Use Global Paths?"))
        StoredFile_BC.SetData(3, gui.InputDialog("How many Seconds per Frame?"))
        c4d.plugins.SetWorldPluginData(STOREFILE_1, StoredFile_BC)
        
        return





    #remember old outputpath
    oldPath=rd[c4d.RDATA_PATH]
    oldPathMP=rd[c4d.RDATA_MULTIPASS_FILENAME]

    #set Framerange
    rd = doc.GetActiveRenderData()
    oldFRange = rd[c4d.RDATA_FRAMESEQUENCE]
    
    


    #The Save Incremental code was kindly contributed by Jan Frishmuth (MAXON Developer)
    
    # assume document is unsaved if extension is missing
    if len(fileLocation) < 4 or not fileLocation.lower()[-4:] == ".c4d": 
      fileLocation = storage.SaveDialog(title="Save", force_suffix="c4d") 
      # user canceled
      if fileLocation is None:
        return 
    
    # pure path and file name   
    filePath = os.path.dirname(fileLocation)
    
    
    #Make ResultsFolder STILL
    
    
    if Sequence == False:

        #CreateFolder = True #NEED to build Altmodifier Check
        
        if GlobalPaths == True:
            
            RegionKingFolder = os.path.join(filePath, 'HB_Results')
            if not os.path.exists(RegionKingFolder):
                try:
                    os.makedirs(RegionKingFolder)
                except:
                    return
            
            StillFolder = os.path.join(RegionKingFolder, 'Stills')
            if not os.path.exists(StillFolder):
                try:
                    os.makedirs(StillFolder)
                except:
                    return
      
    
        
        
        fileName = os.path.splitext(os.path.basename(fileLocation))[0]
        
        # add enumeration if necessary
        if not any(char.isdigit() for char in fileName):
          fileName += "_0001"
        
        # increment filename
        while True:
            
          if GlobalPaths == True:
               
           newFile = os.path.join(StillFolder, fileName + "_HB_Still.c4d")
           
          else:
              newFile = os.path.join(filePath, fileName + "_HB.c4d")
          
          # skip increment if filename available
          if not os.path.exists(newFile):
            break
          # increment
          match = pattern.search(fileName)
          next = str(int(match.group(1)) + 1)
          start, end = match.span(1)
          fileName = fileName[:max(end - len(next), start)] + next + fileName[end:]
          
          
          
        #Renderoutputpath
        Bd = doc.GetRenderBaseDraw()
        Cam = Bd.GetSceneCamera(doc)
        CamName = Cam.GetName()
        
        rdMP[c4d.RDATA_MULTIPASS_FILENAME]= fileName +"_"+CamName
        rd[c4d.RDATA_PATH]= fileName +"_HB_"+CamName

        
        if not c4d.documents.SaveDocument(doc, newFile, c4d.SAVEDOCUMENTFLAGS_AUTOSAVE, c4d.FORMAT_C4DEXPORT):
          c4d.gui.MessageDialog("Error saving '%s'" % newFile)
      
        
    
     #Make ResultsFolder (SEQUENCE)
    if Sequence == True:
        
        

        if GlobalPaths == True:
            
            RegionKingFolder = os.path.join(filePath, 'HB_Results')
            if not os.path.exists(RegionKingFolder):
                try:
                    os.makedirs(RegionKingFolder)
                except:
                    return
      
            SequencesFolder = os.path.join(RegionKingFolder, 'Sequences')
            if not os.path.exists(SequencesFolder):
                try:
                    os.makedirs(SequencesFolder)
                except:
                    return
    
        
        
        
        
        fileName = os.path.splitext(os.path.basename(fileLocation))[0]
        
        # add enumeration if necessary
        if not any(char.isdigit() for char in fileName):
          fileName += "_0001"
        
        # increment filename
        while True:
            
          if GlobalPaths == True:
            newFile = os.path.join(SequencesFolder, fileName + "_HB_SEQ.c4d")
              
            
            
           
          else:
              newFile = os.path.join(filePath, fileName + "_HB.c4d")
          
          # skip increment if filename available
          if not os.path.exists(newFile):
            break
          # increment
          match = pattern.search(fileName)
          next = str(int(match.group(1)) + 1)
          start, end = match.span(1)
          fileName = fileName[:max(end - len(next), start)] + next + fileName[end:]
        
        
        
        
        
    
        
        if GlobalPaths == True:
            RegionKingSeqFolder = os.path.join(SequencesFolder, fileName)
            if not os.path.exists(RegionKingSeqFolder):
                try:
                    os.makedirs(RegionKingSeqFolder)
                except:
                    return
        
            
            newSeqPath = os.path.join(RegionKingSeqFolder, fileName + "_HB_SEQ.c4d")
            
            
        else:
            RegionKingSeqFolder = os.path.join(filePath, fileName + "_HB_SEQ")
            if not os.path.exists(RegionKingSeqFolder):
                try:
                    os.makedirs(RegionKingSeqFolder)
                except:
                    return
        
            
            newSeqPath = os.path.join(RegionKingSeqFolder, fileName + "_HB_SEQ.c4d")
            
            
        

    
    # save
    
        
        #Renderoutputpath
        Bd = doc.GetRenderBaseDraw()
        Cam = Bd.GetSceneCamera(doc)
        CamName = Cam.GetName()
        
        rdMP[c4d.RDATA_MULTIPASS_FILENAME]= newSeqPath +"_"+CamName
        rd[c4d.RDATA_PATH]= newSeqPath +"_"+CamName
        
        
        if not c4d.documents.SaveDocument(doc, newFile, c4d.SAVEDOCUMENTFLAGS_AUTOSAVE, c4d.FORMAT_C4DEXPORT):
          c4d.gui.MessageDialog("Error saving '%s'" % newFile)
      
        

    
    #Add to Renderqueue
    BR= c4d.documents.GetBatchRender()
    count = BR.GetElementCount()
    BR.AddFile(newFile,count)
    BR.EnableElement(count, True)
    if TEAMRENDER:
    
        BR.SetUseNet(count, True)
    
    

    if not (BR.IsRendering()):
        BR.SetRendering(2)
    
    
    
    #apply old Rendersettings
    
    rdMP[c4d.RDATA_MULTIPASS_FILENAME]= oldPathMP
    rd[c4d.RDATA_PATH]= oldPath
    rd[c4d.RDATA_FRAMESEQUENCE]=oldFRange
    rd[c4d.RDATA_XRES]= OldRenderWidth
    rd[c4d.RDATA_YRES]= OldRenderHeight
    
    vp = rd.GetFirstVideoPost()
    while vp:
        if vp.GetType() == c4d.VPxmbsampler:    #If type is a Physical render PostEffect
            if vp[c4d.VP_XMB_RAYTRACING_SAMPLER] == 2 and vp[c4d.VP_XMB_RAYTRACING_INTERACTIVE_MODE]==2: #is progresive mode on?
                vp[c4d.VP_XMB_RAYTRACING_INTERACTIVE_TIME] = OldRendertime
               
        vp = vp.GetNext()



if __name__=='__main__':
    main()
