Connect attribute by distance amount

50 views
Skip to first unread message

Francesco

unread,
Jan 24, 2019, 8:11:38 PM1/24/19
to Python Programming for Autodesk Maya
Hi everybody!

I've made this script that creates a ribbon setup between two selected objects, where the user can specify the number of spans of the nurbs plane (which is also the number of follicles and bind joints, as well as the length of the plane) and the number of controllers.to be created. 

Everything works fine except that I'm trying to connect the scale of each controller to the scale of each bind joint (using a plusMinusAverage node maybe?), having the influence of the controller diminish as the bind joint gets further away, until the influence will become zero where a new controller is. I'm not really sure on how to accomplish this, as the number of bind joints and controllers are not set in stone. Any suggestion is welcome!

Here is an example of what I have:

import maya.cmds as cmds

startPointText= "start"
endPointText= "end"
nurbsPlaneSpans= 6
nurbsPlaneCNTLs= 3

#Create NURBS plane (width is equal to number of bind joints that is wanted), and the master groups
ribbonNURBSPlane= cmds.nurbsPlane(p= [0, 0, 0], ax= [0, 1, 0], w= nurbsPlaneSpans, lr= 0.1666666667, d= 3, u= nurbsPlaneSpans, v= 1, ch= False, n= startPointText+ "_NURBS")
ribbonDriverGroup= cmds.group(n= startPointText+ "_ribbon_driver_GRP", em= True)
ribbonBindGroup= cmds.group(n= startPointText+ "_ribbon_bind_GRP", em= True)
cmds.select(d= True)

#Create driver joints, to start the first and last joint at the ends of the NURBS plane
firstRibbonJoint= cmds.joint(position= (nurbsPlaneSpans/ -2, 0, 0), n= startPointText+ "_ribbon_01_JNT", rad= 1)
cmds.select(d= True)
lastRibbonJoint= cmds.joint(position= (nurbsPlaneSpans/ 2, 0, 0), n= startPointText+ "_ribbon_%02d_JNT" %(nurbsPlaneCNTLs), rad= 1)
cmds.select(d= True)
#Get their positions and decrease nurbsPlaneCNTLs amount by 1 for formula
startXYZ= cmds.xform(firstRibbonJoint, query= 1, worldSpace= 1, translation= 1)
endXYZ= cmds.xform(lastRibbonJoint, q= 1, ws= 1, t= 1)
nurbsPlaneCNTLs= nurbsPlaneCNTLs- 1
#Midpoint formula
locationXYZ= startXYZ[0] + (endXYZ[0] - startXYZ[0])/nurbsPlaneCNTLs, startXYZ[1] + (endXYZ[1] - startXYZ[1])/nurbsPlaneCNTLs, startXYZ[2] + (endXYZ[2] - startXYZ[2])/nurbsPlaneCNTLs
cmds.select(d= True)
cmds.joint(p= (locationXYZ[0], locationXYZ[1], locationXYZ[2]), n= startPointText+ "_ribbon_02_JNT", rad= 1)
for i in range(nurbsPlaneCNTLs- 2):
    currentRibbonJointSelection= cmds.ls(sl= True)
    newXYZ= cmds.xform(currentRibbonJointSelection, query= 1, worldSpace= 1, translation= 1)
    #Formula to find the next segment division (new point coordinates plus distance)
    remainderXYZ= newXYZ[0] + (locationXYZ[0] - startXYZ[0]), newXYZ[1] + (locationXYZ[1] - startXYZ[1]), newXYZ[2] + (locationXYZ[2] - startXYZ[2])
    cmds.select(d= True)
    cmds.joint(p= (remainderXYZ[0], remainderXYZ[1], remainderXYZ[2]), n= startPointText+ "_ribbon_%02d_JNT" %(i+ 3), rad= 1)
cmds.reorder(lastRibbonJoint, relative= nurbsPlaneCNTLs- 1)

#Create CNTL and group above each driver joint, and add all to master driver group
cmds.select(startPointText+ "_ribbon*JNT", r= True)
allRibbonDriverJoints= cmds.ls(sl= True)
for jnt in allRibbonDriverJoints:
    currentRibbonJointPosition= cmds.xform(jnt, q= 1, ws= 1, t= 1)
    cmds.spaceLocator(n= jnt[:-4]+ "_CNTL")
    cmds.group(n= jnt[:-4]+ "_GRP")
    cmds.move(currentRibbonJointPosition[0], currentRibbonJointPosition[1], currentRibbonJointPosition[2], r= True)
    cmds.parent(jnt, jnt[:-4]+ "_CNTL")
    cmds.parent(jnt[:-4]+ "_GRP", ribbonDriverGroup)

#Create follicles and name them accordingly
folliclesMasterGRP= cmds.group(n= startPointText+ "_follicles_GRP", em= True)
parameterUFormula= (1.0/ nurbsPlaneSpans)/ 2 #Formula to get the first U coordinate, which needs to be half
parameterUFormulaIncrease= parameterUFormula* 2 #Get the exponent needed to increase the U coordinate after first iteration
for i in range(1, nurbsPlaneSpans+ 1):
    cmds.createNode("follicle")
    cmds.pickWalk(d= "up")
    cmds.rename(startPointText+ "_%02d_FOL" %(i))
    cmds.pickWalk(d= "down")
    currentFollicleShape= cmds.ls(sl= True)[0]
    #Connect them to NURBS plane
    cmds.connectAttr(startPointText+ "_NURBSShape"+ ".local", currentFollicleShape+ ".inputSurface", f= True)
    cmds.connectAttr(startPointText+ "_NURBSShape"+ ".worldMatrix[0]", currentFollicleShape+ ".inputWorldMatrix", f= True)
    cmds.connectAttr(currentFollicleShape+ ".outRotate", startPointText+ "_%02d_FOL" %(i)+ ".rotate", f= True)
    cmds.connectAttr(currentFollicleShape+ ".outTranslate", startPointText+ "_%02d_FOL" %(i)+ ".translate", f= True)
    #Position them on the correct U coordinate
    cmds.setAttr(currentFollicleShape+ ".parameterU", parameterUFormula)
    cmds.setAttr(currentFollicleShape+ ".parameterV", 0.5)
    #Parent follicles under follicle GRP
    cmds.parent(startPointText+ "_%02d_FOL" %(i), folliclesMasterGRP)
    #Increase the U coordinate
    parameterUFormula= parameterUFormula+ parameterUFormulaIncrease

#Select each follicle and create joint underneath
cmds.select(startPointText+ "*FOL", r= True)
allRibbonFollicles= cmds.ls(sl= True)
for fol in allRibbonFollicles:
    cmds.select(fol, r= True)
    cmds.joint(n= fol[:-7]+ "_follicle"+ fol[-7:-4]+ "_JNT", rad= 0.5)

#Select driver joints, NURBS plane, and bind skin
cmds.select(allRibbonDriverJoints, r= True)
cmds.select(ribbonNURBSPlane, add= True)
cmds.skinCluster(toSelectedBones= True, bindMethod= 0, skinMethod= 0, normalizeWeights= 1, weightDistribution= 0, maximumInfluences= 5, obeyMaxInfluences= True, removeUnusedInfluence= True, dropoffRate= 4)

#Hierarchy should be NURBS plane and follicle group under a master group, and driver joints under another master group
cmds.parent(ribbonNURBSPlane, ribbonBindGroup)
cmds.parent(folliclesMasterGRP, ribbonBindGroup)

#Connect the scale of each CNTL to the scale of the closest bind joints, until a new CNTL takes over
"""
This is the part I can't figure out
"""


Reply all
Reply to author
Forward
0 new messages