예제 #1
0
파일: jcRibbon.py 프로젝트: utsdab/usr
def createBendCtrl(myName='Bend_Ctrl', r=1, zero=True):
    grp = None
    curve = cmds.curve(n=myName, d=1, p=[(-1.5*r, 0, 0), (-1.06066*r, 0, -1.06066*r), (0, 0, -1.5*r), (1.06066*r, 0, -1.06066*r), (1.5*r, 0, 0), (1.06066*r, 0, 1.06066*r), (0, 0, 1.5*r), (-1.06066*r, 0, 1.06066*r), (-1.5*r, 0, 0), (-1.06066*r, 0, -1.06066*r)])
    ctrls.renameShape([curve])
    cmds.setAttr(curve+'.rz', 90)
    cmds.makeIdentity(curve, a=1)
    if zero:
        grp = cmds.group(curve, n=myName+'_Grp')
    return [grp, curve]
예제 #2
0
파일: jcRibbon.py 프로젝트: utsdab/usr
def createElbowCtrl(myName='Limb_Ctrl', r=1, zero=True):
    curve = cmds.curve(n=myName, d=1, p=[(-2*r, 0, -1*r), (-1*r, 0, -1*r), (-1*r, 0, -2*r), (1*r, 0, -2*r), (1*r, 0, -1*r), (2*r, 0, -1*r), (2*r, 0, 1*r), (1*r, 0, 1*r), (1*r, 0, 2*r), (-1*r, 0, 2*r), (-1*r, 0, 1*r), (-2*r, 0, 1*r), (-2*r, 0, -1*r), (-1*r, 0, -1*r)])
    ctrls.renameShape([curve])
    cmds.setAttr(curve+'.rx', 90)
    cmds.setAttr(curve+'.rz', 90)
    cmds.makeIdentity(curve, a=1)
    grp = None
    if zero:
        grp = cmds.group(curve, n=myName+'_Grp')
    return [grp, curve]
예제 #3
0
def createBendCtrl(myName='Bend_Ctrl', r=1, zero=True):
    grp = None
    curve = cmds.curve(n=myName,
                       d=1,
                       p=[(-1.5 * r, 0, 0), (-1.06066 * r, 0, -1.06066 * r),
                          (0, 0, -1.5 * r), (1.06066 * r, 0, -1.06066 * r),
                          (1.5 * r, 0, 0), (1.06066 * r, 0, 1.06066 * r),
                          (0, 0, 1.5 * r), (-1.06066 * r, 0, 1.06066 * r),
                          (-1.5 * r, 0, 0), (-1.06066 * r, 0, -1.06066 * r)])
    ctrls.renameShape([curve])
    cmds.setAttr(curve + '.rz', 90)
    cmds.makeIdentity(curve, a=1)
    if zero:
        grp = cmds.group(curve, n=myName + '_Grp')
    return [grp, curve]
예제 #4
0
def createElbowCtrl(myName='Limb_Ctrl', r=1, zero=True):
    curve = cmds.curve(n=myName,
                       d=1,
                       p=[(-2 * r, 0, -1 * r), (-1 * r, 0, -1 * r),
                          (-1 * r, 0, -2 * r), (1 * r, 0, -2 * r),
                          (1 * r, 0, -1 * r), (2 * r, 0, -1 * r),
                          (2 * r, 0, 1 * r), (1 * r, 0, 1 * r),
                          (1 * r, 0, 2 * r), (-1 * r, 0, 2 * r),
                          (-1 * r, 0, 1 * r), (-2 * r, 0, 1 * r),
                          (-2 * r, 0, -1 * r), (-1 * r, 0, -1 * r)])
    ctrls.renameShape([curve])
    cmds.setAttr(curve + '.rx', 90)
    cmds.setAttr(curve + '.rz', 90)
    cmds.makeIdentity(curve, a=1)
    grp = None
    if zero:
        grp = cmds.group(curve, n=myName + '_Grp')
    return [grp, curve]
예제 #5
0
def createElbowCtrl(myName='Limb_Ctrl', r=1, zero=True, armStyle=True):
    curve = cmds.curve(n=myName,
                       d=1,
                       p=[(-2 * r, 0, -1 * r), (-1 * r, 0, -1 * r),
                          (-1 * r, 0, -2 * r), (1 * r, 0, -2 * r),
                          (1 * r, 0, -1 * r), (2 * r, 0, -1 * r),
                          (2 * r, 0, 1 * r), (1 * r, 0, 1 * r),
                          (1 * r, 0, 2 * r), (-1 * r, 0, 2 * r),
                          (-1 * r, 0, 1 * r), (-2 * r, 0, 1 * r),
                          (-2 * r, 0, -1 * r), (-1 * r, 0, -1 * r)])
    ctrls.renameShape([curve])
    if armStyle:
        cmds.setAttr(curve + '.rx', 90)
        cmds.setAttr(curve + '.ry', 90)
    cmds.makeIdentity(curve, a=1)
    grp = None
    if zero:
        zero = cmds.group(curve, n=myName + '_Zero')
        grp = cmds.group(zero, n=myName + '_Grp')
        if armStyle:
            cmds.rotate(0, -90, -90, zero)
        else:
            cmds.rotate(-90, 0, -90, zero)
    cmds.addAttr(curve,
                 longName='autoBend',
                 attributeType='float',
                 minValue=0,
                 maxValue=1,
                 defaultValue=0,
                 keyable=True)
    cmds.addAttr(curve,
                 longName='pin',
                 attributeType='float',
                 minValue=0,
                 maxValue=1,
                 defaultValue=0,
                 keyable=True)
    return [grp, curve, zero]
예제 #6
0
def createElbowCtrl(myName='Limb_Ctrl', r=1, zero=True, armStyle=True):
    curve = cmds.curve(n=myName,
                       d=1,
                       p=[(-2 * r, 0, -1 * r), (-1 * r, 0, -1 * r),
                          (-1 * r, 0, -2 * r), (1 * r, 0, -2 * r),
                          (1 * r, 0, -1 * r), (2 * r, 0, -1 * r),
                          (2 * r, 0, 1 * r), (1 * r, 0, 1 * r),
                          (1 * r, 0, 2 * r), (-1 * r, 0, 2 * r),
                          (-1 * r, 0, 1 * r), (-2 * r, 0, 1 * r),
                          (-2 * r, 0, -1 * r), (-1 * r, 0, -1 * r)])
    ctrls.renameShape([curve])
    if armStyle:
        cmds.setAttr(curve + '.rx', 90)
        cmds.setAttr(curve + '.ry', 90)
    cmds.makeIdentity(curve, a=1)
    grp = None
    if zero:
        zero = cmds.group(curve, n=myName + '_Grp')
        grp = cmds.group(zero, n=myName + '_Grp')
        if armStyle:
            cmds.rotate(0, -90, -90, zero)
        else:
            cmds.rotate(-90, 0, -90, zero)
    return [grp, curve, zero]
