"""
HB_Divider V1.1

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

Name-US: HB_Divider

Description-US: Divide/Undivide any kind of parametric Objects [SHIFT: Divide stronger, ALT: Undivide, CTRL: Reset default Subdivisions]

Usage:
This Script works on Single Objects as well as on multiple different Objects. It increases/decreases subdivisions of any selected Parametric Objects.
Also you can reset Parameters to default settings if you CTRL-Click on the Script.

Works on Following Objects:
- Parametric Objects
- Spline Objects (Increase/Decrease Spline Interpolation)
- Nurbs
- Generators (Mograph,Array,Metaball etc.)
- Polygonselections (subdivide Polygonselections if Polygon Mode is active [SHIFT: Subdivide in Smooth Subdivisions Mode])
- Also Works with Lights (Increase/Decrease Light intensity)
- New in v1.1: When you are in Objectmode and have a Polygonalobject selected it will create a SDS Object.

Video Tutorial:
https://youtu.be/eEcAttV56kE?t=35m53s

Name-DE: HB_Divider
Description-DE: Ändert die Unterteilungen von parametrischen Objekten [SHIFT: Divide stronger, ALT: Undivide, CTRL: Reset default Subdivisions]


ChangeLog:
1/1/2016 v1.1
- New: Create SDS when in Objectmode and Polyobject selected.


6/11/2015 Release Version

"""


import c4d
from c4d import utils

def InputCheck():
    global FACTOR, LFACTOR, CFACTOR, DFACTOR, RESET,SPLINEFACTOR
    RESET=False
    bc = c4d.BaseContainer()
    if c4d.gui.GetInputState(c4d.BFM_INPUT_KEYBOARD,c4d.BFM_INPUT_CHANNEL,bc):
        
        
        FACTOR=1.5
        LFACTOR=1.2
        CFACTOR=1
        SPLINEFACTOR=0.5
    
        if bc[c4d.BFM_INPUT_QUALIFIER] ==1 :
            FACTOR=2
            LFACTOR=1.5
            CFACTOR=2
            SPLINEFACTOR=0.2
        
        if bc[c4d.BFM_INPUT_QUALIFIER] ==4 :
            FACTOR=0.4
            LFACTOR=0.8
            CFACTOR=(-1)
            SPLINEFACTOR=1.5
        if bc[c4d.BFM_INPUT_QUALIFIER] ==5 :
            FACTOR=0.1
            LFACTOR=0.4
            CFACTOR=(-2)
            SPLINEFACTOR=2

        if bc[c4d.BFM_INPUT_QUALIFIER] ==2 :
            RESET=True

