def buildFk(self): # create the fk controls for i, jnt in enumerate(self.joints): con = control.Control(jnt.replace(nameSpace.JOINT, nameSpace.FK), ) con.create() con.setPosition(self.positions[i]) self.controls.append(con)
def buildChest(self): # create chest control self.chest = control.Control("chest", shape="cube") self.chest.create() self.chest.setPosition(self.positions[1]) cmds.select(self.controlRigJoints[0]) cmds.select(self.controlRigJoints[1], tgl=True) self.chestIKH = cmds.ikHandle( name="chest_IKH", sol="ikSCsolver", )[0] cmds.parent(self.chestIKH, self.chest.getName()) cmds.orientConstraint(self.chest.getName(), self.controlRigJoints[1])
def buildSingle( name, shape="circle", color="yellow", position=(0, 0, 0)): """ Creates a basic joint and control hierarchy :parameters: name : str The PART name of rig. Leave out "_JNT" and "_CON" etc shape: str Takes a shape name to be input into rig_tools.core.control creation color: Also takes in a color to be input into rig_tools.core.control creation """ master = "{0}_GRP".format(name) cmds.createNode("transform", n=master) #create joint cmds.select( cl=True ) jnt = cmds.joint( n=(name + "_JNT") ) #joint null jNull = cmds.group(n=(jnt+"_NULL")) #control conBuffer = control.Control( name = (name+"_CON"), shape=shape, color=color) conBuffer.create() con = conBuffer.getName() #control null cNull = conBuffer.getNull() cmds.parent( jNull, master ) cmds.parent( cNull, master) attrs = ["t", "r", "s"] for attr in attrs: cmds.connectAttr( "{0}.{1}".format(con, attr), "{0}.{1}".format(jnt, attr) ) #position the mofo #cmds.xform( cNull, t=position, ws=True ) #kill it off by selecting the con. It pleases me. cmds.select(con) result = { "master": master, "cNull": cNull, "jNull": jNull, "con": con, "jnt": jnt } return result
def controlUp(self): self.startCtrl = control.Control('start_{0}_{1}{2}'.format( self.name, nameSpace.SPLINE, nameSpace.CONTROL), position=cmds.xform(self.jointList[0], q=1, ws=1, t=1), shape='cross') self.startAim = locator.Locator('start_{0}_{1}'.format( self.name, nameSpace.LOCATOR)) self.midCtrl = control.Control('mid_{0}_{1}{2}'.format( self.name, nameSpace.SPLINE, nameSpace.CONTROL), shape='star') self.endCtrl = control.Control('end_{0}_{1}{2}'.format( self.name, nameSpace.SPLINE, nameSpace.CONTROL), position=cmds.xform(self.jointList[-1], q=1, ws=1, t=1), shape='cross') self.endAim = locator.Locator('end_{0}_{1}'.format( self.name, nameSpace.LOCATOR)) #start control self.startCtrl.create() self.startAim.create() self.startAim.setParent(self.startCtrl.getName()) #snap.. self.startAim.setPosition(cmds.xform(self.jointList[0], q=1, ws=1, t=1)) #mid control self.midCtrl.create() self.midCtrl.setOrientation('x') #end control self.endCtrl.create() self.endAim.create() self.endAim.setParent(self.endCtrl.getName()) #snap.. self.endAim.setPosition(cmds.xform(self.jointList[-1], q=1, ws=1, t=1)) #pointConstrain start and end to mid cmds.pointConstraint(self.startCtrl.getName(), self.endCtrl.getName(), self.midCtrl.getZeroGroup1()) #aim mid to end ZeroGroup1 #cmds.aimConstraint( self.endCtrl.getName(), self.midCtrl.getZeroGroup1(), # aim = [1,0,0], u = [0,1,0], wut = 'objectrotation', wuo= self.startCtrl.getName() ) #aim the start and end locators to mid cmds.aimConstraint(self.midCtrl.getName(), self.startAim.getName(), aim=[1, 0, 0], u=[0, 1, 0], wut='objectrotation', wuo=self.startCtrl.getZeroGroup1()) cmds.aimConstraint(self.midCtrl.getName(), self.endAim.getName(), aim=[-1, 0, 0], u=[0, 1, 0], wut='objectrotation', wuo=self.endCtrl.getZeroGroup1()) #clusters... #startClusters cmds.select('{0}.cv[0:1]'.format(self.getSplineCurve())) startCls = cmds.cluster(envelope=True, n='{0}_startCls'.format(self.name)) #midClusters cmds.select('{0}.cv[2]'.format(self.getSplineCurve())) midCls = cmds.cluster(envelope=True, n='{0}_midCls'.format(self.name)) #endClusters cmds.select('{0}.cv[3:4]'.format(self.getSplineCurve())) endCls = cmds.cluster(envelope=True, n='{0}_endCls'.format(self.name)) #parent those clusters! cmds.parent(startCls, self.startAim.getName()) cmds.parent(midCls, self.midCtrl.getName()) cmds.parent(endCls, self.endAim.getName()) #hide clusters cmds.setAttr('{0}.v'.format(startCls[1]), 0) cmds.setAttr('{0}.v'.format(midCls[1]), 0) cmds.setAttr('{0}.v'.format(endCls[1]), 0)
def setup(self): super(Foot,self).setup() #create an upvector for the foot joints self.footJntUpv = control.Control('{0}_upvGuide'.format(self.getName()), shape='cross') self.footJntUpv.create() cmds.parent( self.footJntUpv.getName(), self.masterGuide.getName()) if self.getSide() == nameSpace.SIDES["left"]: #default positioning going in the order of self.jointList: self.jointPositions = [ (0.25, 0.29, -0.06), #ankle (0.25, 0, 0.644), #ball (0.25, 0, 0.95), #tiptoe (0.25, 0, -0.215), #heel (0.065, 0, 0.5), #inpivot (0.46, 0, 0.5) ] #outp #move the masterguide self.masterGuide.setPosition( (2,0,0) ) #move the upv self.footJntUpv.setPosition( (0.25,1,1) ) elif self.getSide() == nameSpace.SIDES["right"]: #default positioning going in the order of self.jointList: self.jointPositions = [ (-0.25, 0.29, -0.06), #ankle (-0.25, 0, 0.644), #ball (-0.25, 0, 0.95), #tiptoe (-0.25, 0, -0.215), #heel (-0.065, 0, 0.5), #inp (-0.46, 0, 0.5) ] #outp #move the masterguide self.masterGuide.setPosition( (-2,0,0) ) #move the upv self.footJntUpv.setPosition( (-0.25,1,1) ) #add aim and up attr to masterGuide self.aimAttr = attribute.switch(self.masterGuide.getName(), "aim",0, ["x","y","z","-x","-y","-z"], [[1,0,0],[0,1,0],[0,0,1],[-1,0,0],[0,-1,0],[0,0,-1]]) self.upAttr = attribute.switch(self.masterGuide.getName(), "up",0, ["x","y","z","-x","-y","-z"], [[1,0,0],[0,1,0],[0,0,1],[-1,0,0],[0,-1,0],[0,0,-1]]) #iterate through self.jointList #for each listItem in self.jointList parent = self.skeletonGroup for index,jnt in enumerate( self.jointList ): #create joint jnt.create() jnt.setPosition( self.jointPositions[index] ) #if it's not the pivots if (index<4): # set parent jnt.setParent(parent) parent = jnt.getName() #if it's the heel, make it world if (index==3): #no parent cmds.select( jnt.getName() ) cmds.parent( w=True ) #and set joint orientations to zero cmds.setAttr( "{0}.jointOrient".format( jnt.getName() ) ) #if it is, parent them to the ankle else: jnt.setParent(parent) #create guides self.guides.append( self.createGuide(jnt.getName().replace(nameSpace.JOINT,nameSpace.GUIDE), jnt.getName(), jnt.getPosition(), self.masterGuide.getName()) ) #resize those guides. #cmds.select( self.guides[index].getName(),r=True ) cmds.setAttr( "{0}.sx".format(self.guides[index].getName()), 0.15) cmds.setAttr( "{0}.sy".format(self.guides[index].getName()), 0.15) cmds.setAttr( "{0}.sz".format(self.guides[index].getName()), 0.15) aimConstraintList = list() for index,jnt in enumerate( self.jointList ): if ( index < 2): #all others are aimConstrained #aim constraint joint[jnt+1] to joint[jnt] aimCon = cmds.aimConstraint( self.guides[index+1].getName(), self.jointList[index].getName(), worldUpType='object', worldUpObject= self.footJntUpv.getName() ) aimConstraintList.append( aimCon[0] ) cmds.parent(aimConstraintList[index], self.guidesGroup) for cst in aimConstraintList: cmds.connectAttr(self.upAttr, "{0}.upVector".format(cst),f=True) cmds.connectAttr(self.aimAttr, "{0}.aimVector".format(cst),f=True) #cmds.setAttr("{0}.worldUpVector".format( cst ), self.upAttr ) #so that the aim and up are not both x cmds.setAttr("{0}.up".format(self.masterGuide.getName()) ,1) self.strUpAttr = (cmds.getAttr ("{0}.up".format(self.masterGuide.getName()), asString = True)) cmds.select(cl=True)
def build(self): super(Foot,self).build() #get rid of this! cmds.delete( self.footJntUpv.getZeroGroup1() ) #duplicate ball joint self.ankle1.create() self.ankle1.setPosition ( self.ball.getPosition() ) #make it a little bigger cmds.setAttr("{0}.radius".format(self.ankle1.getName()), 2) self.ankle1.setParent( self.heel.getName() ) #rename and move the bind joints to jointgrp self.ankle.setName( self.ankle.getName().replace(nameSpace.JOINT, nameSpace.BINDJOINT) ) self.ball.setName( self.ball.getName().replace(nameSpace.JOINT, nameSpace.BINDJOINT) ) self.tipToe.setName( self.tipToe.getName().replace(nameSpace.JOINT, nameSpace.BINDJOINT) ) #duplicate the bind joints and we'll use them for the ctrl rig self.ballJntRig = joint.Joint( self.ball.getName().replace(nameSpace.JOINT, nameSpace.DRVJOINT), position=self.ball.getPosition(), parent=self.heel.getName) self.toeJntRig = joint.Joint( self.tipToe.getName().replace(nameSpace.JOINT, nameSpace.DRVJOINT), position=self.tipToe.getPosition(), parent=self.ballJntRig.getName()) self.ankleJntRig = joint.Joint( self.ankle.getName().replace(nameSpace.JOINT, nameSpace.DRVJOINT), position=self.ankle.getPosition(), parent=self.ankle1.getName()) self.ballJntRig.create() self.toeJntRig.create() cmds.select(cl=True) self.ankleJntRig.create() self.ankleJntRig.setParent( self.ankle1.getName() ) #parent accordingly #first remove parent on pivots cmds.parent(self.inPivot.getName() ,w=True) cmds.parent(self.outPivot.getName() ,w=True) cmds.select(cl=True) #ikh names self.toeIkh = self.tipToe.getName().replace(nameSpace.BINDJOINT, nameSpace.IK) self.ankleIkh = self.ankle1.getName().replace(nameSpace.JOINT, nameSpace.IK) #ikh applications cmds.ikHandle( sj=self.ballJntRig.getName(), ee=self.toeJntRig.getName(), sol="ikSCsolver", n=self.toeIkh ) cmds.ikHandle( sj=self.ankle1.getName(), ee=self.ankleJntRig.getName(), sol="ikSCsolver", n=self.ankleIkh ) #create sdk nodes tipToeSdk = cmds.createNode('transform', n=self.tipToe.getName().replace( nameSpace.BINDJOINT, 'sdk' )) ankleSdk = cmds.createNode('transform', n=self.ankle.getName().replace( nameSpace.BINDJOINT, 'sdk' )) #pointConstraint ball to ankle1jnt #cmds.pointConstraint( self.ballJntRig.getName(), self.ankle1.getName()) #snap self.snap( self.ball.getName(), tipToeSdk ) self.snap( self.ankle1.getName(), ankleSdk) #create ikh ctrls self.toeCtrl = control.Control( self.tipToe.getName().replace(nameSpace.BINDJOINT, nameSpace.CONTROL), position=self.tipToe.getPosition(), parent=tipToeSdk, shape = "circle" ) self.ankleCtrl = control.Control( self.ankle.getName().replace(nameSpace.BINDJOINT, nameSpace.CONTROL), position=self.ankle.getPosition(), parent=ankleSdk, shape = "circle" ) self.ankleCtrl.create() self.toeCtrl.create() self.toeCtrl.setColor(7) self.toeCtrl.setOrientation( 'z' ) #parent ik handles to ctrls cmds.parent( self.toeIkh, self.toeCtrl.getName() ) cmds.parent( self.ankleIkh, self.ankleCtrl.getName() ) #replace pivot joints with locators self.inPivotLocator = locator.Locator( name="{0}_{1}".format( self.inPivot.getName(), nameSpace.LOCATOR )) self.outPivotLocator = locator.Locator( name="{0}_{1}".format( self.outPivot.getName(), nameSpace.LOCATOR )) self.inPivotLocator.create() self.outPivotLocator.create() #snap! self.snap( self.inPivot.getName(), self.inPivotLocator.getName()) self.snap( self.outPivot.getName(), self.outPivotLocator.getName()) #delete the joints. cmds.delete( self.inPivot.getName()) cmds.delete( self.outPivot.getName()) #now implement the hierarchy cmds.parent( self.outPivotLocator.getName(),self.inPivotLocator.getName()) cmds.parent( self.heel.getName(), self.outPivotLocator.getName()) cmds.parent( tipToeSdk, ankleSdk, self.heel.getName() ) #create foot control self.footCtrl = control.Control( name="{0}_{1}".format( self.getName(), nameSpace.CONTROL), position = self.ankle.getPosition(), parent = self.controlsGroup, shape = 'square') self.footCtrl.create() cmds.parent(self.inPivotLocator.getName(), self.footCtrl.getName()) self.footCtrl.setColor(7) #add attributes cmds.select(self.footCtrl.getName()) cmds.addAttr( ln="footRoll", at="float", max=45, min=-45, k=True) cmds.addAttr( ln="toeBend", at="float", max=45, min=-45, k=True) cmds.addAttr( ln="tilt", at="float", max=45, min=-45, k=True) #set driven keys footRoll = ("{0}.footRoll".format( self.footCtrl.getName() )) toeBend = ("{0}.toeBend".format( self.footCtrl.getName() )) tilt = ("{0}.tilt".format( self.footCtrl.getName() )) #foot roll ''' #ball footRoll animSdk.setDrivenKey(footRoll, 0, "{0}.rx".format(ankleSdk), 0) animSdk.setDrivenKey(footRoll, 45, "{0}.rx".format(ankleSdk), 90) #heel footRoll animSdk.setDrivenKey(footRoll, 0, "{0}.rx".format(self.heel.getName()), 0) animSdk.setDrivenKey(footRoll, -45, "{0}.rx".format(self.heel.getName()), -90) #toe bend animSdk.setDrivenKey(toeBend, 0, "{0}.rx".format(tipToeSdk), 0) animSdk.setDrivenKey(toeBend, 45, "{0}.rx".format(tipToeSdk), 90) animSdk.setDrivenKey(toeBend, -45, "{0}.rx".format(tipToeSdk), -90) #tilt if self.getSide() == nameSpace.SIDES["left"]: animSdk.setDrivenKey(tilt, 0, "{0}.rz".format(self.inPivotLocator.getName()), 0) animSdk.setDrivenKey(tilt, 45, "{0}.rz".format(self.inPivotLocator.getName()), 90) animSdk.setDrivenKey(tilt, 0, "{0}.rz".format(self.outPivotLocator.getName()), 0) animSdk.setDrivenKey(tilt, -45, "{0}.rz".format(self.outPivotLocator.getName()), -90) else: animSdk.setDrivenKey(tilt, 0, "{0}.rz".format(self.inPivotLocator.getName()), 0) animSdk.setDrivenKey(tilt, 45, "{0}.rz".format(self.inPivotLocator.getName()), -90) animSdk.setDrivenKey(tilt, 0, "{0}.rz".format(self.outPivotLocator.getName()), 0) animSdk.setDrivenKey(tilt, -45, "{0}.rz".format(self.outPivotLocator.getName()), 90) ''' #delete the unessecaries cmds.delete( self.noXformGroup, self.hookGroup )
def setup(self): super(FkChain,self).setup() parent = self.skeletonGroup #this builds and names the bind joints self.guides = list() for i,jnt in enumerate(self.fkChainJoints): jnt.create() self.allJoints.append(jnt.getName()) #add to allJoints ^ jnt.setPosition(self.jointPositions[i]) # workaround because setParent is parenting the parent for now cmds.parent(jnt.getName(), parent) self.guides.append( self.createGuide( jnt.getName().replace(nameSpace.BINDJOINT, nameSpace.GUIDE), jnt.getName(), jnt.getPosition(), self.masterGuide.getName() ) ) #parent = jnt.getName() #create an upvector for fkChain self.fkChainUpv = control.Control('{0}_upvGuide'.format(self.getName()), shape='cross') self.fkChainUpv.create() aimConstraintList = list() for index,jnt in enumerate(self.fkChainJoints): #the last joint get's orientConstrained if index == (self.jointCount-1): constraint = cmds.orientConstraint( self.fkChainJoints[index-1].getName(), self.fkChainJoints[index].getName() ) cmds.parent(constraint, self.guidesGroup) else: #all others are aimConstrained #aim constraint joint[jnt+1] to joint[jnt] aimCon = cmds.aimConstraint( self.guides[index+1].getName(), self.fkChainJoints[index].getName(), worldUpType='object', worldUpObject= self.fkChainUpv.getName() ) aimConstraintList.append( aimCon[0] ) cmds.parent(aimConstraintList[index], self.guidesGroup) self.aimAttr = attribute.switch(self.masterGuide.getName(), "aim",0, ["x","y","z","-x","-y","-z"], [[1,0,0],[0,1,0],[0,0,1],[-1,0,0],[0,-1,0],[0,0,-1]]) self.upAttr = attribute.switch(self.masterGuide.getName(), "up",0, ["x","y","z","-x","-y","-z"], [[1,0,0],[0,1,0],[0,0,1],[-1,0,0],[0,-1,0],[0,0,-1]]) for cst in aimConstraintList: cmds.connectAttr(self.upAttr, "{0}.upVector".format(cst),f=True) cmds.connectAttr(self.aimAttr, "{0}.aimVector".format(cst),f=True) #cmds.setAttr("{0}.worldUpVector".format( cst ), self.upAttr ) #so that the aim and up are not both x cmds.setAttr("{0}.up".format(self.masterGuide.getName()) ,1) self.strUpAttr = (cmds.getAttr ("{0}.up".format(self.masterGuide.getName()), asString = True)) cmds.select(cl=True) #move the fkChainUPV somewhere reasonable self.fkChainUpv.setPosition( [-5, 10, 0] ) #and parent it to the masterGuide cmds.parent(self.fkChainUpv.getNull(), self.masterGuide.getName())
def build(self): super(FkChain,self).build() #create ctrls and non hierarchy ctrls self.mainCtrls = list() subCtrls = list() for i, joint in enumerate(self.fkChainJoints): ii = i+1 self.mainCtrls.append( control.Control("{0}{1}_1".format( self.getName(), str(ii) ), position = joint.getPosition(), shape='square') ) self.mainCtrls[i].create() self.mainCtrls[i].setColor(30) #scale self.mainCtrls to be a little bigger cmds.select("{0}.cv[0:4]".format(self.mainCtrls[i].getName(), r=True )) cmds.scale(1.2,1.2,1.2) #point curve in right direction self.mainCtrls[i].setOrientation( self.downAxis ) #build subCtrl? if self.subCtrl : subCtrls.append( control.Control( "{0}{1}_{2}".format( self.getName(), str(ii), nameSpace.SUBCONTROL ), position = joint.getPosition(), shape='circle' ) ) subCtrls[i].create() subCtrls[i].setColor(26) #point curve in right direction subCtrls[i].setOrientation( self.downAxis ) #parent subCtrl to mainCtrl cmds.parent( subCtrls[i].getNull(), self.mainCtrls[i].getName() ) #snap ctrls par = cmds.parentConstraint( joint.getName(), self.mainCtrls[i].getNull()) cmds.delete(par) #parent accordingly #if i is not 0, parent accordingly if (i != 0): cmds.parent(self.mainCtrls[i].getNull(), self.mainCtrls[i-1].getName()) #and zero out zeroGroup1 rotate #cmds.setAttr("{0}.rotate".format(self.mainCtrls[i].getNull()), 0, 0,0) #parent to subCtrl or mainCtrl? if self.subCtrl: #parentConstraint subCtrl to joints cmds.parentConstraint(subCtrls[i].getName(), joint.getName(), mo=True) else: #parentConstraint mainCtrl to joints cmds.parentConstraint(self.mainCtrls[i].getName(), joint.getName(), mo=True) #parent controls to ctrl gorup cmds.parent( self.mainCtrls[0].getNull(), self.controlsGroup) cmds.select(cl=True)
def setup(self): #handle which direction UPV will be in x = 5 y = 0 z = 0 #control and grp frz creation #organize and place into groups #ctrlGroup self.ctrlGrp = cmds.createNode("transform", n="{0}_ctrl_grp".format(self.getName())) #Master Group self.masterGrp = cmds.createNode("transform", n="{0}_rbn_grp".format( self.getName())) for i in range(int(self.jointAmmount)): inc = i + 1 #check if it's the MID!!! if i == self.middleList: #ctrl creation midCtrl = control.Control("{0}_ctrl{1}".format( self.nameSpace, inc), (0, i, 0), shape="star") midCtrl.create() midCtrl.setColor(17) self.ribbonCtrls.append(midCtrl.getName()) #joint creation midJnt = joint.Joint("{0}_{1}{2}".format( self.nameSpace, nameSpace.JOINT, inc), (0, i, 0), parent=midCtrl.getName()) midJnt.create() self.ribbonJnts.append(midJnt.getName()) #midJnt.setPosition([0,i,0]) #upv creation upvCtrl = control.Control("{0}_{1}{2}".format( self.nameSpace, nameSpace.UPV, inc), (0, i, 0), shape="cross") upvCtrl.create() self.ribbonUpvs.append(upvCtrl.getName()) cmds.select(upvCtrl.getZeroGroup1()) cmds.move(x, y, z, r=True) cmds.parent(upvCtrl.getZeroGroup1(), self.masterGrp) #hide upvector. Animators don't need to see it! cmds.setAttr("{0}.visibility".format(upvCtrl.getName()), 0) self.ribbonZeros.append(midCtrl.getZeroGroup1()) self.getMidCtrl = midCtrl.getName() self.getMidZeroGroup = midCtrl.getZeroGroup1() cmds.parent(midCtrl.getZeroGroup1(), self.ctrlGrp) #midLocator self.midLoc = control.Control("{0}_midpoint".format( self.nameSpace), (0, i, 0), shape="cross") self.midLoc.create() #hide it cmds.setAttr("{0}.visibility".format(self.midLoc.getName()), 0) else: #ctrl creation ribbonCtrl = control.Control("{0}_ctrl{1}".format( self.nameSpace, inc), (0, i, 0), shape="square") ribbonCtrl.create() self.ribbonCtrls.append(ribbonCtrl.getName()) #loc creation ribbonLoc = cmds.spaceLocator( n="{0}_loc{1}".format(self.nameSpace, inc)) cmds.parent(ribbonLoc[0], ribbonCtrl.getName()) self.ribbonLocs.append(ribbonLoc[0]) cmds.setAttr("{0}.ty".format(ribbonLoc[0]), 0) #hide it cmds.setAttr("{0}.visibility".format(ribbonLoc[0]), 0) #joint creation ribbonJnt = joint.Joint("{0}_{1}{2}".format( self.nameSpace, nameSpace.JOINT, inc), (0, i, 0), parent=ribbonCtrl.getName()) ribbonJnt.create() self.ribbonJnts.append(ribbonJnt.getName()) #upv creation upvCtrl = control.Control("{0}_{1}{2}".format( self.nameSpace, nameSpace.UPV, inc), (0, i, 0), shape="cross") upvCtrl.create() self.ribbonUpvs.append(upvCtrl.getName()) cmds.parent(upvCtrl.getZeroGroup1(), ribbonCtrl.getName()) cmds.select(upvCtrl.getZeroGroup1()) cmds.move(x, y, z, r=True) #hide upvector. Animators don't need to see it! cmds.setAttr("{0}.visibility".format(upvCtrl.getName()), 0) self.ribbonZeros.append(ribbonCtrl.getZeroGroup1()) cmds.parent(ribbonCtrl.getZeroGroup1(), self.ctrlGrp) #orientControls. ribbons are default set to z-downaxis ribbonCtrl.setOrientation('z') #make them a little smaller too cmds.select("{0}.cv[*]".format(ribbonCtrl.getName())) cmds.scale(0.6, 0.6, 0.6, r=True) #aim contraint startLoc to midCtrl cmds.aimConstraint(self.ribbonCtrls[1], self.ribbonLocs[0], mo=True, wut="object", wuo=self.ribbonUpvs[0]) #aim constraint endLoc to midCtrl cmds.aimConstraint(self.ribbonCtrls[1], self.ribbonLocs[-1], mo=True, wut="object", wuo=self.ribbonUpvs[-1]) #parentConstraint start and end ctrls to midloc cmds.parentConstraint(self.ribbonCtrls[0], self.ribbonCtrls[-1], self.midLoc.getName()) #pointConstraint midZeroGrp to midLoc cmds.pointConstraint(self.midLoc.getName(), self.ribbonZeros[1]) #aim midZero to startCtrl cmds.aimConstraint(self.ribbonCtrls[-1], self.ribbonZeros[1], wut="object", wuo=self.ribbonUpvs[1], mo=True) #parentConstraint startUpv and endUpv to midUpv cmds.parentConstraint(self.ribbonUpvs[-1], self.ribbonUpvs[0], self.ribbonUpvs[1])