Shockassembly v2

Version 2 of my shockAssembly. This time written in python so no need for pymel

Made for constraining two objects together in the form of a shock absorber. Objects can be groupnodes or single geometry. Two required.
Locators will be created at the pivot of each object so be sure to move the pivot to where ever you want your shock to pivot from.
Locators can be parentconstrained to external objects in order to attach them. If you don’t want to use the locators there is a group and bone system in place to be used in existing rigs

Demo:

##
## Shockassembly
## -------------
## 27 maj 2009
## Jan-Erik "Jonne" Östman (jonne@jonne.net)
##
## www.jonne.net
##
##
## Instructions:
## -------------
## Made for constraining two obejects together in the form of a shock absorber.
## Objects kan be groupnodes or single geometry. Two required.
## Locators will be created at the pivot of each object so be sure to move the
## pivot to where ever you want your shock to pivot from.
## Locators can be parentconstrained to external objects in order to attach them
##
## --------------------------------------------------------------------------------

import maya.cmds as cmds

def createShockAssembly(start=None, end=None):

    sel = cmds.ls(sl=1)

    ##
    ## Create locators at object pivots to drive the setup
    ##

    # Find the world location of the selected object's pivot.
    firstPivot = cmds.xform(sel[0], q=1, ws=1, rp=1)
    secondPivot = cmds.xform(sel[1], q=1, ws=1, rp=1)

    # Create and move locators to pivot of selected object
    sFirstLoc = cmds.move(firstPivot[0],firstPivot[1],firstPivot[2], cmds.spaceLocator( n=(sel[0]+"_LOC" )) , absolute=True)
    sSecondLoc = cmds.move(secondPivot[0],secondPivot[1],secondPivot[2], cmds.spaceLocator( n=(sel[1]+"_LOC" )), absolute=True)

    ##
    ## Get start and end info
    ##

    if not start:
        if len(sel)>0:
            start = sel[0]+"_LOC"
        else:
            return 0
    if not end:
        if len(sel)>1:
            end = sel[1]+"_LOC"
        else:
            return 0

    ##
    ## Take userinput as a custom shockname
    ##
    result = cmds.promptDialog(
		title='Shock Name',
		message='Enter Name:',
		button=['OK', 'Cancel'],
		defaultButton='OK',
		cancelButton='Cancel',
		dismissString='Cancel')

    if result == 'OK':
	shockName = cmds.promptDialog(query=True, text=True)
    else:
        shockName = "shock_"

    ##
    ## Build the heirarchy
    ##

    locs = ["%s_GRP" % shockName, "%s_startPos_NUL" % shockName , "%s_StartGeo_GRP" % shockName, "%s_endPos_NUL" % shockName, "%s_EndGeo_GRP" % shockName]

    for c, cur in enumerate(locs):
        grp = cmds.group(n = cur, em = 1)
        locs[c] = grp #replace old list entry with new one

        # Parent groups to create heirarchy
        if c == 1:
            cmds.parent(grp, locs[0])
        if c == 2:
            cmds.parent(grp, locs[1])
        if c == 3:
            cmds.parent(grp, locs[0])
        if c == 4:
            cmds.parent(grp, locs[1])

    ##
    ## Build joints and IK
    ##

    startP = cmds.xform(start, q=1, ws=1, t=1)
    endP = cmds.xform(end, q=1, ws=1, t=1)

    cmds.xform(locs[1],ws = 1, t = (startP[0], startP[1], startP[2]))
    cmds.xform(locs[3],ws = 1, t = (endP[0], endP[1], endP[2]))

    # Clear selection
    cmds.select(cl=1)

    # Create joints
    jnt1 = cmds.joint(p = (startP[0], startP[1], startP[2]), r = 1)
    jnt2 = cmds.joint(p = (endP[0], endP[1], endP[2]), a=1, r = 1)
    cmds.joint(jnt1, e = True, zso = True, oj = "xyz")
    cmds.joint(jnt2 , e=True, zso = True, oj = 'xyz')

    # Create IKHandle
    ikh = cmds.ikHandle(sj = jnt1, ee = jnt2, sol = "ikRPsolver")

    # Hide joints and IKhandle

    cmds.setAttr(jnt1 + '.visibility', 0)
    cmds.setAttr(jnt2 + '.visibility', 0)
    cmds.setAttr(ikh[0] + '.visibility', 0)

    # Parent joints and IK under the main groupnode
    cmds.parent(jnt1, locs[0])
    cmds.parent(ikh[0], locs[0])

    ##
    ## Constraints
    ##

    # Create a polevector
    pvNul = cmds.group(n = "%s_shockJointCahinPoleVector_NUL" % shockName , em=1)
    cmds.parent(pvNul, jnt1)
    cmds.xform(pvNul, t = (0, 0, 5))
    cmds.parent(pvNul, locs[0])
    cmds.pointConstraint(locs[3], locs[4], n = locs[4] + "_PCN")
    cmds.poleVectorConstraint(pvNul, ikh[0], n = ikh[0] + "_PVC")

    # Orient and point constraints
    cmds.pointConstraint(locs[3], ikh[0], n = ikh[0] + "_PCN")
    cmds.pointConstraint(start,locs[0],mo=True,n="start_PCN")
    cmds.pointConstraint(end,locs[3],mo=True,n="end_PCN")
    cmds.orientConstraint(jnt2,locs[4],mo=True,n=locs[4]+"_OCN")
    cmds.orientConstraint(jnt1,locs[2],mo=True,n=locs[2]+"_OCN")

    # Create a new maingroup and parent everything under it
    mainGroup = cmds.group(n = "%s_GRP" % shockName, em=1)
    cmds.parent(sel[0],locs[2])
    cmds.parent(sel[1], locs[4])
    cmds.parent(start, mainGroup)
    cmds.parent(end, mainGroup)
    cmds.parent(locs[0], mainGroup)

# end createShockAssembly()

# Run the function
createShockAssembly()
I wish to do something Great and Wonderful, but I must start by doing the little things like they were Great and Wonderful”
~ Albert Einstein