############ OBJECT TYPE CHECK  ################
def TypeCheck(selobj):
    
    global FACTOR, LFACTOR, CFACTOR, RESET, SPLINEFACTOR
    

    if doc.GetMode()==7: # is Polymode active? Run Subdivide Command
        if selobj.GetType()== c4d.Opolygon:
            settings = c4d.BaseContainer()
            
            doc.AddUndo(c4d.UNDO_CHANGE,selobj)
            bc = c4d.BaseContainer()    
            if c4d.gui.GetInputState(c4d.BFM_INPUT_KEYBOARD,c4d.BFM_INPUT_CHANNEL,bc):
                
                if bc[c4d.BFM_INPUT_QUALIFIER] ==0 :
                    settings[c4d.MDATA_SUBDIVIDE_HYPER] = False
                
                
                if bc[c4d.BFM_INPUT_QUALIFIER] ==1 :
                    settings[c4d.MDATA_SUBDIVIDE_HYPER] = True
                
                
                utils.SendModelingCommand(command = c4d.MCOMMAND_SUBDIVIDE, list = [selobj], mode =c4d.MODELINGCOMMANDMODE_POLYGONSELECTION, bc = settings, doc = doc)
    
                return

    # POLYOBJECT & MODELMODE
    
    if doc.GetMode()==11:
        if selobj.GetType()== c4d.Opolygon or selobj.GetType()== c4d.Osymmetry :
            SDS=c4d.BaseObject(c4d.Osds)
            SDS.SetName(selobj.GetName()+"_SDS")
            selobjpos=selobj.GetMg()
            SDS.SetMg(selobjpos)
            
            doc.AddUndo(c4d.UNDOTYPE_NEW, SDS)
            SDS.InsertAfter(selobj)
            selobj.Remove()
            doc.AddUndo(c4d.UNDOTYPE_DELETE, selobj)
            doc.AddUndo(c4d.UNDOTYPE_NEW, selobj)
            selobj.InsertUnder(SDS)
            selobj.SetMg(selobjpos)
        
    
    

    # SPLINE OBJECTS
    
    if selobj.GetType() in [5101,5182,5185, 5181, 5186, 5187, 5178, 5189, 5180, 5183, 5188, 5184, 5177, 5176, 5175 ]:
        if (RESET):
            selobj[c4d.SPLINEOBJECT_SUB]=8
            selobj[c4d.SPLINEOBJECT_ANGLE]=c4d.utils.Rad(5)
            return
        
        selobj[c4d.SPLINEOBJECT_ANGLE]=selobj[c4d.SPLINEOBJECT_ANGLE]*SPLINEFACTOR+c4d.utils.Rad(0.1)
        selobj[c4d.SPLINEOBJECT_SUB]=int(selobj[c4d.SPLINEOBJECT_SUB]*FACTOR+1)
        return  
    
    # SWEEP
    if (selobj.GetType() == c4d.Osweep):
        
        child = selobj.GetDown()
        secondChild=child.GetNext()
        
        if (child.GetType() == c4d.Osplinenside):
            if (RESET):
                    child[c4d.PRIM_NSIDE_SIDES]=6
                    return
            child[c4d.PRIM_NSIDE_SIDES]=int(child[c4d.PRIM_NSIDE_SIDES]* FACTOR+2)
        
        if (child.GetType() == c4d.Ospline or child.GetType() == c4d.Osplinecircle or child.GetType() == c4d.Osplinearc or child.GetType() == c4d.Osplinetext or child.GetType() == c4d.Osplinehelix or child.GetType() == c4d.Osplineformula) :
            
            if (child[c4d.SPLINEOBJECT_INTERPOLATION]==3 or child[c4d.SPLINEOBJECT_INTERPOLATION]==4):
                child[c4d.SPLINEOBJECT_ANGLE]=child[c4d.SPLINEOBJECT_ANGLE]*SPLINEFACTOR
                
            else:
                child[c4d.SPLINEOBJECT_SUB]=int(child[c4d.SPLINEOBJECT_SUB]*FACTOR+1)
        
        if (secondChild.GetType() == c4d.Ospline or secondChild.GetType() == c4d.Osplinecircle or secondChild.GetType() == c4d.Osplinearc or secondChild.GetType() == c4d.Osplinetext or secondChild.GetType() == c4d.Osplinehelix or secondChild.GetType() == c4d.Osplineformula) :
            
            if (secondChild[c4d.SPLINEOBJECT_INTERPOLATION]==3 or secondChild[c4d.SPLINEOBJECT_INTERPOLATION]==4):
                secondChild[c4d.SPLINEOBJECT_ANGLE]=secondChild[c4d.SPLINEOBJECT_ANGLE]*SPLINEFACTOR
            else:
                secondChild[c4d.SPLINEOBJECT_SUB]=int(secondChild[c4d.SPLINEOBJECT_SUB]*FACTOR+1)
        
        return
        
 
    # NSIDE

    if (selobj.GetType() == c4d.Osplinenside):

        if (RESET):
            selobj[c4d.PRIM_NSIDE_SIDES]=6
            return
        
        selobj[c4d.PRIM_NSIDE_SIDES]=int(selobj[c4d.PRIM_NSIDE_SIDES]* CFACTOR+2)
        return
    
    ############# NURBS & GENERATORS ##################
    
    # LOFT
    
    if (selobj.GetType() == c4d.Oloft):
        if (RESET):
            selobj[c4d.LOFTOBJECT_SUBX]=5
            selobj[c4d.LOFTOBJECT_SUBY]=5
            return
        selobj[c4d.LOFTOBJECT_SUBX]=int(selobj[c4d.LOFTOBJECT_SUBX]*FACTOR)
        selobj[c4d.LOFTOBJECT_SUBY]=int(selobj[c4d.LOFTOBJECT_SUBY]*FACTOR)
        return

   # EXTRUDE
    
    if (selobj.GetType() == 5116):
        if (RESET):
            selobj[c4d.EXTRUDEOBJECT_SUB]=1
            selobj[c4d.CAP_REGULARWIDTH]=10
            selobj[c4d.CAP_STARTSTEPS]=1
            selobj[c4d.CAP_ENDSTEPS]=1
            

            return
        
        
        #selobj[c4d.EXTRUDEOBJECT_SUB]=int(selobj[c4d.EXTRUDEOBJECT_SUB]*FACTOR+1)
        selobj[c4d.CAP_STARTSTEPS]=int(selobj[c4d.CAP_STARTSTEPS]*FACTOR+1)
        selobj[c4d.CAP_ENDSTEPS]=int(selobj[c4d.CAP_ENDSTEPS]*FACTOR+1)
        if selobj[c4d.CAP_TYPE]==1 and selobj[c4d.CAP_REGULAR]==True:
            selobj[c4d.CAP_REGULARWIDTH]=selobj[c4d.CAP_REGULARWIDTH]*SPLINEFACTOR+1

        
        
        """
        child = selobj.GetDown()
       
        
        if (child.GetType() == c4d.Osplinenside):
            if (RESET):
                    child[c4d.PRIM_NSIDE_SIDES]=6
                    return
            child[c4d.PRIM_NSIDE_SIDES]=int(child[c4d.PRIM_NSIDE_SIDES]* FACTOR+2)
        
        if (child.GetType() == c4d.Ospline or child.GetType() == c4d.Osplinecircle or child.GetType() == c4d.Osplinearc or child.GetType() == c4d.Osplinetext or child.GetType() == c4d.Osplinehelix or child.GetType() == c4d.Osplineformula) :
            
            if (child[c4d.SPLINEOBJECT_INTERPOLATION]==3 or child[c4d.SPLINEOBJECT_INTERPOLATION]==4):
                child[c4d.SPLINEOBJECT_ANGLE]=child[c4d.SPLINEOBJECT_ANGLE]*SPLINEFACTOR
                
            else:
                child[c4d.SPLINEOBJECT_SUB]=int(child[c4d.SPLINEOBJECT_SUB]*FACTOR+1)
        
        
        
        
        """
        

        return

    # LATHE
    
    if (selobj.GetType() == 5117):
        if (RESET):
            selobj[c4d.LATHEOBJECT_SUB]=24

            return
        selobj[c4d.LATHEOBJECT_SUB]=int(selobj[c4d.LATHEOBJECT_SUB]*FACTOR)
        return

    # BEZIER
    
    if (selobj.GetType() == 5120):
        if (RESET):
            selobj[c4d.BEZIEROBJECT_SUBRX]=24
            selobj[c4d.BEZIEROBJECT_SUBRY]=24

            return
        selobj[c4d.BEZIEROBJECT_SUBRX]=int(selobj[c4d.BEZIEROBJECT_SUBRX]*FACTOR)
        selobj[c4d.BEZIEROBJECT_SUBRY]=int(selobj[c4d.BEZIEROBJECT_SUBRY]*FACTOR)
        return


    # SDS
    
    if (selobj.GetType() == c4d.Osds):
        if (RESET):
            selobj[c4d.SDSOBJECT_SUBEDITOR_CM]=2
            selobj[c4d.SDSOBJECT_SUBRAY_CM]=3
            return
        
        selobj[c4d.SDSOBJECT_SUBEDITOR_CM]=int(selobj[c4d.SDSOBJECT_SUBEDITOR_CM]*FACTOR+1)
        selobj[c4d.SDSOBJECT_SUBRAY_CM]=int(selobj[c4d.SDSOBJECT_SUBRAY_CM]*FACTOR+1)
        return

    # ATOM ARRAY
    
    if (selobj.GetType() == 1001002):
        if (RESET):
            selobj[c4d.ATOMARRAYOBJECT_SUB]=8

            return
        selobj[c4d.ATOMARRAYOBJECT_SUB]=int(selobj[c4d.ATOMARRAYOBJECT_SUB]*FACTOR)

        return

   # METABALL
    
    if (selobj.GetType() == 5125):
        if (RESET):
            selobj[c4d.METABALLOBJECT_SUBEDITOR]=40
            selobj[c4d.METABALLOBJECT_SUBRAY]=5

            return
        selobj[c4d.METABALLOBJECT_SUBEDITOR]=int(selobj[c4d.METABALLOBJECT_SUBEDITOR]*SPLINEFACTOR)
        selobj[c4d.METABALLOBJECT_SUBRAY]=int(selobj[c4d.METABALLOBJECT_SUBRAY]*SPLINEFACTOR)
        return
     

    # LIGHT
        
    if (selobj.GetType() == c4d.Olight):
        if (RESET): 
            selobj[c4d.LIGHT_BRIGHTNESS]=1
            return
                
        selobj[c4d.LIGHT_BRIGHTNESS]=round(selobj[c4d.LIGHT_BRIGHTNESS]*LFACTOR,2)
        return


    # MOGRAPH
    
    if (selobj.GetType() == 1018544):
        if (RESET):
            selobj[c4d.MG_SPLINE_COUNT]=10
            selobj[c4d.MG_LINEAR_COUNT]=3
            selobj[c4d.MG_RADIAL_COUNT]=5
            selobj[c4d.MG_GRID_RESOLUTION]=c4d.Vector(3,3,3)
            return
        
        if selobj[c4d.ID_MG_MOTIONGENERATOR_MODE]==0:
            selobj[c4d.MG_SPLINE_COUNT]=int(selobj[c4d.MG_SPLINE_COUNT]*FACTOR+1)
            
        if selobj[c4d.ID_MG_MOTIONGENERATOR_MODE]==1:
            selobj[c4d.MG_LINEAR_COUNT]=int(selobj[c4d.MG_LINEAR_COUNT]*FACTOR+1)
            
        if selobj[c4d.ID_MG_MOTIONGENERATOR_MODE]==2:
             selobj[c4d.MG_RADIAL_COUNT]=int(selobj[c4d.MG_RADIAL_COUNT]*FACTOR+1)
            
        if selobj[c4d.ID_MG_MOTIONGENERATOR_MODE]==3:
            selobj[c4d.MG_GRID_RESOLUTION]=c4d.Vector(selobj[c4d.MG_GRID_RESOLUTION]+CFACTOR)
       
        
        return
    
    
    # ARRAY
    
    if (selobj.GetType() == 5150):
        if (RESET):
            selobj[c4d.ARRAYOBJECT_COPIES]=7

            return
        selobj[c4d.ARRAYOBJECT_COPIES]=int(selobj[c4d.ARRAYOBJECT_COPIES]*FACTOR+1)

        return

    
    
    
    
    
    
    
    ####################    PRIMITIVES    #####################
        
    # CUBE
    
    if (selobj.GetType() == c4d.Ocube):

        if (RESET): 
            selobj[c4d.PRIM_CUBE_SUBX]=1
            selobj[c4d.PRIM_CUBE_SUBY]=1
            selobj[c4d.PRIM_CUBE_SUBZ]=1
            return
        selobj[c4d.PRIM_CUBE_SUBX]=int(selobj[c4d.PRIM_CUBE_SUBX]+CFACTOR)
        selobj[c4d.PRIM_CUBE_SUBY]=int(selobj[c4d.PRIM_CUBE_SUBY]+CFACTOR)
        selobj[c4d.PRIM_CUBE_SUBZ]=int(selobj[c4d.PRIM_CUBE_SUBZ]+CFACTOR)
        return
    
    # CONE
    
    if (selobj.GetType() == 5162):

        if (RESET): 
            selobj[c4d.PRIM_CONE_HSUB]=8
            selobj[c4d.PRIM_CONE_SEG]=36
            return
        
        selobj[c4d.PRIM_CONE_HSUB]=int(selobj[c4d.PRIM_CONE_HSUB]*FACTOR)
        selobj[c4d.PRIM_CONE_SEG]=int(selobj[c4d.PRIM_CONE_SEG]*FACTOR)
        return
    
    
    
    # CYLINDER
    
    if (selobj.GetType() == 5170):

        if (RESET): 
            selobj[c4d.PRIM_CYLINDER_HSUB]=1
            selobj[c4d.PRIM_CYLINDER_SEG]=36
            return
        
        selobj[c4d.PRIM_CYLINDER_HSUB]=int(selobj[c4d.PRIM_CYLINDER_HSUB]*FACTOR+1)
        selobj[c4d.PRIM_CYLINDER_SEG]=int(selobj[c4d.PRIM_CYLINDER_SEG]*FACTOR)
        return
    
    # DISC
    
    if (selobj.GetType() == 5164):

        if (RESET): 
            selobj[c4d.PRIM_DISC_CSUB]=4
            selobj[c4d.PRIM_DISC_SEG]=36
            return
        
        selobj[c4d.PRIM_DISC_CSUB]=int(selobj[c4d.PRIM_DISC_CSUB]*FACTOR)
        selobj[c4d.PRIM_DISC_SEG]=int(selobj[c4d.PRIM_DISC_SEG]*FACTOR)
        return
    
    # PLANE
    
    if (selobj.GetType() == 5168):

        if (RESET): 
            selobj[c4d.PRIM_PLANE_SUBW]=20
            selobj[c4d.PRIM_PLANE_SUBH]=20
            return
        
        selobj[c4d.PRIM_PLANE_SUBW]=int(selobj[c4d.PRIM_PLANE_SUBW]*FACTOR)
        selobj[c4d.PRIM_PLANE_SUBH]=int(selobj[c4d.PRIM_PLANE_SUBH]*FACTOR)
        return
    
    # POLYGON
    
    if (selobj.GetType() == 5174):

        if (RESET): 
            selobj[c4d.PRIM_POLY_SUB]=1

            return

        selobj[c4d.PRIM_POLY_SUB]=int(selobj[c4d.PRIM_POLY_SUB]*FACTOR+1)
        return 
     
     
    # SPHERE
    
    if (selobj.GetType() == 5160):

        if (RESET): 
            selobj[c4d.PRIM_SPHERE_SUB]=24
            return
        
        selobj[c4d.PRIM_SPHERE_SUB]=int(selobj[c4d.PRIM_SPHERE_SUB]*FACTOR)
        return
       
    # TORUS
    
    if (selobj.GetType() == 5163):

        if (RESET): 
            selobj[c4d.PRIM_TORUS_SEG]=36
            selobj[c4d.PRIM_TORUS_CSUB]=18
            return
        
        selobj[c4d.PRIM_TORUS_SEG]=int(selobj[c4d.PRIM_TORUS_SEG]*FACTOR)
        selobj[c4d.PRIM_TORUS_CSUB]=int(selobj[c4d.PRIM_TORUS_CSUB]*FACTOR)
        return
    
    # CAPSULE
    
    if (selobj.GetType() == 5171):

        if (RESET): 
            selobj[c4d.PRIM_CAPSULE_HSUB]=8
            selobj[c4d.PRIM_CAPSULE_FSUB]=8
            selobj[c4d.PRIM_CAPSULE_SEG]=36
            return
        
        selobj[c4d.PRIM_CAPSULE_HSUB]=int(selobj[c4d.PRIM_CAPSULE_HSUB]*FACTOR)
        selobj[c4d.PRIM_CAPSULE_FSUB]=int(selobj[c4d.PRIM_CAPSULE_FSUB]*FACTOR)
        selobj[c4d.PRIM_CAPSULE_SEG]=int(selobj[c4d.PRIM_CAPSULE_SEG]*FACTOR)
        return    
       
    # OILTANK
    
    if (selobj.GetType() == 5172):

        if (RESET): 
            selobj[c4d.PRIM_OILTANK_HSUB]=8
            selobj[c4d.PRIM_OILTANK_FSUB]=8
            selobj[c4d.PRIM_OILTANK_SEG]=36
            return
        
        selobj[c4d.PRIM_OILTANK_HSUB]=int(selobj[c4d.PRIM_OILTANK_HSUB]*FACTOR)
        selobj[c4d.PRIM_OILTANK_FSUB]=int(selobj[c4d.PRIM_OILTANK_FSUB]*FACTOR)
        selobj[c4d.PRIM_OILTANK_SEG]=int(selobj[c4d.PRIM_OILTANK_SEG]*FACTOR)
        return          
     
    # TUBE
    
    if (selobj.GetType() == 5165):

        if (RESET): 
            selobj[c4d.PRIM_TUBE_SEG]=36
            selobj[c4d.PRIM_TUBE_CSUB]=1
            selobj[c4d.PRIM_TUBE_HSUB]=1
            return
        
        selobj[c4d.PRIM_TUBE_SEG]=int(selobj[c4d.PRIM_TUBE_SEG]*FACTOR)
        selobj[c4d.PRIM_TUBE_CSUB]=int(selobj[c4d.PRIM_TUBE_CSUB]*FACTOR)
        selobj[c4d.PRIM_TUBE_HSUB]=int(selobj[c4d.PRIM_TUBE_HSUB]*FACTOR)
        return          
      
     # PYRAMID
    
    if (selobj.GetType() == 5167):

        if (RESET): 
            selobj[c4d.PRIM_PYRAMID_SUB]=1

            return
        
        selobj[c4d.PRIM_PYRAMID_SUB]=int(selobj[c4d.PRIM_PYRAMID_SUB]*FACTOR+1)

        return          
     
    # PLATONIC
    
    if (selobj.GetType() == 5161):

        if (RESET): 
            selobj[c4d.PRIM_PLATONIC_SUB]=1

            return
        
        selobj[c4d.PRIM_PLATONIC_SUB]=int(selobj[c4d.PRIM_PLATONIC_SUB]*FACTOR+1)

        return          
     
    # FIGURE
    
    if (selobj.GetType() == 5166):

        if (RESET): 
            selobj[c4d.PRIM_FIGURE_SUB]=14
            return
        
        selobj[c4d.PRIM_FIGURE_SUB]=int(selobj[c4d.PRIM_FIGURE_SUB]*FACTOR)
     
        return          
     
    # LANDSCAPE
    
    if (selobj.GetType() == 5169):

        if (RESET): 
            selobj[c4d.PRIM_FRACTAL_SUBW]=100
            selobj[c4d.PRIM_FRACTAL_SUBH]=100

            return
        
        selobj[c4d.PRIM_FRACTAL_SUBW]=int(selobj[c4d.PRIM_FRACTAL_SUBW]*FACTOR)
        selobj[c4d.PRIM_FRACTAL_SUBH]=int(selobj[c4d.PRIM_FRACTAL_SUBH]*FACTOR)

        return          
    
     # RELIEF
    
    if (selobj.GetType() == 5173):

        if (RESET): 
            selobj[c4d.PRIM_RELIEF_SUBW]=100
            selobj[c4d.PRIM_RELIEF_SUBH]=100
 
            return
        
        selobj[c4d.PRIM_RELIEF_SUBW]=int(selobj[c4d.PRIM_RELIEF_SUBW]*FACTOR)
        selobj[c4d.PRIM_RELIEF_SUBH]=int(selobj[c4d.PRIM_RELIEF_SUBH]*FACTOR)
        
        return          
     
   
    
    
      
        ###############    MAIN      ####################

def main():
    
    InputCheck()

    objList=doc.GetSelection()
    doc.StartUndo()
    for obj in objList:
        #doc.AddUndo(c4d.UNDOTYPE_CHANGE_SMALL,obj)
        TypeCheck(obj)
        
    doc.EndUndo()
    c4d.EventAdd()
    c4d.CallCommand(100004769) 

if __name__=='__main__':
    main()