예제 #7
0
파일: jcRibbon.py 프로젝트: utsdab/usr
def createRibbon(axis=(0, 0, 1), name='xxxx', horizontal=False, numJoints=3, guias=None, v=True, s=0, firstLimb=True, upCtrl=None, ctrlRadius=1, worldRef="worldRef"):
        retDict = {}
        
        #define variables
        top_Loc = []
        mid_Loc = []
        bttm_Loc = []
        rb_Jnt = []
        drv_Jnt =[]
        fols = []
        aux_Jnt = []
        ribbon = ''
        extraCtrlList = []

        #define attributes
        limbManualVVAttr = "limbManualVolume"
        limbVVAttr       = "limbVolumeVariation"
        limbMinVVAttr    = "limbMinVolume"

        #create a nurbsPlane based in the choose orientation option
        if horizontal:
            ribbon =cmds.nurbsPlane(ax=axis, w=numJoints, lr=(1/float(numJoints)), d=3, u=numJoints, v=1, ch=0, name=name+'_Plane')[0]
            cmds.rebuildSurface(ribbon, ch=0, rpo=1, rt=0, end=1, kr=0, kcp=0, kc=0, sv=1, du=3, dv=1, tol=0.01, fr=0, dir=1) 
        else:
            ribbon =cmds.nurbsPlane(ax=axis, w=1, lr=numJoints, d=3, u=1, v=numJoints, ch=0, name=name+'_Plane')[0]
            cmds.rebuildSurface(ribbon, ch=0, rpo=1, rt=0, end=1, kr=0, kcp=0, kc=0, su=1, du=1, dv=3, tol=0.01, fr=0, dir=0) 
        # make this ribbonNurbsPlane as not skinable from dpAR_UI:
        cmds.addAttr(ribbon, longName="doNotSkinIt", attributeType="bool", keyable=True)
        cmds.setAttr(ribbon+".doNotSkinIt", 1)
        #call the function to create follicles and joint in the nurbsPlane
        results = createFollicles(rib=ribbon, num=numJoints, name=name, horizontal=horizontal)
        rb_Jnt = results[0]
        fols = results[1]
        #create locator controls for the middle of the ribbon
        mid_Loc.append(cmds.spaceLocator(name=name+'_Mid_Pos_Loc')[0])
        mid_Loc.append(cmds.spaceLocator(name=name+'_Mid_Aim_Loc')[0])
        mid_Loc.append(cmds.spaceLocator(name=name+'_Mid_Off_Loc')[0])
        mid_Loc.append(cmds.spaceLocator(name=name+'_Mid_Up_Loc')[0])
        #parent correctly the middle locators
        cmds.parent(mid_Loc[2], mid_Loc[1], relative=True)
        cmds.parent(mid_Loc[1], mid_Loc[0], relative=True)
        cmds.parent(mid_Loc[3], mid_Loc[0], relative=True)
        #create the locators controls for the top of the ribbon
        top_Loc.append(cmds.spaceLocator(name=name+'_Top_Pos_Loc')[0])
        top_Loc.append(cmds.spaceLocator(name=name+'_Top_Aim_Loc')[0])
        top_Loc.append(cmds.spaceLocator(name=name+'_Top_Up_Loc')[0])
        #parent correctly the top locators
        cmds.parent(top_Loc[1], top_Loc[0], relative=True)
        cmds.parent(top_Loc[2], top_Loc[0], relative=True)
        #create the locators for the end of the ribbon
        bttm_Loc.append(cmds.spaceLocator(name=name+'_Bttm_Pos_Loc')[0])
        bttm_Loc.append(cmds.spaceLocator(name=name+'_Bttm_Aim_Loc')[0])
        bttm_Loc.append(cmds.spaceLocator(name=name+'_Bttm_Up_Loc')[0])
        #parent correctly the bottom locators
        cmds.parent(bttm_Loc[1], bttm_Loc[0], relative=True)
        cmds.parent(bttm_Loc[2], bttm_Loc[0], relative=True)
        
        #put the top locators in the same place of the top joint
        cmds.parent(top_Loc[0], fols[len(fols)-1], relative=True)
        cmds.parent(top_Loc[0], w=True)
        
        #put the bottom locators in the same place of the bottom joint
        cmds.parent(bttm_Loc[0], fols[0], relative=True)
        cmds.parent(bttm_Loc[0], w=True)
        cmds.select(clear=True)
        
        #create the joints that will be used to control the ribbon
        drv_Jnt = cmds.duplicate([rb_Jnt[0], rb_Jnt[(len(rb_Jnt)-1)/2], rb_Jnt[len(rb_Jnt)-1]])
        dup = cmds.duplicate([drv_Jnt[0], drv_Jnt[2]])
        drv_Jnt.append(dup[0])
        drv_Jnt.append(dup[1])
        #cmds.parent(drv_Jnt, w=True)
        for jnt in drv_Jnt:
            cmds.joint(jnt, e=True, oj='none', ch=True, zso=True);
            cmds.setAttr(jnt+'.radius', cmds.getAttr(jnt+'.radius')+0.5)
        #rename created joints
        drv_Jnt[0] = cmds.rename(drv_Jnt[0], name+'_Drv_Bttm_Jxt')
        drv_Jnt[1] = cmds.rename(drv_Jnt[1], name+'_Drv_Mid_Jxt')
        drv_Jnt[2] = cmds.rename(drv_Jnt[2], name+'_Drv_Top_Jxt')
        drv_Jnt[3] = cmds.rename(drv_Jnt[3], name+'_Drv_Bttm_End')
        drv_Jnt[4] = cmds.rename(drv_Jnt[4], name+'_Drv_Top_End')
        
        #place joints correctly accordaly with the user options choose
        if (horizontal and axis==(1, 0, 0)) or (horizontal and axis==(0, 0, 1)):
            cmds.setAttr(bttm_Loc[2]+'.translateY', 2)
            cmds.setAttr(top_Loc[2]+'.translateY', 2)
            cmds.setAttr(mid_Loc[3]+'.translateY', 2)
        elif (horizontal and axis==(0, 1, 0)) or (not horizontal and axis==(1, 0, 0)):
            cmds.setAttr(bttm_Loc[2]+'.translateZ', 2)
            cmds.setAttr(top_Loc[2]+'.translateZ', 2)
            cmds.setAttr(mid_Loc[3]+'.translateZ', 2)
        elif not horizontal and axis==(0, 1, 0) or (not horizontal and axis==(0, 0, 1)):
            cmds.setAttr(bttm_Loc[2]+'.translateX', 2)
            cmds.setAttr(top_Loc[2]+'.translateX', 2)
            cmds.setAttr(mid_Loc[3]+'.translateX', 2)
        elif horizontal and axis==(0, 0, -1):
            if firstLimb:
                cmds.setAttr(bttm_Loc[2]+'.translateY', 2)
                cmds.setAttr(top_Loc[2]+'.translateX', -2)
                cmds.setAttr(mid_Loc[3]+'.translateX', -2)
                cmds.setAttr(mid_Loc[3]+'.translateY', 2)
            else:
                if s == 0:
                    cmds.setAttr(bttm_Loc[2]+'.translateX', -2)
                    cmds.setAttr(top_Loc[2]+'.translateY', -2)
                    cmds.setAttr(mid_Loc[3]+'.translateX', -2)
                    cmds.setAttr(mid_Loc[3]+'.translateY', 2)
                else:
                    cmds.setAttr(bttm_Loc[2]+'.translateX', -2)
                    cmds.setAttr(top_Loc[2]+'.translateY', -2)
                    cmds.setAttr(mid_Loc[3]+'.translateX', -2)
                    cmds.setAttr(mid_Loc[3]+'.translateY', 2)
                
        
        #create auxiliary joints that will be used to control the ribbon
        aux_Jnt.append(cmds.duplicate(drv_Jnt[1], name=name+'_Jxt_Rot')[0])
        cmds.setAttr(aux_Jnt[0]+'.jointOrient', 0, 0, 0)
        aux_Jnt.append(cmds.duplicate(aux_Jnt[0], name=name+'_Jxt_Rot_End')[0])
        
        cmds.parent(aux_Jnt[1], mid_Loc[3])
        cmds.setAttr(aux_Jnt[1]+'.translate', 0, 0, 0)
        cmds.parent(aux_Jnt[1], aux_Jnt[0])
        cmds.parent(mid_Loc[3], aux_Jnt[1])
        #calculate the adjust for the new chain position
        dist = float(numJoints)/2.0
        end_dist = (1/float(numJoints))
        cmds.parent(drv_Jnt[3], drv_Jnt[0])
        cmds.parent(drv_Jnt[4], drv_Jnt[2])
        
        #adjust the joints orientation and position based in the options choose from user
        if horizontal and axis==(1, 0, 0):
            cmds.setAttr(drv_Jnt[0]+'.jointOrient', 0, 90, 0)
            cmds.setAttr(drv_Jnt[2]+'.jointOrient', 0, 90, 0)
            
            cmds.setAttr(drv_Jnt[0]+'.tz', -dist)
            cmds.setAttr(drv_Jnt[3]+'.tz', end_dist*dist)
            cmds.setAttr(drv_Jnt[2]+'.tz', dist)
            cmds.setAttr(drv_Jnt[4]+'.tz', -end_dist*dist)
        
        elif horizontal and axis==(0, 1, 0):
            cmds.setAttr(drv_Jnt[0]+'.jointOrient', 0, 0, 0)
            cmds.setAttr(drv_Jnt[2]+'.jointOrient', 0, 0, 0)
            
            cmds.setAttr(drv_Jnt[0]+'.tx', -dist)
            cmds.setAttr(drv_Jnt[3]+'.tx', end_dist*dist)
            cmds.setAttr(drv_Jnt[2]+'.tx', dist)
            cmds.setAttr(drv_Jnt[4]+'.tx', -end_dist*dist)
        
        elif horizontal and axis==(0, 0, 1):
            cmds.setAttr(drv_Jnt[0]+'.jointOrient', 0, 0, 0)
            cmds.setAttr(drv_Jnt[2]+'.jointOrient', 0, 0, 0)
            
            cmds.setAttr(drv_Jnt[0]+'.tx', -dist)
            cmds.setAttr(drv_Jnt[3]+'.tx', end_dist*dist)
            cmds.setAttr(drv_Jnt[2]+'.tx', dist)
            cmds.setAttr(drv_Jnt[4]+'.tx', -end_dist*dist)
        
        elif horizontal and axis==(0, 0, -1):
            cmds.setAttr(drv_Jnt[0]+'.jointOrient', 0, 0, 0)
            cmds.setAttr(drv_Jnt[2]+'.jointOrient', 0, 0, 0)
            
            cmds.setAttr(drv_Jnt[0]+'.tx', -dist)
            cmds.setAttr(drv_Jnt[3]+'.tx', end_dist*dist)
            cmds.setAttr(drv_Jnt[2]+'.tx', dist)
            cmds.setAttr(drv_Jnt[4]+'.tx', -end_dist*dist)
            
        elif not horizontal and axis==(1, 0, 0):
            cmds.setAttr(drv_Jnt[0]+'.jointOrient', 0, 0, -90)
            cmds.setAttr(drv_Jnt[2]+'.jointOrient', 0, 0, -90)
        
            cmds.setAttr(drv_Jnt[0]+'.ty', -dist)
            cmds.setAttr(drv_Jnt[3]+'.ty', end_dist*dist)
            cmds.setAttr(drv_Jnt[2]+'.ty', dist)
            cmds.setAttr(drv_Jnt[4]+'.ty', -end_dist*dist)
            
        elif not horizontal and axis==(0, 1, 0):
            cmds.setAttr(drv_Jnt[0]+'.jointOrient', 0, 90, 0)
            cmds.setAttr(drv_Jnt[2]+'.jointOrient', 0, 90, 0)
        
            cmds.setAttr(drv_Jnt[0]+'.tz', -dist)
            cmds.setAttr(drv_Jnt[3]+'.tz', end_dist*dist)
            cmds.setAttr(drv_Jnt[2]+'.tz', dist)
            cmds.setAttr(drv_Jnt[4]+'.tz', -end_dist*dist)
            
        elif not horizontal and axis==(0, 0, 1):
            cmds.setAttr(drv_Jnt[0]+'.jointOrient', 0, 0, -90)
            cmds.setAttr(drv_Jnt[2]+'.jointOrient', 0, 0, -90)
        
            cmds.setAttr(drv_Jnt[0]+'.ty', -dist)
            cmds.setAttr(drv_Jnt[3]+'.ty', end_dist*dist)
            cmds.setAttr(drv_Jnt[2]+'.ty', dist)
            cmds.setAttr(drv_Jnt[4]+'.ty', -end_dist*dist)
        
        #fix the control locators position and orientation
        cmds.parent(top_Loc[0], drv_Jnt[2])
        cmds.setAttr(top_Loc[0]+'.translate', 0, 0, 0)
        cmds.parent(top_Loc[0], w=True)
        cmds.setAttr(top_Loc[0]+'.rotate', 0, 0, 0)
        
        cmds.parent(bttm_Loc[0], drv_Jnt[0])
        cmds.setAttr(bttm_Loc[0]+'.translate', 0, 0, 0)
        cmds.parent(bttm_Loc[0], w=True)
        cmds.setAttr(bttm_Loc[0]+'.rotate', 0, 0, 0)    
        
        cmds.parent(drv_Jnt[2], top_Loc[1])
        cmds.parent(drv_Jnt[1], mid_Loc[2])
        cmds.parent(drv_Jnt[0], bttm_Loc[1])
        
        cmds.parent(aux_Jnt[0], mid_Loc[0])
        #create a nurbs control in order to be used in the ribbon offset
        mid_Ctrl = cmds.circle (c=(0, 0, 0), nr=(1, 0, 0), ch=0, name=name+'_MidCtrl')[0]
        ctrls.renameShape([mid_Ctrl])
        midCtrl = mid_Ctrl
        mid_Ctrl = cmds.group(n=mid_Ctrl+'_Grp', em=True)
        cmds.delete(cmds.parentConstraint(midCtrl, mid_Ctrl, mo=0))
        cmds.parent(midCtrl, mid_Ctrl)
        
        #adjust the realtionship between the locators
        cmds.parent(mid_Ctrl, mid_Loc[2], r=True)
        cmds.parent(drv_Jnt[1], midCtrl)
        cmds.parent([top_Loc[2], mid_Loc[3], bttm_Loc[2]], w=True)
        cmds.makeIdentity(top_Loc[0], apply=True)
        cmds.makeIdentity(mid_Loc[0], apply=True)
        cmds.makeIdentity(bttm_Loc[0], apply=True)
        cmds.parent(top_Loc[2], top_Loc[0])
        cmds.parent(bttm_Loc[2], bttm_Loc[0])
        cmds.parent(mid_Loc[3], aux_Jnt[1]) 
        #create needed constraints in the locators in order to set the top always follow, to the base always aim the middle, to the middle always aim the top
        if firstLimb:
            cmds.aimConstraint(drv_Jnt[1], bttm_Loc[1], offset=(0, 0, 0), weight=1, aimVector=(1, 0, 0), upVector=(0, 0, 1), worldUpType='object', worldUpObject=bttm_Loc[2], name=bttm_Loc[1]+"_AimConstraint")
            cmds.aimConstraint(top_Loc[0], mid_Loc[1], offset=(0, 0, 0), weight=1, aimVector=(1, 0, 0), upVector=(0, 0, 1), worldUpType='object', worldUpObject=mid_Loc[3], name=mid_Loc[1]+"_AimConstraint")
            cmds.aimConstraint(drv_Jnt[1], top_Loc[1], offset=(0, 0, 0), weight=1, aimVector=(-1, 0, 0), upVector=(0, 1, 0), worldUpType='object', worldUpObject=top_Loc[2], name=top_Loc[1]+"_AimConstraint")
        else:
            # bug fix to plane twist
            cmds.aimConstraint(drv_Jnt[1], bttm_Loc[1], offset=(0, 0, 0), weight=1, aimVector=(1, 0, 0), upVector=(0, 1, 0), worldUpType='object', worldUpObject=bttm_Loc[2], name=bttm_Loc[1]+"_AimConstraint")
            cmds.aimConstraint(top_Loc[0], mid_Loc[1], offset=(0, 0, 0), weight=1, aimVector=(-1, 0, 0), upVector=(0, 0, 1), worldUpType='object', worldUpObject=mid_Loc[3], name=mid_Loc[1]+"_AimConstraint")
            cmds.aimConstraint(drv_Jnt[1], top_Loc[1], offset=(0, 0, 0), weight=1, aimVector=(-1, 0, 0), upVector=(0, 0, 1), worldUpType='object', worldUpObject=top_Loc[2], name=top_Loc[1]+"_AimConstraint")
        
        #create a point and orient constraint for the middel control
        cmds.pointConstraint(top_Loc[0], bttm_Loc[0], mid_Loc[0], offset=(0, 0, 0), weight=1, name=mid_Loc[0]+"_PointConstraint")
        ori = cmds.orientConstraint(top_Loc[0], bttm_Loc[0], aux_Jnt[0], offset=(0, 0, 0), weight=1, name=aux_Jnt[0]+"_OrientConstraint")
        
        #ribbon scale (volume variation)
        if numJoints == 3:
            proportionList = [0.5, 1, 0.5]
        elif numJoints == 5:
            proportionList = [0.4, 0.8, 1, 0.8, 0.4]
        elif numJoints == 7:
            proportionList = [0.25, 0.5, 0.75, 1, 0.75, 0.5, 0.25]

        curveInfoNode = cmds.arclen(ribbon+".v[0.5]", constructionHistory=True)
        curveInfoNode = cmds.rename(curveInfoNode, ribbon+"_CurveInfo")
        rbScaleMD = cmds.createNode("multiplyDivide", name=ribbon+"_ScaleCompensate_MD")
        rbNormalizeMD = cmds.createNode("multiplyDivide", name=ribbon+"_Normalize_MD")
        cmds.setAttr(rbNormalizeMD+".operation", 2)
        cmds.connectAttr(curveInfoNode+".arcLength", rbNormalizeMD+".input2X", force=True)
        cmds.connectAttr(rbScaleMD+".outputX", rbNormalizeMD+".input1X", force=True)

        if cmds.objExists(worldRef):
            if not cmds.objExists(worldRef+"."+limbManualVVAttr):
                cmds.addAttr(worldRef, longName=limbVVAttr, attributeType="float", minValue=0, maxValue=1, defaultValue=1, keyable=True)
                cmds.addAttr(worldRef, longName=limbManualVVAttr, attributeType="float", defaultValue=1, keyable=True)
                cmds.addAttr(worldRef, longName=limbMinVVAttr, attributeType="float", defaultValue=0.01, keyable=True)
            cmds.connectAttr(worldRef+".scaleX", rbScaleMD+".input1X", force=True)
        
        #fix group hierarchy
        extraCtrlGrp = cmds.group(empty=True, name=name+"_ExtraBendyCtrl_Grp")
        i = 0
        for jnt in rb_Jnt:
            cmds.makeIdentity(jnt, a=True)
            # create extra control
            extraCtrlName = jnt.replace("_Jnt", "_Ctrl")
            extraCtrl = ctrls.cvSquare(ctrlName=extraCtrlName, r=ctrlRadius)
            extraCtrlList.append(extraCtrl)
            cmds.rotate(0, 0, 90, extraCtrl)
            cmds.makeIdentity(extraCtrl, a=True)
            extraCtrlZero = utils.zeroOut([extraCtrl])[0]
            cmds.parent(extraCtrlZero, extraCtrlGrp)
            cmds.parentConstraint(fols[i], extraCtrlZero, w=1, name=extraCtrlZero+"_ParentConstraint")
            cmds.parentConstraint(extraCtrl, jnt, w=1, name=jnt+"_ParentConstraint")
            cmds.scaleConstraint(extraCtrl, jnt, w=1, name=jnt+"_ScaleConstraint")
            
            # work with volume variation
            rbProportionMD = cmds.createNode("multiplyDivide", name=extraCtrlName.replace("_Ctrl", "_Proportion_MD"))
            rbIntensityMD = cmds.createNode("multiplyDivide", name=extraCtrlName.replace("_Ctrl", "_Intensity_MD"))
            rbAddScalePMA = cmds.createNode("plusMinusAverage", name=extraCtrlName.replace("_Ctrl", "_AddScale_PMA"))
            rbScaleClp = cmds.createNode("clamp", name=extraCtrlName.replace("_Ctrl", "_Scale_Clp"))
            rbBlendCB = cmds.createNode("blendColors", name=extraCtrlName.replace("_Ctrl", "_Blend_BC"))
            cmds.connectAttr(worldRef+"."+limbVVAttr, rbBlendCB+".blender", force=True)
            cmds.setAttr(rbBlendCB+".color2", 1, 1, 1, type="double3")
            cmds.connectAttr(rbNormalizeMD+".outputX", rbProportionMD+".input1X", force=True)
            cmds.setAttr(rbProportionMD+".input2X", proportionList[i])
            cmds.connectAttr(rbProportionMD+".outputX", rbIntensityMD+".input1X", force=True)
            cmds.connectAttr(worldRef+"."+limbManualVVAttr, rbIntensityMD+".input2X", force=True)
            cmds.connectAttr(rbIntensityMD+".outputX", rbAddScalePMA+".input1D[1]", force=True)
            cmds.connectAttr(rbAddScalePMA+".output1D", rbScaleClp+".inputR", force=True)
            cmds.connectAttr(worldRef+"."+limbMinVVAttr, rbScaleClp+".minR")
            cmds.setAttr(rbScaleClp+".maxR", 1000000)
            cmds.connectAttr(rbScaleClp+".outputR", rbBlendCB+".color1.color1R", force=True)
            cmds.connectAttr(rbBlendCB+".output.outputR", extraCtrlZero+".scaleY", force=True)
            cmds.connectAttr(rbBlendCB+".output.outputR", extraCtrlZero+".scaleZ", force=True)
            
            # update i
            i = i + 1
        
        locatorsGrp = cmds.group(bttm_Loc[0], top_Loc[0], mid_Loc[0], n=name+'_Loc_Grp')
        skinJntGrp = cmds.group(rb_Jnt, n=name+'_Jnt_Grp')
        finalSystemGrp = cmds.group(ribbon, locatorsGrp, skinJntGrp, n=name+'_RibbonSystem_Grp')
        
        #do the controller joints skin and the ribbon
        ribbonShape = cmds.listRelatives(ribbon, shapes=True)
        skin = cmds.skinCluster(drv_Jnt[0:3], ribbonShape, tsb=True, mi=2, dr=1)
        
        #skin presets for the ribbon (that's amazing!)
        if not horizontal:
            if numJoints == 3:
                cmds.skinPercent(skin[0], ribbon + '.cv[0:1][5]', tv=(drv_Jnt[2], 1))
                cmds.skinPercent(skin[0], ribbon + '.cv[0:1][4]', tv=[(drv_Jnt[2], 0.6), (drv_Jnt[1], 0.4)])
                cmds.skinPercent(skin[0], ribbon + '.cv[0:1][3]', tv=[(drv_Jnt[2], 0.2), (drv_Jnt[1], 0.8)])
                cmds.skinPercent(skin[0], ribbon + '.cv[0:1][2]', tv=[(drv_Jnt[0], 0.2), (drv_Jnt[1], 0.8)])
                cmds.skinPercent(skin[0], ribbon + '.cv[0:1][1]', tv=[(drv_Jnt[0], 0.6), (drv_Jnt[1], 0.4)])
                cmds.skinPercent(skin[0], ribbon + '.cv[0:1][0]', tv=(drv_Jnt[0], 1))

            elif numJoints == 5:
                cmds.skinPercent(skin[0], ribbon + '.cv[0:1][7]', tv=(drv_Jnt[2], 1))
                cmds.skinPercent(skin[0], ribbon + '.cv[0:1][6]', tv=[(drv_Jnt[2], 0.80), (drv_Jnt[1], 0.2)])
                cmds.skinPercent(skin[0], ribbon + '.cv[0:1][5]', tv=[(drv_Jnt[2], 0.5), (drv_Jnt[1], 0.5)])
                cmds.skinPercent(skin[0], ribbon + '.cv[0:1][4]', tv=[(drv_Jnt[2], 0.25), (drv_Jnt[1], 0.75)])
                cmds.skinPercent(skin[0], ribbon + '.cv[0:1][3]', tv=[(drv_Jnt[0], 0.25), (drv_Jnt[1], 0.75)])
                cmds.skinPercent(skin[0], ribbon + '.cv[0:1][2]', tv=[(drv_Jnt[0], 0.5), (drv_Jnt[1], 0.5)])
                cmds.skinPercent(skin[0], ribbon + '.cv[0:1][1]', tv=[(drv_Jnt[0], 0.8), (drv_Jnt[1], 0.2)])
                cmds.skinPercent(skin[0], ribbon + '.cv[0:1][0]', tv=(drv_Jnt[0], 1))
            elif numJoints == 7:
                cmds.skinPercent(skin[0], ribbon + '.cv[0:1][9]', tv=(drv_Jnt[2], 1))
                cmds.skinPercent(skin[0], ribbon + '.cv[0:1][8]', tv=[(drv_Jnt[2], 0.85), (drv_Jnt[1], 0.15)])
                cmds.skinPercent(skin[0], ribbon + '.cv[0:1][7]', tv=[(drv_Jnt[2], 0.6), (drv_Jnt[1], 0.4)])
                cmds.skinPercent(skin[0], ribbon + '.cv[0:1][6]', tv=[(drv_Jnt[2], 0.35), (drv_Jnt[1], 0.65)])
                cmds.skinPercent(skin[0], ribbon + '.cv[0:1][5]', tv=[(drv_Jnt[2], 0.25), (drv_Jnt[1], 0.75)])
                cmds.skinPercent(skin[0], ribbon + '.cv[0:1][4]', tv=[(drv_Jnt[0], 0.25), (drv_Jnt[1], 0.75)])
                cmds.skinPercent(skin[0], ribbon + '.cv[0:1][3]', tv=[(drv_Jnt[0], 0.35), (drv_Jnt[1], 0.65)])
                cmds.skinPercent(skin[0], ribbon + '.cv[0:1][2]', tv=[(drv_Jnt[0], 0.6), (drv_Jnt[1], 0.4)])
                cmds.skinPercent(skin[0], ribbon + '.cv[0:1][1]', tv=[(drv_Jnt[0], 0.85), (drv_Jnt[1], 0.15)])
                cmds.skinPercent(skin[0], ribbon + '.cv[0:1][0]', tv=(drv_Jnt[0], 1))
        else:
            if numJoints == 3:
                cmds.skinPercent(skin[0], ribbon + '.cv[5][0:1]', tv=(drv_Jnt[2], 1))
                cmds.skinPercent(skin[0], ribbon + '.cv[4][0:1]', tv=[(drv_Jnt[2], 0.6), (drv_Jnt[1], 0.4)])
                cmds.skinPercent(skin[0], ribbon + '.cv[3][0:1]', tv=[(drv_Jnt[2], 0.2), (drv_Jnt[1], 0.8)])
                cmds.skinPercent(skin[0], ribbon + '.cv[2][0:1]', tv=[(drv_Jnt[0], 0.2), (drv_Jnt[1], 0.8)])
                cmds.skinPercent(skin[0], ribbon + '.cv[1][0:1]', tv=[(drv_Jnt[0], 0.6), (drv_Jnt[1], 0.4)])
                cmds.skinPercent(skin[0], ribbon + '.cv[0][0:1]', tv=(drv_Jnt[0], 1))
            elif numJoints == 5:
                cmds.skinPercent(skin[0], ribbon + '.cv[7][0:1]', tv=(drv_Jnt[2], 1))
                cmds.skinPercent(skin[0], ribbon + '.cv[6][0:1]', tv=[(drv_Jnt[2], 0.80), (drv_Jnt[1], 0.2)])
                cmds.skinPercent(skin[0], ribbon + '.cv[5][0:1]', tv=[(drv_Jnt[2], 0.5), (drv_Jnt[1], 0.5)])
                cmds.skinPercent(skin[0], ribbon + '.cv[4][0:1]', tv=[(drv_Jnt[2], 0.25), (drv_Jnt[1], 0.75)])
                cmds.skinPercent(skin[0], ribbon + '.cv[3][0:1]', tv=[(drv_Jnt[0], 0.25), (drv_Jnt[1], 0.75)])
                cmds.skinPercent(skin[0], ribbon + '.cv[2][0:1]', tv=[(drv_Jnt[0], 0.5), (drv_Jnt[1], 0.5)])
                cmds.skinPercent(skin[0], ribbon + '.cv[1][0:1]', tv=[(drv_Jnt[0], 0.8), (drv_Jnt[1], 0.2)])
                cmds.skinPercent(skin[0], ribbon + '.cv[0][0:1]', tv=(drv_Jnt[0], 1))
            elif numJoints == 7:
                cmds.skinPercent(skin[0], ribbon + '.cv[9][0:1]', tv=(drv_Jnt[2], 1))
                cmds.skinPercent(skin[0], ribbon + '.cv[8][0:1]', tv=[(drv_Jnt[2], 0.85), (drv_Jnt[1], 0.15)])
                cmds.skinPercent(skin[0], ribbon + '.cv[7][0:1]', tv=[(drv_Jnt[2], 0.6), (drv_Jnt[1], 0.4)])
                cmds.skinPercent(skin[0], ribbon + '.cv[6][0:1]', tv=[(drv_Jnt[2], 0.35), (drv_Jnt[1], 0.65)])
                cmds.skinPercent(skin[0], ribbon + '.cv[5][0:1]', tv=[(drv_Jnt[2], 0.25), (drv_Jnt[1], 0.75)])
                cmds.skinPercent(skin[0], ribbon + '.cv[4][0:1]', tv=[(drv_Jnt[0], 0.25), (drv_Jnt[1], 0.75)])
                cmds.skinPercent(skin[0], ribbon + '.cv[3][0:1]', tv=[(drv_Jnt[0], 0.35), (drv_Jnt[1], 0.65)])
                cmds.skinPercent(skin[0], ribbon + '.cv[2][0:1]', tv=[(drv_Jnt[0], 0.6), (drv_Jnt[1], 0.4)])
                cmds.skinPercent(skin[0], ribbon + '.cv[1][0:1]', tv=[(drv_Jnt[0], 0.85), (drv_Jnt[1], 0.15)])
                cmds.skinPercent(skin[0], ribbon + '.cv[0][0:1]', tv=(drv_Jnt[0], 1))
        constr = []
        if guias:
            top = guias[0]
            bottom = guias[1]
            constr.append(cmds.parentConstraint(top, bttm_Loc[0], mo=False, name=bttm_Loc[0]+"_ParentConstraint"))
            constr.append(cmds.parentConstraint(bottom, top_Loc[0], mo=False, name=top_Loc[0]+"_ParentConstraint"))
        
        #fix orientation issues
        cmds.delete(ori)
        cmds.orientConstraint(bttm_Loc[0], aux_Jnt[0], weight=0.5, mo=True, name=aux_Jnt[0]+"_OrientConstraint")
        
        #fix loc_Grp scale
        if guias:
            from math import sqrt, pow
            auxLoc1 = cmds.spaceLocator(name='auxLoc1')[0]
            auxLoc2 = cmds.spaceLocator(name='auxLoc2')[0]
            cmds.delete(cmds.parentConstraint(top, auxLoc1, mo=False, w=1))
            cmds.delete(cmds.parentConstraint(bottom, auxLoc2, mo=False, w=1))
            a = cmds.xform(auxLoc1, ws=True, translation=True, q=True)
            b = cmds.xform(auxLoc2, ws=True, translation=True, q=True)
            
            dist = sqrt(pow(a[0]-b[0], 2.0)+pow(a[1]-b[1], 2.0)+pow(a[2]-b[2], 2.0))
            scale = dist/float(numJoints)
            
            cmds.setAttr(locatorsGrp+'.s', scale, scale, scale)
        
            cmds.delete(auxLoc1, auxLoc2)
        
        # baseTwist:
        if not upCtrl == None:
            bttm_LocGrp = cmds.group(bttm_Loc[2], name=bttm_Loc[2]+"_Grp")
            bttm_LocPos = cmds.xform(bttm_Loc[0], query=True, worldSpace=True, translation=True)
            cmds.move(bttm_LocPos[0], bttm_LocPos[1], bttm_LocPos[2], bttm_LocGrp+".scalePivot", bttm_LocGrp+".rotatePivot", absolute=True)
            cmds.connectAttr(upCtrl+".baseTwist", bttm_LocGrp+".rotateZ", force=True)
        
        #updating values
        cmds.setAttr(rbScaleMD+".input2X", cmds.getAttr(curveInfoNode+".arcLength"))
        for jnt in rb_Jnt:
            rbAddScalePMA = jnt.replace("_Jnt", "_AddScale_PMA")
            cmds.setAttr(rbAddScalePMA+".input1D[0]", 1-cmds.getAttr(rbAddScalePMA+".input1D[1]"))

        #change renderStats
        ribbonShape = cmds.listRelatives(ribbon, s=True, f=True)[0]
        
        cmds.setAttr(ribbonShape+'.castsShadows', 0)
        cmds.setAttr(ribbonShape+'.receiveShadows', 0)
        cmds.setAttr(ribbonShape+'.motionBlur', 0)
        cmds.setAttr(ribbonShape+'.primaryVisibility', 0)
        cmds.setAttr(ribbonShape+'.smoothShading', 0)
        cmds.setAttr(ribbonShape+'.visibleInReflections', 0)
        cmds.setAttr(ribbonShape+'.visibleInRefractions', 0)
        cmds.setAttr(ribbonShape+'.doubleSided', 1)
        
        retDict['name'] = name
        retDict['locsList'] = [top_Loc[0], mid_Loc[0], bttm_Loc[0]]
        retDict['skinJointsList'] =  rb_Jnt
        retDict['scaleGrp'] = locatorsGrp
        retDict['finalGrp'] = finalSystemGrp
        retDict['middleCtrl'] = mid_Ctrl
        retDict['constraints'] = constr
        retDict['bendGrpList'] = [top_Loc[0], bttm_Loc[0]]
        retDict['extraCtrlGrp'] = extraCtrlGrp
        retDict['extraCtrlList'] = extraCtrlList
        retDict['rbScaleMD'] = rbScaleMD
        retDict['rbNormalizeMD'] = rbNormalizeMD
        cmds.setAttr(finalSystemGrp+'.v', v)
        return retDict
