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]
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]
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]
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]
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]
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]
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
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