

#create Ik constraint ver 1.1
##created BY http://steamcommunity.com/id/OMGTheresABearInMyOatmeal/
#feel free to modify the script for your own use
#find any bugs or suggestions message me in the workshop page comments


from PySide import QtGui
import random
#==================================================================================================
# Compute the direction from boneA to boneB
#==================================================================================================
def ComputeVectorBetweenBones( boneA, boneB, scaleFactor ):

    vPosA = vs.Vector( 0, 0, 0 )
    boneA.GetAbsPosition()
    print boneA.GetAbsPosition()

    vPosB = vs.Vector( 0, 0, 0 )
    boneB.GetAbsPosition( vPosB )
    print vPosB
    vDir = vs.Vector( 0, 0, 0 )
    vs.mathlib.VectorSubtract( vPosB, vPosA, vDir )
    vDir.NormalizeInPlace()

    vScaledDir = vs.Vector( 0, 0, 0 )
    vs.mathlib.VectorScale( vDir, scaleFactor, vScaledDir )

    return vScaledDir

def error(e):
    
    #error box

    msgBox = QtGui.QMessageBox(QtGui.QMessageBox.Critical,
            "ERROR",str(e),QtGui.QMessageBox.NoButton)


    msgBox.addButton("&Continue", QtGui.QMessageBox.RejectRole)
    if msgBox.exec_() == QtGui.QMessageBox.AcceptRole:pass


def BuildRig(control_dag):
    animSet = sfm.GetCurrentAnimationSet()
    rootGroup = animSet.GetRootControlGroup()

    #gets the dag ,parent and its grandparent
    targetDag = sfmUtils.FindFirstDag( [ control_dag ], True )

    
    parent=targetDag.GetParent()
    grandparent=parent.GetParent()



    #gets the name of the dags and fins out which control group it belongs to
    b=str(grandparent.GetName()).find('(')
    e=str(grandparent.GetName()).find(')')
    grandparentgroup=rootGroup.FindGroupContainingControl(animSet.FindControl(str(grandparent.GetName())[b+1:e]))

    b=str(parent.GetName()).find('(')
    e=str(parent.GetName()).find(')')
    parentgroup=rootGroup.FindGroupContainingControl(animSet.FindControl(str(parent.GetName())[b+1:e]))
    parentname="RIG_"+str(parent.GetName())[b+1:e]

    b=str(targetDag.GetName()).find('(')
    e=str(targetDag.GetName()).find(')')
    #print(rootGroup.FindChildByName("LeftFingers",True))
    targetgroup=rootGroup.FindGroupContainingControl(animSet.FindControl(str(targetDag.GetName())[b+1:e]))
    targetname="RIG_"+str(targetDag.GetName())[b+1:e]

    #just checks to see if the dags are bones
    if "bone" not in str(grandparent):
        
        error(targetDag.GetName()+" does'nt have a bone grandparent")
        return

    rig = sfm.BeginRig( "IK_" + targetname + str(random.randint(1,100)) );
    if ( rig == None ):
        return


    boneRoot      = sfmUtils.FindFirstDag( [ "RootTransform" ], True )

    # Change the operation mode to passthrough so changes can be made temporarily
    sfm.SetOperationMode( "Pass" )

    # Move everything into the reference pose
    sfm.SelectAll()
    sfm.SetReferencePose()


    #creates the righandels
   # vKneeOffset = ComputeVectorBetweenBones( grandparent, parent, 10 )
    #print (sfm.GetPosition(space="World"))

    rigparent   = sfmUtils.CreateOffsetHandle( parentname,  parent,  vs.Vector( 0, 0, 0 ), bCreateControls=True )

    rigtarget    = sfmUtils.CreateConstrainedHandle( targetname,   targetDag,   bCreateControls=False )



    sfm.ClearSelection()
    sfmUtils.SelectDagList( [rigparent,rigtarget] )
    sfm.GenerateSamples()
    sfm.RemoveConstraints()


    ConstraintGroup=rootGroup.CreateControlGroup( "Constraints" )
    ConstraintGroup.SetGroupColor(vs.Color( 0, 128, 255, 255 ),False)
    ConstraintGroup.SetSelectable( False )
    ConstraintGroup.SetVisible( False )


    sfmUtils.AddDagControlsToGroup(ConstraintGroup,targetDag,parent,grandparent)



    sfmUtils.BuildArmLeg( rigparent,rigtarget, grandparent,  targetDag, True )




    sfmUtils.AddDagControlsToGroup(grandparentgroup,grandparent)#gets added back to avoid the weight controls geting in the way
    sfmUtils.AddDagControlsToGroup(targetgroup,rigtarget)
    sfmUtils.AddDagControlsToGroup(parentgroup,rigparent)


    sfm.EndRig()

controls_to_rig=['ValveBiped.Bip01_L_Hand', 'ValveBiped.Bip01_R_Hand', 'ValveBiped.Bip01_R_Foot', 'ValveBiped.Bip01_L_Foot']

for elm in controls_to_rig:

    BuildRig(elm)

    