예제 #8
0
def createRibbon(axis=(0, 0, 1),
                 name='xxxx',
                 horizontal=False,
                 numJoints=3,
                 guias=None,
                 v=True,
                 s=0,
                 firstLimb=True,
                 upCtrl=None,
                 ctrlRadius=1,
                 worldRef="worldRef"):
    retDict = {}

    #define variables
    top_Loc = []
    mid_Loc = []
    bttm_Loc = []
    rb_Jnt = []
    drv_Jnt = []
    fols = []
    aux_Jnt = []
    ribbon = ''
    extraCtrlList = []

    #define attributes
    limbManualVVAttr = "limbManualVolume"
    limbVVAttr = "limbVolumeVariation"
    limbMinVVAttr = "limbMinVolume"

    #create a nurbsPlane based in the choose orientation option
    if horizontal:
        ribbon = cmds.nurbsPlane(ax=axis,
                                 w=numJoints,
                                 lr=(1 / float(numJoints)),
                                 d=3,
                                 u=numJoints,
                                 v=1,
                                 ch=0,
                                 name=name + '_Plane')[0]
        cmds.rebuildSurface(ribbon,
                            ch=0,
                            rpo=1,
                            rt=0,
                            end=1,
                            kr=0,
                            kcp=0,
                            kc=0,
                            sv=1,
                            du=3,
                            dv=1,
                            tol=0.01,
                            fr=0,
                            dir=1)
    else:
        ribbon = cmds.nurbsPlane(ax=axis,
                                 w=1,
                                 lr=numJoints,
                                 d=3,
                                 u=1,
                                 v=numJoints,
                                 ch=0,
                                 name=name + '_Plane')[0]
        cmds.rebuildSurface(ribbon,
                            ch=0,
                            rpo=1,
                            rt=0,
                            end=1,
                            kr=0,
                            kcp=0,
                            kc=0,
                            su=1,
                            du=1,
                            dv=3,
                            tol=0.01,
                            fr=0,
                            dir=0)
    # make this ribbonNurbsPlane as not skinable from dpAR_UI:
    cmds.addAttr(ribbon,
                 longName="doNotSkinIt",
                 attributeType="bool",
                 keyable=True)
    cmds.setAttr(ribbon + ".doNotSkinIt", 1)
    #call the function to create follicles and joint in the nurbsPlane
    results = createFollicles(rib=ribbon,
                              num=numJoints,
                              name=name,
                              horizontal=horizontal)
    rb_Jnt = results[0]
    fols = results[1]
    #create locator controls for the middle of the ribbon
    mid_Loc.append(cmds.spaceLocator(name=name + '_Mid_Pos_Loc')[0])
    mid_Loc.append(cmds.spaceLocator(name=name + '_Mid_Aim_Loc')[0])
    mid_Loc.append(cmds.spaceLocator(name=name + '_Mid_Off_Loc')[0])
    mid_Loc.append(cmds.spaceLocator(name=name + '_Mid_Up_Loc')[0])
    #parent correctly the middle locators
    cmds.parent(mid_Loc[2], mid_Loc[1], relative=True)
    cmds.parent(mid_Loc[1], mid_Loc[0], relative=True)
    cmds.parent(mid_Loc[3], mid_Loc[0], relative=True)
    #create the locators controls for the top of the ribbon
    top_Loc.append(cmds.spaceLocator(name=name + '_Top_Pos_Loc')[0])
    top_Loc.append(cmds.spaceLocator(name=name + '_Top_Aim_Loc')[0])
    top_Loc.append(cmds.spaceLocator(name=name + '_Top_Up_Loc')[0])
    #parent correctly the top locators
    cmds.parent(top_Loc[1], top_Loc[0], relative=True)
    cmds.parent(top_Loc[2], top_Loc[0], relative=True)
    #create the locators for the end of the ribbon
    bttm_Loc.append(cmds.spaceLocator(name=name + '_Bttm_Pos_Loc')[0])
    bttm_Loc.append(cmds.spaceLocator(name=name + '_Bttm_Aim_Loc')[0])
    bttm_Loc.append(cmds.spaceLocator(name=name + '_Bttm_Up_Loc')[0])
    #parent correctly the bottom locators
    cmds.parent(bttm_Loc[1], bttm_Loc[0], relative=True)
    cmds.parent(bttm_Loc[2], bttm_Loc[0], relative=True)

    #put the top locators in the same place of the top joint
    cmds.parent(top_Loc[0], fols[len(fols) - 1], relative=True)
    cmds.parent(top_Loc[0], w=True)

    #put the bottom locators in the same place of the bottom joint
    cmds.parent(bttm_Loc[0], fols[0], relative=True)
    cmds.parent(bttm_Loc[0], w=True)
    cmds.select(clear=True)

    #create the joints that will be used to control the ribbon
    drv_Jnt = cmds.duplicate(
        [rb_Jnt[0], rb_Jnt[(len(rb_Jnt) - 1) / 2], rb_Jnt[len(rb_Jnt) - 1]])
    dup = cmds.duplicate([drv_Jnt[0], drv_Jnt[2]])
    drv_Jnt.append(dup[0])
    drv_Jnt.append(dup[1])
    #cmds.parent(drv_Jnt, w=True)
    for jnt in drv_Jnt:
        cmds.joint(jnt, e=True, oj='none', ch=True, zso=True)
        cmds.setAttr(jnt + '.radius', cmds.getAttr(jnt + '.radius') + 0.5)
    #rename created joints
    drv_Jnt[0] = cmds.rename(drv_Jnt[0], name + '_Drv_Bttm_Jxt')
    drv_Jnt[1] = cmds.rename(drv_Jnt[1], name + '_Drv_Mid_Jxt')
    drv_Jnt[2] = cmds.rename(drv_Jnt[2], name + '_Drv_Top_Jxt')
    drv_Jnt[3] = cmds.rename(drv_Jnt[3], name + '_Drv_Bttm_End')
    drv_Jnt[4] = cmds.rename(drv_Jnt[4], name + '_Drv_Top_End')

    #place joints correctly accordaly with the user options choose
    if (horizontal and axis == (1, 0, 0)) or (horizontal
                                              and axis == (0, 0, 1)):
        cmds.setAttr(bttm_Loc[2] + '.translateY', 2)
        cmds.setAttr(top_Loc[2] + '.translateY', 2)
        cmds.setAttr(mid_Loc[3] + '.translateY', 2)
    elif (horizontal and axis == (0, 1, 0)) or (not horizontal
                                                and axis == (1, 0, 0)):
        cmds.setAttr(bttm_Loc[2] + '.translateZ', 2)
        cmds.setAttr(top_Loc[2] + '.translateZ', 2)
        cmds.setAttr(mid_Loc[3] + '.translateZ', 2)
    elif not horizontal and axis == (0, 1, 0) or (not horizontal
                                                  and axis == (0, 0, 1)):
        cmds.setAttr(bttm_Loc[2] + '.translateX', 2)
        cmds.setAttr(top_Loc[2] + '.translateX', 2)
        cmds.setAttr(mid_Loc[3] + '.translateX', 2)
    elif horizontal and axis == (0, 0, -1):
        if firstLimb:
            cmds.setAttr(bttm_Loc[2] + '.translateY', 2)
            cmds.setAttr(top_Loc[2] + '.translateX', -2)
            cmds.setAttr(mid_Loc[3] + '.translateX', -2)
            cmds.setAttr(mid_Loc[3] + '.translateY', 2)
        else:
            if s == 0:
                cmds.setAttr(bttm_Loc[2] + '.translateX', -2)
                cmds.setAttr(top_Loc[2] + '.translateY', -2)
                cmds.setAttr(mid_Loc[3] + '.translateX', -2)
                cmds.setAttr(mid_Loc[3] + '.translateY', 2)
            else:
                cmds.setAttr(bttm_Loc[2] + '.translateX', -2)
                cmds.setAttr(top_Loc[2] + '.translateY', -2)
                cmds.setAttr(mid_Loc[3] + '.translateX', -2)
                cmds.setAttr(mid_Loc[3] + '.translateY', 2)

    #create auxiliary joints that will be used to control the ribbon
    aux_Jnt.append(cmds.duplicate(drv_Jnt[1], name=name + '_Jxt_Rot')[0])
    cmds.setAttr(aux_Jnt[0] + '.jointOrient', 0, 0, 0)
    aux_Jnt.append(cmds.duplicate(aux_Jnt[0], name=name + '_Jxt_Rot_End')[0])

    cmds.parent(aux_Jnt[1], mid_Loc[3])
    cmds.setAttr(aux_Jnt[1] + '.translate', 0, 0, 0)
    cmds.parent(aux_Jnt[1], aux_Jnt[0])
    cmds.parent(mid_Loc[3], aux_Jnt[1])
    #calculate the adjust for the new chain position
    dist = float(numJoints) / 2.0
    end_dist = (1 / float(numJoints))
    cmds.parent(drv_Jnt[3], drv_Jnt[0])
    cmds.parent(drv_Jnt[4], drv_Jnt[2])

    #adjust the joints orientation and position based in the options choose from user
    if horizontal and axis == (1, 0, 0):
        cmds.setAttr(drv_Jnt[0] + '.jointOrient', 0, 90, 0)
        cmds.setAttr(drv_Jnt[2] + '.jointOrient', 0, 90, 0)

        cmds.setAttr(drv_Jnt[0] + '.tz', -dist)
        cmds.setAttr(drv_Jnt[3] + '.tz', end_dist * dist)
        cmds.setAttr(drv_Jnt[2] + '.tz', dist)
        cmds.setAttr(drv_Jnt[4] + '.tz', -end_dist * dist)

    elif horizontal and axis == (0, 1, 0):
        cmds.setAttr(drv_Jnt[0] + '.jointOrient', 0, 0, 0)
        cmds.setAttr(drv_Jnt[2] + '.jointOrient', 0, 0, 0)

        cmds.setAttr(drv_Jnt[0] + '.tx', -dist)
        cmds.setAttr(drv_Jnt[3] + '.tx', end_dist * dist)
        cmds.setAttr(drv_Jnt[2] + '.tx', dist)
        cmds.setAttr(drv_Jnt[4] + '.tx', -end_dist * dist)

    elif horizontal and axis == (0, 0, 1):
        cmds.setAttr(drv_Jnt[0] + '.jointOrient', 0, 0, 0)
        cmds.setAttr(drv_Jnt[2] + '.jointOrient', 0, 0, 0)

        cmds.setAttr(drv_Jnt[0] + '.tx', -dist)
        cmds.setAttr(drv_Jnt[3] + '.tx', end_dist * dist)
        cmds.setAttr(drv_Jnt[2] + '.tx', dist)
        cmds.setAttr(drv_Jnt[4] + '.tx', -end_dist * dist)

    elif horizontal and axis == (0, 0, -1):
        cmds.setAttr(drv_Jnt[0] + '.jointOrient', 0, 0, 0)
        cmds.setAttr(drv_Jnt[2] + '.jointOrient', 0, 0, 0)

        cmds.setAttr(drv_Jnt[0] + '.tx', -dist)
        cmds.setAttr(drv_Jnt[3] + '.tx', end_dist * dist)
        cmds.setAttr(drv_Jnt[2] + '.tx', dist)
        cmds.setAttr(drv_Jnt[4] + '.tx', -end_dist * dist)

    elif not horizontal and axis == (1, 0, 0):
        cmds.setAttr(drv_Jnt[0] + '.jointOrient', 0, 0, -90)
        cmds.setAttr(drv_Jnt[2] + '.jointOrient', 0, 0, -90)

        cmds.setAttr(drv_Jnt[0] + '.ty', -dist)
        cmds.setAttr(drv_Jnt[3] + '.ty', end_dist * dist)
        cmds.setAttr(drv_Jnt[2] + '.ty', dist)
        cmds.setAttr(drv_Jnt[4] + '.ty', -end_dist * dist)

    elif not horizontal and axis == (0, 1, 0):
        cmds.setAttr(drv_Jnt[0] + '.jointOrient', 0, 90, 0)
        cmds.setAttr(drv_Jnt[2] + '.jointOrient', 0, 90, 0)

        cmds.setAttr(drv_Jnt[0] + '.tz', -dist)
        cmds.setAttr(drv_Jnt[3] + '.tz', end_dist * dist)
        cmds.setAttr(drv_Jnt[2] + '.tz', dist)
        cmds.setAttr(drv_Jnt[4] + '.tz', -end_dist * dist)

    elif not horizontal and axis == (0, 0, 1):
        cmds.setAttr(drv_Jnt[0] + '.jointOrient', 0, 0, -90)
        cmds.setAttr(drv_Jnt[2] + '.jointOrient', 0, 0, -90)

        cmds.setAttr(drv_Jnt[0] + '.ty', -dist)
        cmds.setAttr(drv_Jnt[3] + '.ty', end_dist * dist)
        cmds.setAttr(drv_Jnt[2] + '.ty', dist)
        cmds.setAttr(drv_Jnt[4] + '.ty', -end_dist * dist)

    #fix the control locators position and orientation
    cmds.parent(top_Loc[0], drv_Jnt[2])
    cmds.setAttr(top_Loc[0] + '.translate', 0, 0, 0)
    cmds.parent(top_Loc[0], w=True)
    cmds.setAttr(top_Loc[0] + '.rotate', 0, 0, 0)

    cmds.parent(bttm_Loc[0], drv_Jnt[0])
    cmds.setAttr(bttm_Loc[0] + '.translate', 0, 0, 0)
    cmds.parent(bttm_Loc[0], w=True)
    cmds.setAttr(bttm_Loc[0] + '.rotate', 0, 0, 0)

    cmds.parent(drv_Jnt[2], top_Loc[1])
    cmds.parent(drv_Jnt[1], mid_Loc[2])
    cmds.parent(drv_Jnt[0], bttm_Loc[1])

    cmds.parent(aux_Jnt[0], mid_Loc[0])
    #create a nurbs control in order to be used in the ribbon offset
    mid_Ctrl = cmds.circle(c=(0, 0, 0),
                           nr=(1, 0, 0),
                           ch=0,
                           name=name + '_MidCtrl')[0]
    ctrls.renameShape([mid_Ctrl])
    midCtrl = mid_Ctrl
    mid_Ctrl = cmds.group(n=mid_Ctrl + '_Grp', em=True)
    cmds.delete(cmds.parentConstraint(midCtrl, mid_Ctrl, mo=0))
    cmds.parent(midCtrl, mid_Ctrl)

    #adjust the realtionship between the locators
    cmds.parent(mid_Ctrl, mid_Loc[2], r=True)
    cmds.parent(drv_Jnt[1], midCtrl)
    cmds.parent([top_Loc[2], mid_Loc[3], bttm_Loc[2]], w=True)
    cmds.makeIdentity(top_Loc[0], apply=True)
    cmds.makeIdentity(mid_Loc[0], apply=True)
    cmds.makeIdentity(bttm_Loc[0], apply=True)
    cmds.parent(top_Loc[2], top_Loc[0])
    cmds.parent(bttm_Loc[2], bttm_Loc[0])
    cmds.parent(mid_Loc[3], aux_Jnt[1])
    #create needed constraints in the locators in order to set the top always follow, to the base always aim the middle, to the middle always aim the top
    if firstLimb:
        cmds.aimConstraint(drv_Jnt[1],
                           bttm_Loc[1],
                           offset=(0, 0, 0),
                           weight=1,
                           aimVector=(1, 0, 0),
                           upVector=(0, 0, 1),
                           worldUpType='object',
                           worldUpObject=bttm_Loc[2],
                           name=bttm_Loc[1] + "_AimConstraint")
        cmds.aimConstraint(top_Loc[0],
                           mid_Loc[1],
                           offset=(0, 0, 0),
                           weight=1,
                           aimVector=(1, 0, 0),
                           upVector=(0, 0, 1),
                           worldUpType='object',
                           worldUpObject=mid_Loc[3],
                           name=mid_Loc[1] + "_AimConstraint")
        cmds.aimConstraint(drv_Jnt[1],
                           top_Loc[1],
                           offset=(0, 0, 0),
                           weight=1,
                           aimVector=(-1, 0, 0),
                           upVector=(0, 1, 0),
                           worldUpType='object',
                           worldUpObject=top_Loc[2],
                           name=top_Loc[1] + "_AimConstraint")
    else:
        # bug fix to plane twist
        cmds.aimConstraint(drv_Jnt[1],
                           bttm_Loc[1],
                           offset=(0, 0, 0),
                           weight=1,
                           aimVector=(1, 0, 0),
                           upVector=(0, 1, 0),
                           worldUpType='object',
                           worldUpObject=bttm_Loc[2],
                           name=bttm_Loc[1] + "_AimConstraint")
        cmds.aimConstraint(top_Loc[0],
                           mid_Loc[1],
                           offset=(0, 0, 0),
                           weight=1,
                           aimVector=(-1, 0, 0),
                           upVector=(0, 0, 1),
                           worldUpType='object',
                           worldUpObject=mid_Loc[3],
                           name=mid_Loc[1] + "_AimConstraint")
        cmds.aimConstraint(drv_Jnt[1],
                           top_Loc[1],
                           offset=(0, 0, 0),
                           weight=1,
                           aimVector=(-1, 0, 0),
                           upVector=(0, 0, 1),
                           worldUpType='object',
                           worldUpObject=top_Loc[2],
                           name=top_Loc[1] + "_AimConstraint")

    #create a point and orient constraint for the middel control
    cmds.pointConstraint(top_Loc[0],
                         bttm_Loc[0],
                         mid_Loc[0],
                         offset=(0, 0, 0),
                         weight=1,
                         name=mid_Loc[0] + "_PointConstraint")
    ori = cmds.orientConstraint(top_Loc[0],
                                bttm_Loc[0],
                                aux_Jnt[0],
                                offset=(0, 0, 0),
                                weight=1,
                                name=aux_Jnt[0] + "_OrientConstraint")

    #ribbon scale (volume variation)
    if numJoints == 3:
        proportionList = [0.5, 1, 0.5]
    elif numJoints == 5:
        proportionList = [0.4, 0.8, 1, 0.8, 0.4]
    elif numJoints == 7:
        proportionList = [0.25, 0.5, 0.75, 1, 0.75, 0.5, 0.25]

    curveInfoNode = cmds.arclen(ribbon + ".v[0.5]", constructionHistory=True)
    curveInfoNode = cmds.rename(curveInfoNode, ribbon + "_CurveInfo")
    rbScaleMD = cmds.createNode("multiplyDivide",
                                name=ribbon + "_ScaleCompensate_MD")
    rbNormalizeMD = cmds.createNode("multiplyDivide",
                                    name=ribbon + "_Normalize_MD")
    cmds.setAttr(rbNormalizeMD + ".operation", 2)
    cmds.connectAttr(curveInfoNode + ".arcLength",
                     rbNormalizeMD + ".input2X",
                     force=True)
    cmds.connectAttr(rbScaleMD + ".outputX",
                     rbNormalizeMD + ".input1X",
                     force=True)

    if cmds.objExists(worldRef):
        if not cmds.objExists(worldRef + "." + limbManualVVAttr):
            cmds.addAttr(worldRef,
                         longName=limbVVAttr,
                         attributeType="float",
                         minValue=0,
                         maxValue=1,
                         defaultValue=1,
                         keyable=True)
            cmds.addAttr(worldRef,
                         longName=limbManualVVAttr,
                         attributeType="float",
                         defaultValue=1,
                         keyable=True)
            cmds.addAttr(worldRef,
                         longName=limbMinVVAttr,
                         attributeType="float",
                         defaultValue=0.01,
                         keyable=True)
        cmds.connectAttr(worldRef + ".scaleX",
                         rbScaleMD + ".input1X",
                         force=True)

    #fix group hierarchy
    extraCtrlGrp = cmds.group(empty=True, name=name + "_ExtraBendyCtrl_Grp")
    i = 0
    for jnt in rb_Jnt:
        cmds.makeIdentity(jnt, a=True)
        # create extra control
        extraCtrlName = jnt.replace("_Jnt", "_Ctrl")
        extraCtrl = ctrls.cvSquare(ctrlName=extraCtrlName, r=ctrlRadius)
        extraCtrlList.append(extraCtrl)
        cmds.rotate(0, 0, 90, extraCtrl)
        cmds.makeIdentity(extraCtrl, a=True)
        extraCtrlZero = utils.zeroOut([extraCtrl])[0]
        cmds.parent(extraCtrlZero, extraCtrlGrp)
        cmds.parentConstraint(fols[i],
                              extraCtrlZero,
                              w=1,
                              name=extraCtrlZero + "_ParentConstraint")
        cmds.parentConstraint(extraCtrl,
                              jnt,
                              w=1,
                              name=jnt + "_ParentConstraint")
        cmds.scaleConstraint(extraCtrl,
                             jnt,
                             w=1,
                             name=jnt + "_ScaleConstraint")

        # work with volume variation
        rbProportionMD = cmds.createNode("multiplyDivide",
                                         name=extraCtrlName.replace(
                                             "_Ctrl", "_Proportion_MD"))
        rbIntensityMD = cmds.createNode("multiplyDivide",
                                        name=extraCtrlName.replace(
                                            "_Ctrl", "_Intensity_MD"))
        rbAddScalePMA = cmds.createNode("plusMinusAverage",
                                        name=extraCtrlName.replace(
                                            "_Ctrl", "_AddScale_PMA"))
        rbScaleClp = cmds.createNode("clamp",
                                     name=extraCtrlName.replace(
                                         "_Ctrl", "_Scale_Clp"))
        rbBlendCB = cmds.createNode("blendColors",
                                    name=extraCtrlName.replace(
                                        "_Ctrl", "_Blend_BC"))
        cmds.connectAttr(worldRef + "." + limbVVAttr,
                         rbBlendCB + ".blender",
                         force=True)
        cmds.setAttr(rbBlendCB + ".color2", 1, 1, 1, type="double3")
        cmds.connectAttr(rbNormalizeMD + ".outputX",
                         rbProportionMD + ".input1X",
                         force=True)
        cmds.setAttr(rbProportionMD + ".input2X", proportionList[i])
        cmds.connectAttr(rbProportionMD + ".outputX",
                         rbIntensityMD + ".input1X",
                         force=True)
        cmds.connectAttr(worldRef + "." + limbManualVVAttr,
                         rbIntensityMD + ".input2X",
                         force=True)
        cmds.connectAttr(rbIntensityMD + ".outputX",
                         rbAddScalePMA + ".input1D[1]",
                         force=True)
        cmds.connectAttr(rbAddScalePMA + ".output1D",
                         rbScaleClp + ".inputR",
                         force=True)
        cmds.connectAttr(worldRef + "." + limbMinVVAttr, rbScaleClp + ".minR")
        cmds.setAttr(rbScaleClp + ".maxR", 1000000)
        cmds.connectAttr(rbScaleClp + ".outputR",
                         rbBlendCB + ".color1.color1R",
                         force=True)
        cmds.connectAttr(rbBlendCB + ".output.outputR",
                         extraCtrlZero + ".scaleY",
                         force=True)
        cmds.connectAttr(rbBlendCB + ".output.outputR",
                         extraCtrlZero + ".scaleZ",
                         force=True)

        # update i
        i = i + 1

    locatorsGrp = cmds.group(bttm_Loc[0],
                             top_Loc[0],
                             mid_Loc[0],
                             n=name + '_Loc_Grp')
    skinJntGrp = cmds.group(rb_Jnt, n=name + '_Jnt_Grp')
    finalSystemGrp = cmds.group(ribbon,
                                locatorsGrp,
                                skinJntGrp,
                                n=name + '_RibbonSystem_Grp')

    #do the controller joints skin and the ribbon
    ribbonShape = cmds.listRelatives(ribbon, shapes=True)
    skin = cmds.skinCluster(drv_Jnt[0:3], ribbonShape, tsb=True, mi=2, dr=1)

    #skin presets for the ribbon (that's amazing!)
    if not horizontal:
        if numJoints == 3:
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[0:1][5]',
                             tv=(drv_Jnt[2], 1))
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[0:1][4]',
                             tv=[(drv_Jnt[2], 0.6), (drv_Jnt[1], 0.4)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[0:1][3]',
                             tv=[(drv_Jnt[2], 0.2), (drv_Jnt[1], 0.8)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[0:1][2]',
                             tv=[(drv_Jnt[0], 0.2), (drv_Jnt[1], 0.8)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[0:1][1]',
                             tv=[(drv_Jnt[0], 0.6), (drv_Jnt[1], 0.4)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[0:1][0]',
                             tv=(drv_Jnt[0], 1))

        elif numJoints == 5:
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[0:1][7]',
                             tv=(drv_Jnt[2], 1))
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[0:1][6]',
                             tv=[(drv_Jnt[2], 0.80), (drv_Jnt[1], 0.2)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[0:1][5]',
                             tv=[(drv_Jnt[2], 0.5), (drv_Jnt[1], 0.5)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[0:1][4]',
                             tv=[(drv_Jnt[2], 0.25), (drv_Jnt[1], 0.75)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[0:1][3]',
                             tv=[(drv_Jnt[0], 0.25), (drv_Jnt[1], 0.75)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[0:1][2]',
                             tv=[(drv_Jnt[0], 0.5), (drv_Jnt[1], 0.5)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[0:1][1]',
                             tv=[(drv_Jnt[0], 0.8), (drv_Jnt[1], 0.2)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[0:1][0]',
                             tv=(drv_Jnt[0], 1))
        elif numJoints == 7:
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[0:1][9]',
                             tv=(drv_Jnt[2], 1))
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[0:1][8]',
                             tv=[(drv_Jnt[2], 0.85), (drv_Jnt[1], 0.15)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[0:1][7]',
                             tv=[(drv_Jnt[2], 0.6), (drv_Jnt[1], 0.4)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[0:1][6]',
                             tv=[(drv_Jnt[2], 0.35), (drv_Jnt[1], 0.65)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[0:1][5]',
                             tv=[(drv_Jnt[2], 0.25), (drv_Jnt[1], 0.75)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[0:1][4]',
                             tv=[(drv_Jnt[0], 0.25), (drv_Jnt[1], 0.75)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[0:1][3]',
                             tv=[(drv_Jnt[0], 0.35), (drv_Jnt[1], 0.65)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[0:1][2]',
                             tv=[(drv_Jnt[0], 0.6), (drv_Jnt[1], 0.4)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[0:1][1]',
                             tv=[(drv_Jnt[0], 0.85), (drv_Jnt[1], 0.15)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[0:1][0]',
                             tv=(drv_Jnt[0], 1))
    else:
        if numJoints == 3:
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[5][0:1]',
                             tv=(drv_Jnt[2], 1))
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[4][0:1]',
                             tv=[(drv_Jnt[2], 0.6), (drv_Jnt[1], 0.4)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[3][0:1]',
                             tv=[(drv_Jnt[2], 0.2), (drv_Jnt[1], 0.8)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[2][0:1]',
                             tv=[(drv_Jnt[0], 0.2), (drv_Jnt[1], 0.8)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[1][0:1]',
                             tv=[(drv_Jnt[0], 0.6), (drv_Jnt[1], 0.4)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[0][0:1]',
                             tv=(drv_Jnt[0], 1))
        elif numJoints == 5:
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[7][0:1]',
                             tv=(drv_Jnt[2], 1))
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[6][0:1]',
                             tv=[(drv_Jnt[2], 0.80), (drv_Jnt[1], 0.2)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[5][0:1]',
                             tv=[(drv_Jnt[2], 0.5), (drv_Jnt[1], 0.5)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[4][0:1]',
                             tv=[(drv_Jnt[2], 0.25), (drv_Jnt[1], 0.75)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[3][0:1]',
                             tv=[(drv_Jnt[0], 0.25), (drv_Jnt[1], 0.75)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[2][0:1]',
                             tv=[(drv_Jnt[0], 0.5), (drv_Jnt[1], 0.5)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[1][0:1]',
                             tv=[(drv_Jnt[0], 0.8), (drv_Jnt[1], 0.2)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[0][0:1]',
                             tv=(drv_Jnt[0], 1))
        elif numJoints == 7:
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[9][0:1]',
                             tv=(drv_Jnt[2], 1))
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[8][0:1]',
                             tv=[(drv_Jnt[2], 0.85), (drv_Jnt[1], 0.15)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[7][0:1]',
                             tv=[(drv_Jnt[2], 0.6), (drv_Jnt[1], 0.4)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[6][0:1]',
                             tv=[(drv_Jnt[2], 0.35), (drv_Jnt[1], 0.65)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[5][0:1]',
                             tv=[(drv_Jnt[2], 0.25), (drv_Jnt[1], 0.75)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[4][0:1]',
                             tv=[(drv_Jnt[0], 0.25), (drv_Jnt[1], 0.75)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[3][0:1]',
                             tv=[(drv_Jnt[0], 0.35), (drv_Jnt[1], 0.65)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[2][0:1]',
                             tv=[(drv_Jnt[0], 0.6), (drv_Jnt[1], 0.4)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[1][0:1]',
                             tv=[(drv_Jnt[0], 0.85), (drv_Jnt[1], 0.15)])
            cmds.skinPercent(skin[0],
                             ribbon + '.cv[0][0:1]',
                             tv=(drv_Jnt[0], 1))
    constr = []
    if guias:
        top = guias[0]
        bottom = guias[1]
        constr.append(
            cmds.parentConstraint(top,
                                  bttm_Loc[0],
                                  mo=False,
                                  name=bttm_Loc[0] + "_ParentConstraint"))
        constr.append(
            cmds.parentConstraint(bottom,
                                  top_Loc[0],
                                  mo=False,
                                  name=top_Loc[0] + "_ParentConstraint"))

    #fix orientation issues
    cmds.delete(ori)
    cmds.orientConstraint(bttm_Loc[0],
                          aux_Jnt[0],
                          weight=0.5,
                          mo=True,
                          name=aux_Jnt[0] + "_OrientConstraint")

    #fix loc_Grp scale
    if guias:
        from math import sqrt, pow
        auxLoc1 = cmds.spaceLocator(name='auxLoc1')[0]
        auxLoc2 = cmds.spaceLocator(name='auxLoc2')[0]
        cmds.delete(cmds.parentConstraint(top, auxLoc1, mo=False, w=1))
        cmds.delete(cmds.parentConstraint(bottom, auxLoc2, mo=False, w=1))
        a = cmds.xform(auxLoc1, ws=True, translation=True, q=True)
        b = cmds.xform(auxLoc2, ws=True, translation=True, q=True)

        dist = sqrt(
            pow(a[0] - b[0], 2.0) + pow(a[1] - b[1], 2.0) +
            pow(a[2] - b[2], 2.0))
        scale = dist / float(numJoints)

        cmds.setAttr(locatorsGrp + '.s', scale, scale, scale)

        cmds.delete(auxLoc1, auxLoc2)

    # baseTwist:
    if not upCtrl == None:
        bttm_LocGrp = cmds.group(bttm_Loc[2], name=bttm_Loc[2] + "_Grp")
        bttm_LocPos = cmds.xform(bttm_Loc[0],
                                 query=True,
                                 worldSpace=True,
                                 translation=True)
        cmds.move(bttm_LocPos[0],
                  bttm_LocPos[1],
                  bttm_LocPos[2],
                  bttm_LocGrp + ".scalePivot",
                  bttm_LocGrp + ".rotatePivot",
                  absolute=True)
        cmds.connectAttr(upCtrl + ".baseTwist",
                         bttm_LocGrp + ".rotateZ",
                         force=True)

    #updating values
    cmds.setAttr(rbScaleMD + ".input2X",
                 cmds.getAttr(curveInfoNode + ".arcLength"))
    for jnt in rb_Jnt:
        rbAddScalePMA = jnt.replace("_Jnt", "_AddScale_PMA")
        cmds.setAttr(rbAddScalePMA + ".input1D[0]",
                     1 - cmds.getAttr(rbAddScalePMA + ".input1D[1]"))

    #change renderStats
    ribbonShape = cmds.listRelatives(ribbon, s=True, f=True)[0]

    cmds.setAttr(ribbonShape + '.castsShadows', 0)
    cmds.setAttr(ribbonShape + '.receiveShadows', 0)
    cmds.setAttr(ribbonShape + '.motionBlur', 0)
    cmds.setAttr(ribbonShape + '.primaryVisibility', 0)
    cmds.setAttr(ribbonShape + '.smoothShading', 0)
    cmds.setAttr(ribbonShape + '.visibleInReflections', 0)
    cmds.setAttr(ribbonShape + '.visibleInRefractions', 0)
    cmds.setAttr(ribbonShape + '.doubleSided', 1)

    retDict['name'] = name
    retDict['locsList'] = [top_Loc[0], mid_Loc[0], bttm_Loc[0]]
    retDict['skinJointsList'] = rb_Jnt
    retDict['scaleGrp'] = locatorsGrp
    retDict['finalGrp'] = finalSystemGrp
    retDict['middleCtrl'] = mid_Ctrl
    retDict['constraints'] = constr
    retDict['bendGrpList'] = [top_Loc[0], bttm_Loc[0]]
    retDict['extraCtrlGrp'] = extraCtrlGrp
    retDict['extraCtrlList'] = extraCtrlList
    retDict['rbScaleMD'] = rbScaleMD
    retDict['rbNormalizeMD'] = rbNormalizeMD
    cmds.setAttr(finalSystemGrp + '.v', v)
    return retDict