shockAssembly.py

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.

Pymel available from http://code.google.com/p/pymel/downloads/list

##
## Shockassembly
## -------------
## 6 mar 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
##
## Pymel available from http://code.google.com/p/pymel/downloads/list
## --------------------------------------------------------------------------------

import pymel as pm

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

    sel = pm.selected()

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

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

    # Create and move locators to pivot of selected object
    sFirstLoc = pm.move(pm.spaceLocator( n=(sel[0]+"_LOC")), [firstPivot[0],firstPivot[1],firstPivot[2]], absolute=True)
    sSecondLoc = pm.move(pm.spaceLocator( n=(sel[1]+"_LOC")), [secondPivot[0],secondPivot[1],secondPivot[2]], 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

    ##
    ## Build the heirarchy
    ##

    locs = ["shockSub_GRP","startPos_NULL","startGeo_GRP","endPos_NULL","endGeo_GRP"]

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

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

    ##
    ## Build joints and IK
    ##

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

    pm.PyNode(locs[1]).t.set(startP[0], startP[1], startP[2])
    pm.PyNode(locs[3]).t.set(endP[0], endP[1], endP[2])

    # Clear selection
    pm.select(cl=1)

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

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

    # Hide joints and IKhandle
    jnt1.visibility.set(0)
    jnt2.visibility.set(0)
    ikh[0].visibility.set(0)

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

    ##
    ## Constraints
    ##

    # Create a polevector
    pvNul = pm.group(n = "shockJointCahinPoleVector_NUL", em=1)
    pm.parent(pvNul, jnt1)
    pvNul.t.set(0,0,5)
    pm.parent(pvNul, locs[0])
    pm.pointConstraint(locs[3], locs[4], n = locs[4] + "_PCN")
    pm.poleVectorConstraint(pvNul, ikh[0], n = ikh[0] + "_PVC")

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

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

    # Lock groupnodes
    for c, cur in enumerate(locs):

        # Lock the translate, rotate and scale channels on the groups
        for ch in "trs":
            for a in "xyz":
                pm.PyNode(locs[c]).attr("%s%s" %(ch,a)).set(l = 1)

# 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