"""
HB_Rotator V1.0

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

Name-US: HB_Rotator
Description-US: Rotates Objects 90 Degree or Resets PSR [SHIFT-CLICK: Rotate Pitch, CTRL-CLICK: Rotate Banking, CTRL+SHIFT: Reset Rotations, CTRL+SHIFT+ALT: Reset Position and Rotations]

Usage:
Select one or more Objects. When you run the Script all Objects will locally rotate 90 Degree in Heading (H-Axis). 
Use Shift or Ctrl modifiers to Rotate P and B Axsis. The ALT-Key in combination will always reverse the Rotation to the Negative direction.
CTRL+SHIFT Click will reset all Rotations to Zero. CTRL+SHIFT+ALT will reset Position and Rotation to Zero. 

Video Tutorial:
https://youtu.be/eEcAttV56kE?t=24m31s

Name-DE: HB_Rotator
Description-DE: Rotiere Objekte um 90 Grad oder setze Rotationen zurück [SHIFT-CLICK: Rotate Pitch, CTRL-CLICK: Rotate Banking, CTRL+SHIFT: Reset Rotations, CTRL+SHIFT+ALT: Reset Position and Rotations]

ChangeLog:
6/11/2015 Release Version

"""

import c4d, math
from c4d import gui


def GetLocalRotation(obj):
    return obj.GetRelRot()

#Definitons Set Rotation    
def SetLocalRotation_H_Positive(obj, rot):
    return obj.SetRelRot(c4d.Vector(rot.x+math.pi/2,rot.y,rot.z))

def SetLocalRotation_H_Negative(obj, rot):
    return obj.SetRelRot(c4d.Vector(rot.x-math.pi/2,rot.y,rot.z))

def SetLocalRotation_P_Positive(obj, rot):
    return obj.SetRelRot(c4d.Vector(rot.x,rot.y+math.pi/2,rot.z))

def SetLocalRotation_P_Negative(obj, rot):
    return obj.SetRelRot(c4d.Vector(rot.x,rot.y-math.pi/2,rot.z))

def SetLocalRotation_B_Positive(obj, rot):
    return obj.SetRelRot(c4d.Vector(rot.x,rot.y,rot.z+math.pi/2))

def SetLocalRotation_B_Negative(obj, rot):
    return obj.SetRelRot(c4d.Vector(rot.x,rot.y,rot.z-math.pi/2))

def SetLocalRotation_NULL(obj):
    return obj.SetRelRot(c4d.Vector(0,0,0))

def SetLocalPR_NULL(obj):
    obj.SetRelRot(c4d.Vector(0,0,0))
    obj.SetRelPos(c4d.Vector(0,0,0))
    return obj


def RotateH_Positive(objList):
    for obj in objList:
        
        doc.AddUndo(c4d.UNDOTYPE_CHANGE, obj)
        SetLocalRotation_H_Positive(obj, GetLocalRotation(obj))
        c4d.EventAdd()

def RotateH_Negative(objList):
    for obj in objList:
        if not obj: print "no Object"
        doc.AddUndo(c4d.UNDOTYPE_CHANGE, obj)
        SetLocalRotation_H_Negative(obj, GetLocalRotation(obj))
        c4d.EventAdd()        
      
def RotateP_Positive(objList):
    for obj in objList:
        doc.AddUndo(c4d.UNDOTYPE_CHANGE, obj)
        SetLocalRotation_P_Positive(obj, GetLocalRotation(obj))
        c4d.EventAdd()      
      
def RotateP_Negative(objList):
    for obj in objList:
        doc.AddUndo(c4d.UNDOTYPE_CHANGE, obj)
        SetLocalRotation_P_Negative(obj, GetLocalRotation(obj))
        c4d.EventAdd()       
        
        
def RotateB_Positive(objList):
    for obj in objList:
        doc.AddUndo(c4d.UNDOTYPE_CHANGE, obj)
        SetLocalRotation_B_Positive(obj, GetLocalRotation(obj))
        c4d.EventAdd()      

def RotateB_Negative(objList):
    for obj in objList:
        doc.AddUndo(c4d.UNDOTYPE_CHANGE, obj)
        SetLocalRotation_B_Negative(obj, GetLocalRotation(obj))
        c4d.EventAdd()      


def ResetRotation(objList):
    for obj in objList:
        
        doc.AddUndo(c4d.UNDOTYPE_CHANGE, obj)
        SetLocalRotation_NULL(obj)
        c4d.EventAdd()

def ResetPR(objList):
    for obj in objList:
        if not obj: print "no Object"
        doc.AddUndo(c4d.UNDOTYPE_CHANGE, obj)
        SetLocalPR_NULL(obj)
        c4d.EventAdd()  


def main():
    
    doc.StartUndo()
 
    bc = c4d.BaseContainer()
    if c4d.gui.GetInputState(c4d.BFM_INPUT_KEYBOARD,c4d.BFM_INPUT_CHANNEL,bc):
        
        if bc[c4d.BFM_INPUT_QUALIFIER] ==0 :
            RotateH_Positive(doc.GetSelection())
        if bc[c4d.BFM_INPUT_QUALIFIER] ==4 :
            RotateH_Negative(doc.GetSelection())
        if bc[c4d.BFM_INPUT_QUALIFIER] ==1 :
            RotateP_Positive(doc.GetSelection())
        if bc[c4d.BFM_INPUT_QUALIFIER] ==5 :
            RotateP_Negative(doc.GetSelection())       
        if bc[c4d.BFM_INPUT_QUALIFIER] ==2 :
            RotateB_Positive(doc.GetSelection())
        if bc[c4d.BFM_INPUT_QUALIFIER] ==6 :
            RotateB_Negative(doc.GetSelection())   
        if bc[c4d.BFM_INPUT_QUALIFIER] ==3 :
            ResetRotation(doc.GetSelection()) 
        if bc[c4d.BFM_INPUT_QUALIFIER] ==7 :
            ResetPR(doc.GetSelection())
       
    doc.EndUndo()    
    
    
if __name__=='__main__':
    main()
