def bulge_button( self, *args ): if( cmds.objExists( "ZBend" ) ): cmds.confirmDialog( title="Error", message="First delete the bulge history on the previously\ndeformed object before bulging another.", button="Okie Dokie" ) return 0 latestSelection = cmds.ls( selection=True ) if( len( latestSelection ) == 0 ): return 0 if( len( latestSelection ) == 1 ): self.relatives = cmds.listRelatives( children=True ) if( len(self.relatives) == 1 ): self.bbox = cmds.exactWorldBoundingBox( latestSelection ) cmds.nonLinear( type='bend', curvature=cmds.intSliderGrp( "x_bulge_slider", value=True, query=True ) ) cmds.rename( "XBend" ) cmds.move((self.bbox[0] + self.bbox[3])/2, self.bbox[1], (self.bbox[2] + self.bbox[5])/2, "XBend", rpr=True ) cmds.setAttr( "XBend.rotateZ", -90 ) cmds.select( latestSelection ) cmds.nonLinear( type='bend', curvature=cmds.intSliderGrp( "z_bulge_slider", value=True, query=True ) ) cmds.rename( "ZBend" ) cmds.move((self.bbox[0] + self.bbox[3])/2, self.bbox[1], (self.bbox[2] + self.bbox[5])/2, "ZBend", rpr=True ) cmds.setAttr( "ZBend.rotateZ", -90 ) cmds.setAttr( "ZBend.rotateX", 90 ) cmds.connectControl( "x_bulge_slider", "bend1.curvature" ) cmds.connectControl( "z_bulge_slider", "bend2.curvature" ) cmds.select( latestSelection )
def create_deform(deform_type, axis, node): """that function creates a nonLinear deformer of the specified type and rename it and its Handle according to the specified type and axis :param deform_type: type of the deformer to create :type deform_type: string :param axis: axis of influence of the deformer :type axis: string :param node: node to deform :type node: string :return: name of the new deformer and name of its handle :rtype: list""" # counts the nonLinear of the specified type and defines the name of the new node to create count = count_non_linear(deform_type) + 1 deform = deform_type + str(count) # select the geometry to deform and create the deformer mc.select(node) mc.nonLinear(typ=deform_type) # rename the deformer deform_name = mc.rename(deform, node + '_' + deform_type + '_' + axis) deform_handle = mc.rename(deform + 'Handle', node + '_' + deform_type + 'Handle_' + axis) # return both the name of the newly created nonLinear and his handle return [deform_name, deform_handle]
def addDeformer(self): ''' Adds one or two deformers to a house. self : Object of the class House. On exit : A flare deformer has been added to the object house.name. A twist deformer is occasionally added on top of that. Some of the deformers' attributes have been randomly set. ''' cmds.select(self.name) self.flare = cmds.nonLinear(type = "flare") moveFlare = random.choice(["Yes", "No"]) if (moveFlare == "Yes"): cmds.xform(self.flare, translation = (0, random.uniform(self.height / 2.0, self.height + self.height / 4.0), 0)) endFlare = random.uniform(0.3, 1.5) cmds.setAttr(self.flare[0] + ".endFlareX", endFlare) cmds.setAttr(self.flare[0] + ".endFlareZ", endFlare) cmds.setAttr(self.flare[0] + ".curve", random.uniform(-0.4, min((self.height/min(self.width, self.depth)) * 0.3, 0.9))) cmds.xform(self.flare, scale = (0,self.height / 2, 0)) twist = random.randint(0, 6) if (twist == 0): if not(self.type == "box" and (self.width/self.depth > 1.5 or self.depth/self.width > 1.5)): cmds.select(self.name) self.twist = cmds.nonLinear(type = "twist") cmds.setAttr(self.twist[0] + ".endAngle", random.randint(-90, 90)) cmds.xform(self.twist, scale = (0,self.height / 2, 0))
def makeBalloon(): bubble = cmds.polySphere(r=BALLOON_RADIUS) cmds.nonLinear(bubble, typ='flare', endFlareX=1.25, endFlareZ=1.25) tie = cmds.polyCone(radius=.1, height=.1) cmds.move(0, -BALLOON_RADIUS, ) balloon = cmds.polyUnite(bubble, tie) cmds.move(BALLOON_DISTANCE, BALLOON_DISTANCE, 0)
def createHoneySphere(i): pn = 'plane'+str(i) #bend1 cmds.select(pn); cmds.nonLinear(type='bend', lowBound=-1, highBound=1, curvature = PI) cmds.setAttr("bend"+str(i*2+1)+"Handle.rotateX", 90); cmds.setAttr("bend"+str(i*2+1)+"Handle.rotateZ", 90); #bend2 cmds.select(pn); cmds.nonLinear(type='bend', lowBound=-1, highBound=1, curvature = PI) cmds.setAttr("bend"+str(i*2+2)+"Handle.rotateZ", 90);
def create_deform(deform_type, axis, current_node): if deform_type == 'bend': deform = deform_type + str(datas['count_b']) if deform_type == 'squash': deform = deform_type + str(datas['count_s']) if deform_type == 'wave': deform = deform_type + str(datas['count_w']) mc.select(current_node) mc.nonLinear(typ=deform_type) deform_name = mc.rename(deform, current_node+ '_'+deform_type+'_'+axis) deform_handle = mc.rename(deform+'Handle', current_node+'_'+deform_type+'Handle'+axis) return [deform_name, deform_handle]
def nonlinearDeformer(objects=[], defType=None, lowBound=-1, highBound=1, translate=None, rotate=None, name='nonLinear'): #If something went wrong or the type is not valid, raise exception if not objects or defType not in [ 'bend', 'flare', 'sine', 'squash', 'twist', 'wave' ]: raise Exception, "function: 'nonlinearDeformer' - Make sure you specified a mesh and a valid deformer" #Create and rename the deformer nonLinDef = cmds.nonLinear(objects[0], type=defType, lowBound=lowBound, highBound=highBound) nonLinDef[0] = cmds.rename(nonLinDef[0], (name + '_' + defType + '_def')) nonLinDef[1] = cmds.rename(nonLinDef[1], (name + '_' + defType + 'Handle')) #If translate was specified, set the translate if translate: cmds.setAttr((nonLinDef[1] + '.translate'), translate[0], translate[1], translate[2]) #If rotate was specified, set the rotate if rotate: cmds.setAttr((nonLinDef[1] + '.rotate'), rotate[0], rotate[1], rotate[2]) #Return the deformer return nonLinDef
def random_flare(curve_range=(-0.5, 0)): curve_value = random.uniform(*curve_range) f_v = [random.uniform(0.6, 1.6) for i in range(2)] return cmds.nonLinear(type="flare", curve=curve_value, startFlareX=f_v[0], endFlareX=f_v[1])
def bookShape( curv1=90, lowB1=0.5, highB1=0.5, ro1=(90, 180, 90), curv2=90, lowB2=0.5, highB2=0.5, ro2=(-90, 180, 90), lightPos=(1, 10, -1), fileName='D:/OneDrive - HKUST Connect/20Spring_UROP/3D-Modeling/Texture/bookShaped.obj' ): deleteAll() myPlane1 = mc.polyPlane(sx=20, sy=15, w=30, h=20, name='myPlane1') bend1 = mc.nonLinear(myPlane1, type='bend', curvature=curv1, lowBound=-lowB1, highBound=highB1) mc.rotate(ro1[0], ro1[1], ro1[2], bend1, a=True, ws=True, fo=True) piv1 = mc.pointPosition('myPlane1.vtx[325]') mc.select(bend1, myPlane1) mc.move(0, 0, -piv1[2], r=True) myPlane2 = mc.polyPlane(sx=20, sy=15, w=30, h=20, name='myPlane2') bend2 = mc.nonLinear(myPlane2, type='bend', curvature=curv2, lowBound=-lowB2, highBound=highB2) mc.rotate(ro2[0], ro2[1], ro2[2], bend2, a=True, ws=True, fo=True) piv2 = mc.pointPosition('myPlane2.vtx[10]') mc.select(bend2, myPlane2) mc.move(0, 0, -piv2[2], r=True) mc.polyUnite(myPlane1, myPlane2, ch=1, mergeUVSets=1, centerPivot=True, n='myPlane') addPointLight(lightPos) exportObj(fileName)
def random_bend(thresh=20): curvature, rotation = random.uniform(-thresh, thresh), random.uniform(0, 360) bend, bend_handle = cmds.nonLinear(type="bend", curvature=curvature, highBound=5) cmds.rotate(0, rotation, 0, bend_handle, fo=True, os=True, r=True) return bend, bend_handle
def GenTentacles (n): for i in range(0, n): # create a new cone cmds.select(baseTentacle) newTentacle = cmds.duplicate()[0] cmds.move(0, 0, 0) # vary tentacle size sx = random.uniform(0.1, 0.3) sy = random.uniform(0.5, 1.3) cmds.scale(sx, sy, sx) # create twist deformer twist = cmds.nonLinear(type="twist", lowBound=-1, highBound=1)[0] cmds.move(-11.25, 44, 0) # hide the deformer mel.eval("editDisplayLayerMembers -noRecurse hidden `ls -selection`;") # combine twist and model, rotate it rx = random.uniform(-360, 360) ry = random.uniform(-360, 360) rz = random.uniform(-360, 360) cmds.select(newTentacle, add=True) mel.eval("doGroup 0 1 1") cmds.rotate(rx, ry, rz); tentacleGroup = cmds.ls(selection=True) # move to frame 0 cmds.currentTime(0) for j in range(0, 40): #TODO this is frames # do the twist cmds.select(twist) twistAmount = RandTwist() cmds.setAttr(twist + ".endAngle", twistAmount); cmds.setKeyframe(twist + ".ea") # rotate a bit cmds.select(tentacleGroup) rx = random.uniform(-36, 36) ry = random.uniform(-36, 36) rz = random.uniform(-36, 36) cmds.rotate(rx, ry, rz, relative=True) cmds.setKeyframe(tentacleGroup) # move to next key frame cmds.currentTime(30 * j + random.uniform(-10, 10)) allTentacles.append(tentacleGroup)
def createNails(self): x = -10 z = -10 for i in range(441): height = 2 cmds.polyCylinder(n='nailt' + str(i), h=height, r=0.1, sz=1, sy=10) cmds.move(0, 1, 0) cmds.polyCylinder(n='nailb' + str(i), h=0.02, r=0.2) cmds.polyCone(n='nailp' + str(i), h=0.5, r=0.1, sy=5) cmds.move(0, 2.25, 0) nail = 'nail' + str(i) cmds.polyUnite('nailt' + str(i), 'nailb' + str(i), 'nailp' + str(i), n=nail) cmds.move(x, 0, z) cmds.nonLinear(type='bend', curvature=0.0, lowBound=0, highBound=2) cmds.move(x, 0, z) x += 1 if x == 11: x = -10 z += 1
def staggerTime(): ''' Animate a serie of planes and animed them 1. create file: force a new file on default location 2. set perspective view 3. create object 4. create Mash network: fills inside with instances 5. animation offset components ''' # 1. new file cmds.file(force=True, new=True) # 2. move the camera cmds.setAttr('persp.translateX', 25) cmds.setAttr('persp.translateY', 20) cmds.setAttr('persp.translateZ', 20) # 3. create a poly cube pcube = cmds.polyPlane(sx=1, sy=1) cmds.setKeyframe(pcube[0], attribute='rotateX', t=['0sec'], v=-180.0) cmds.setKeyframe(pcube[0], attribute='rotateX', t=['0.5sec'], v=0.0) # 4. create a new MASH network mashNetwork = mapi.Network() mashNetwork.createNetwork(name="TimeNetwork", geometry="Repro") cmds.setAttr(mashNetwork.distribute + '.arrangement', 6) # 6=Grid cmds.setAttr(mashNetwork.distribute + '.gridAmplitudeX', 30) cmds.setAttr(mashNetwork.distribute + '.gridx', 30) cmds.setAttr(mashNetwork.distribute + '.gridz', 6) # 5. create node: timeNode timeNode = mashNetwork.addNode("MASH_Time") cmds.setAttr(timeNode.name + '.animationEnd', 1000) #one attribute way to turn off looping cmds.setAttr(timeNode.name + '.staggerFrames', 120) cmds.setAttr(timeNode.name + '.timeOffset', -120) reproMesh = cmds.listConnections(mashNetwork.instancer + '.outMesh', d=True, s=False)[0] cmds.flushIdleQueue() cmds.select(clear=True) cmds.select(reproMesh) bendDeformer = cmds.nonLinear(type='bend', curvature=179.5)[1] #handle cmds.setAttr(bendDeformer + '.rotateX', 90) cmds.setAttr(bendDeformer + '.rotateY', 90) cmds.playbackOptions(animationEndTime='6sec') cmds.playblast(format="qt", viewer=True, p=100)
def addBlend(): cards = cmds.ls('card*', transforms=True) for card in cards: bend = cmds.nonLinear(card, type='bend')[1] if not cmds.ls('bendHandleLayer'): cmds.createDisplayLayer(nr=True, name='bendHandleLayer') else: cmds.editDisplayLayerMembers('bendHandleLayer', bend) cmds.parent(bend, card) cmds.setAttr(bend + '.rx', 90) cmds.setAttr(bend + '.ry', 0) cmds.setAttr(bend + '.rz', 90)
def makeBilly(): #torso torso = cmds.polySphere(radius=BILLY_TORSO_RADIUS) cmds.nonLinear(torso, type='flare', endFlareX=.5, endFlareZ=.5) #head and eyes head = cmds.polySphere(radius=BILLY_HEAD_RADIUS) #move the head to the top cmds.move(0, (BILLY_TORSO_RADIUS + BILLY_HEAD_RADIUS), 0) core = cmds.polyUnite(head, torso) leftEye = cmds.polySphere(radius=BILLY_EYE_RADIUS) cmds.move((-(BILLY_HEAD_RADIUS/2)), (BILLY_TORSO_RADIUS + BILLY_HEAD_RADIUS), BILLY_EYE_BULGE) rightEye = cmds.polySphere(radius=BILLY_EYE_RADIUS) cmds.move(((BILLY_HEAD_RADIUS/2)), (BILLY_TORSO_RADIUS + BILLY_HEAD_RADIUS), BILLY_EYE_BULGE) print core, leftEye, rightEye core2 = cmds.polyUnite(core, leftEye, rightEye) #arms leftArm = cmds.polyCube(h=BILLY_ARM_WIDTH, w=BILLY_ARM_LENGTH, d=BILLY_ARM_WIDTH) cmds.move(-BILLY_TORSO_RADIUS, (BILLY_TORSO_RADIUS / 2), 0) rightArm = cmds.polyCube(h=BILLY_ARM_WIDTH, d=BILLY_ARM_WIDTH, w=BILLY_ARM_LENGTH) cmds.move(BILLY_TORSO_RADIUS, (BILLY_TORSO_RADIUS / 2), 0) coreArms = cmds.polyUnite(core2, leftArm, rightArm) #legs leftLeg = cmds.polyCube(h=BILLY_ARM_LENGTH, d=BILLY_ARM_WIDTH, w=BILLY_ARM_WIDTH) cmds.move(-(BILLY_TORSO_RADIUS / 2), -(BILLY_TORSO_RADIUS), 0) rightLeg = cmds.polyCube(h=BILLY_ARM_LENGTH, d=BILLY_ARM_WIDTH, w=BILLY_ARM_WIDTH) cmds.move((BILLY_TORSO_RADIUS / 2), -(BILLY_TORSO_RADIUS), 0) billy = cmds.polyUnite(coreArms, leftLeg, rightLeg)
def createTwistDeformer(self): twistDeformer = cmds.nonLinear(self.planeBlend, type="twist", name="%s_TWIST_DFM" % self.name) cmds.rotate(0, -90, 180, twistDeformer) cmds.connectAttr("%s.rotateY" % str(self.controlCurves[0]), "%s.startAngle" % str(twistDeformer[0])) cmds.connectAttr("%s.rotateY" % str(self.controlCurves[2]), "%s.endAngle" % str(twistDeformer[0])) cmds.setAttr("%s.rotateOrder" % str(self.controlCurves[2]), 3) cmds.setAttr("%s.rotateOrder" % str(self.controlCurves[0]), 3) self.parentObject(twistDeformer[1], self.noMoveGroup) self.hideObject(twistDeformer[1]) return twistDeformer
def wiggle(self, TypeFish, x): x = x + 1 if (TypeFish == 1): cmds.select("PoissonFleche" + str(x), r=True) nom = "PoissonFleche" else: cmds.select("PoissonLong" + str(x), r=True) nom = "PoissonLong" cmds.nonLinear(type="sine", n="houla_" + nom + str(x), amplitude=0.05) cmds.setAttr("houla_" + nom + str(x) + ".wavelength", 1.5) cmds.rotate(90, 0, 0) cmds.expression(o="houla_" + nom + str(x), ae=True, uc=all, s="houla_" + nom + str(x) + ".off=time*4") cmds.parent("houla_" + nom + str(x) + "Handle", nom + str(x))
def fountainTop(fountain): ''' Creates a top decoration for a fountain. fountain: A object the top decoration will be placed on. On exit: A top decoration has been created by adding a deformer to a basic polygonal object. The top is returned as a tuple with the object name and node name. ''' height = random.uniform(0.1,0.6) # Decide which type of object will form the top. type = random.choice(["cube", "cylinder", "prism", "cone", "sphere"]) if type == "cube": top = cmds.polyCube(name = "top", h = height, w = 0.2, d = 0.2, sy = 10) if type == "cylinder": top = cmds.polyCylinder(name = "top",h = height, r = 0.1, sy = 10) if type == "prism": top = cmds.polyPrism(name = "top", l = height, w = 0.1, sh = 10) if type == "cone": top = cmds.polyCone(name = "top", h = height, r = 0.1, sy = 10) if type == "sphere": top = cmds.polySphere(name = "top",r = height/2.0) bbox = cmds.exactWorldBoundingBox(fountain) cmds.xform(top, translation = (0,bbox[4]+ height/2.0,0)) flare = random.choice([0,1]) if flare == 1: cmds.select(top[0]) flare = cmds.nonLinear(type = "flare") cmds.setAttr(flare[0] + ".curve", random.uniform(-3,3)) twist = random.choice([0,1]) if type == "cube" or type == "prism": if twist == 1: cmds.select(top[0]) twist = cmds.nonLinear(type = "twist") cmds.setAttr(twist[0] + ".endAngle", random.randint(-500, 500)) return top
def nonlinearDeformer(objects=[], defType=None, lowBound=-1, highBound=1, translate=None, rotate=None, name='nonLinear'): #If something went wrong or the type is not valid, raise exception if not objects or defType not in ['bend','flare','sine','squash','twist','wave']: raise Exception, "function: 'nonlinearDeformer' - Make sure you specified a mesh and a valid deformer" #Create and rename the deformer nonLinDef = cmds.nonLinear(objects[0], type=defType, lowBound=lowBound, highBound=highBound) nonLinDef[0] = cmds.rename(nonLinDef[0], (name + '_' + defType + '_def')) nonLinDef[1] = cmds.rename(nonLinDef[1], (name + '_' + defType + 'Handle')) #If translate was specified, set the translate if translate: cmds.setAttr((nonLinDef[1] + '.translate'), translate[0], translate[1], translate[2]) #If rotate was specified, set the rotate if rotate: cmds.setAttr((nonLinDef[1] + '.rotate'), rotate[0], rotate[1], rotate[2]) #Return the deformer return nonLinDef
def create_twist_deformer(sfc, prefix=''): """ create a single follicle at given u&v on a surface and make necessary attribute connections @param sfc: str, name of the surface we want apply bend deformer to @param prefix: str, name of body part for which the ribbon is being constructed @return: list(str), list of length 2 with names of deformer twist obj and twist-handle obj """ twist_handle = cmds.nonLinear(sfc, type='twist') cmds.rename(twist_handle[0], prefix + '_twist') cmds.rename(twist_handle[1], prefix + '_twist_handle') twist_handle[0] = prefix + '_twist' twist_handle[1] = prefix + '_twist_handle' return twist_handle
def eelFinSwimmer (controlSurface,waveControlObject): #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>auto swim stuff """ Creating our deformation surface """ deformMeshBuffer = mc.duplicate (controlSurface) deformMesh = mc.rename (deformMeshBuffer[0],(controlSurface+'_defmesh')) """ Creates our wave deformer """ deformerBuffer = mc.nonLinear (deformMesh, type = 'wave', name = 'swimWave') waveDeformer = mc.rename (deformerBuffer[0], 'waveDeformer') waveDeformerHandle = mc.rename (deformerBuffer[1], 'waveDeformerHandle') """ move the handle """ mc.setAttr ((waveDeformerHandle+'.rx'),90) mc.setAttr ((waveDeformerHandle+'.ry'),90) """ set some variables """ mc.setAttr ((waveDeformer+'.dropoff'),1) mc.setAttr ((waveDeformer+'.dropoffPosition'),1) mc.setAttr ((waveDeformer+'.maxRadius'),2) """ make our blendshape node and reorder things""" blendshapeNode = mc.blendShape (deformMesh, controlSurface, name = 'swim_bsNode' ) mc.reorderDeformers ("tweak5", blendshapeNode[0],controlSurface) """ add some attrs to our wave control object """ attributes.addSectionBreakAttrToObj (waveControlObject, 'swim') attributes.addFloatAttributeToObject (waveControlObject, 'auto', 0, 1, 0) attributes.addFloatAttributeToObject (waveControlObject, 'speed', -100, 100, 0) attributes.addFloatAttributeToObject (waveControlObject, 'wavelength', 0, 10, 5) attributes.addFloatAttributeToObject (waveControlObject, 'amplitude', 0, 10, 0) attributes.addFloatAttributeToObject (waveControlObject, 'dropoff', 0, 1, 1) attributes.addFloatAttributeToObject (waveControlObject, 'dropoffPosition', 0, 1, 0) attributes.addFloatAttributeToObject (waveControlObject, 'minRadius', 0, 10, 0) attributes.addFloatAttributeToObject (waveControlObject, 'maxRadius', 0, 10, 10) """ connect a few attrs """ mc.connectAttr ((waveControlObject+'.auto'),(blendshapeNode[0]+'.'+deformMesh)) mc.connectAttr ((waveControlObject+'.wavelength'),(waveDeformer+'.wavelength')) mc.connectAttr ((waveControlObject+'.amplitude'),(waveDeformer+'.amplitude')) mc.connectAttr ((waveControlObject+'.dropoff'),(waveDeformer+'.dropoff')) mc.connectAttr ((waveControlObject+'.dropoffPosition'),(waveDeformer+'.dropoffPosition')) mc.connectAttr ((waveControlObject+'.minRadius'),(waveDeformer+'.minRadius')) mc.connectAttr ((waveControlObject+'.maxRadius'),(waveDeformer+'.maxRadius')) """ set some good base values """ mc.setAttr ((waveControlObject+'.speed'),1) mc.setAttr ((waveControlObject+'.wavelength'),4) mc.setAttr ((waveControlObject+'.amplitude'),.3) mc.setAttr ((waveControlObject+'.dropoff'),1) mc.setAttr ((waveControlObject+'.dropoffPosition'),1) mc.setAttr ((waveControlObject+'.maxRadius'),2) """ sets up swim speed """ nodes.offsetCycleSpeedControlNodeSetup (waveDeformer,(waveControlObject+'.speed'),90,-10)
def createParticleSystem_goal(): # Create a constant sized particle object following a deformed torus shape (using goal) cmds.file(new=True, force=True) # Create a torus, we will use it as goal xrez = 14 yrez = 8 goalTorus = cmds.polyTorus( r=1, sr=0.5, tw=0, sx=xrez, sy=yrez, ax=(0, 1, 0), cuv=1, ch=0)[0] # nParticle creation depends on an optoinVar value, make sure we use the default one cmds.optionVar( sv=("NParticleStyle","Points") ) # Emit a lot of particle, the actual number will be limited to the max particle attribute in the particleShape emitter = cmds.emitter(dx=1, dy=0, dz=0, sp=0.1, pos=(0, 5, 0),rate=2500)[0] particleSystem, particleSystemShape = cmds.nParticle(n="nParticle_test_goal") cmds.setAttr('%s.lfm' % particleSystemShape, 0) # live forever cmds.setAttr('%s.particleRenderType' % particleSystemShape, 7) # Blobby, to see radius cmds.setAttr('%s.maxCount' % particleSystemShape, xrez*yrez) # max count is the number of vertices on the torus cmds.connectDynamic( particleSystemShape, em=emitter) # Create Goal cmds.goal(particleSystem, w=1, utr=0, g=goalTorus); # Create Initial state to we start with the correct amount of particle # NOTE: When using this script in command line, the first frame is not correctly evaluated and the particleShape is empty # This doesn't happens in interactive maya for i in range(1, 10): cmds.currentTime(i) cmds.saveInitialState(particleSystemShape) cmds.currentTime(1) bend, bendHandle = cmds.nonLinear( goalTorus, type="bend", lowBound=-1, highBound=1, curvature=0) cmds.setAttr( "%s.rotateZ" % bendHandle, 90) cmds.setKeyframe( "%s.curvature" % bend, v=0, t=1, inTangentType="flat", outTangentType="flat") cmds.setKeyframe( "%s.curvature" % bend, v=-130, t=12, inTangentType="flat", outTangentType="flat") cmds.setKeyframe( "%s.curvature" % bend, v=130, t=24, inTangentType="flat", outTangentType="flat") # Make the bend animation loop cmds.setInfinity( bend, poi="oscillate", attribute="curvature") return particleSystem, particleSystemShape
def createParticleSystem_goal(): # Create a constant sized particle object following a deformed torus shape (using goal) cmds.file(new=True, force=True) # Create a torus, we will use it as goal xrez = 14 yrez = 8 goalTorus = cmds.polyTorus(r=1, sr=0.5, tw=0, sx=xrez, sy=yrez, ax=(0, 1, 0), cuv=1, ch=0)[0] # nParticle creation depends on an optoinVar value, make sure we use the default one cmds.optionVar(sv=("NParticleStyle", "Points")) # Emit a lot of particle, the actual number will be limited to the max particle attribute in the particleShape emitter = cmds.emitter(dx=1, dy=0, dz=0, sp=0.1, pos=(0, 5, 0), rate=2500)[0] particleSystem, particleSystemShape = cmds.nParticle(n="nParticle_test_goal") cmds.setAttr('%s.lfm' % particleSystemShape, 0) # live forever cmds.setAttr('%s.particleRenderType' % particleSystemShape, 7) # Blobby, to see radius cmds.setAttr('%s.maxCount' % particleSystemShape, xrez * yrez) # max count is the number of vertices on the torus cmds.connectDynamic(particleSystemShape, em=emitter) # Create Goal cmds.goal(particleSystem, w=1, utr=0, g=goalTorus); # Create Initial state to we start with the correct amount of particle # NOTE: When using this script in command line, the first frame is not correctly evaluated and the particleShape is empty # This doesn't happens in interactive maya for i in range(1, 10): cmds.currentTime(i) cmds.saveInitialState(particleSystemShape) cmds.currentTime(1) bend, bendHandle = cmds.nonLinear(goalTorus, type="bend", lowBound=-1, highBound=1, curvature=0) cmds.setAttr("%s.rotateZ" % bendHandle, 90) cmds.setKeyframe("%s.curvature" % bend, v=0, t=1, inTangentType="flat", outTangentType="flat") cmds.setKeyframe("%s.curvature" % bend, v=-130, t=12, inTangentType="flat", outTangentType="flat") cmds.setKeyframe("%s.curvature" % bend, v=130, t=24, inTangentType="flat", outTangentType="flat") # Make the bend animation loop cmds.setInfinity(bend, poi="oscillate", attribute="curvature") return particleSystem, particleSystemShape
def mk_deformer(self, ribbon, defType): """ Applies a deformer to your ribbon """ mc.select(ribbon, r=True) bs = "{}_bs".format(ribbon) # Create duplicate ribbon and apply a twist deformer deformer = "{}_{}".format(ribbon, defType) if mc.objExists(deformer): # Make sure deformer doesn't already exist return deformer # Create a duplicate of your ribbon to apply deformer to mc.duplicate(ribbon, name="{}_{}".format(ribbon, defType)) deform = mc.nonLinear(deformer, type=defType) mc.rename(deform[0], "{}Def".format(deformer)) hndl = mc.rename(deform[1], "{}Hndl".format(deformer)) mc.setAttr(hndl + ".rotateZ", -90) # Connect duplicate to primary ribbon via a blend shape if not mc.objExists(bs): mc.blendShape(deformer, ribbon, n=bs, foc=True, w=(0, 1)) else: bs_targets = mc.blendShape(bs, q=True, target=True) mc.blendShape(bs, edit=True, t=(ribbon, len( bs_targets), deformer, 1.0), w=[len(bs_targets), 1.0]) # Group everything together defGrp = "{}_deformers{}".format(ribbon, GRP) if not mc.objExists(defGrp): mc.createNode("transform", n=defGrp) mc.parent(defGrp, "{}{}".format(self.name, RIG)) grp = mc.group(deformer, hndl, n="{}{}".format(deformer, GRP)) mc.select(ribbon, r=True) mc.parent(grp, defGrp) mc.setAttr("{}.visibility".format(grp), 0) return deformer
def setup_blendshape_deformer(control=None, side=None, blendShapeNode=None, blendShape=None, deformerType=None, connectAttr=[None, None], translation=[0, 0, 0], rotation=[0, 0, 0], scale=[1, 1, 1]): #--- this method setups the blendshape deformer if not control: raise Exception('No control specified!') if not side: raise Exception('No side specified!') if not blendShapeNode: raise Exception('No blendShapeNode specified!') if not blendShape: raise Exception('No blendShape specified!') if not deformerType: raise Exception('No deformerType specified!') if not connectAttr: raise Exception('No connectAttr specified!') cmds.setAttr(blendShapeNode + '.' + blendShape, 1) deformer = cmds.nonLinear(blendShape, type=deformerType, name=side + '_' + deformerType + '_DEF') cmds.xform(deformer[1], translation=translation, worldSpace=True) cmds.xform(deformer[1], rotation=rotation, worldSpace=True) cmds.xform(deformer[1], scale=scale, worldSpace=True) if isinstance(connectAttr, list): if isinstance(connectAttr[0], list): for cnt in connectAttr: cmds.connectAttr(control + '.' + cnt[0], deformer[0] + '.' + cnt[1]) cmds.parent(deformer[1], 'Shapes') cmds.setAttr(deformer[1] + '.v', 0)
def bendHandle( curv=90, lowB=0, highB=0.5, ro=(60, 0, 90), pos=(-5, 0, 6), lightPos=(1, 10, -1), fileName='D:/OneDrive - HKUST Connect/20Spring_UROP/3D-Modeling/Texture/bendHandle.obj' ): deleteAll() # create plane with 10 x divisions, 15 y divisions myPlane = mc.polyPlane(sx=10, sy=15, w=15, h=20, name='myPlane') bend = mc.nonLinear(myPlane, type='bend', curvature=curv, lowBound=-lowB, highBound=highB) mc.rotate(ro[0], ro[1], ro[2], bend, a=True, ws=True, fo=True) mc.move(pos[0], pos[1], pos[2], bend) addPointLight(lightPos) exportObj(fileName)
def setup_blendshape_deformer(control = None, side = None, blendShapeNode = None, blendShape = None, deformerType = None, connectAttr = [None, None], translation = [0,0,0], rotation = [0,0,0], scale = [1,1,1]): #--- this method setups the blendshape deformer if not control: raise Exception('No control specified!') if not side: raise Exception('No side specified!') if not blendShapeNode: raise Exception('No blendShapeNode specified!') if not blendShape: raise Exception('No blendShape specified!') if not deformerType: raise Exception('No deformerType specified!') if not connectAttr: raise Exception('No connectAttr specified!') cmds.setAttr(blendShapeNode + '.' + blendShape, 1) deformer = cmds.nonLinear(blendShape, type = deformerType, name = side + '_' + deformerType + '_DEF') cmds.xform(deformer[1], translation = translation, worldSpace = True) cmds.xform(deformer[1], rotation = rotation, worldSpace = True) cmds.xform(deformer[1], scale = scale, worldSpace = True) if isinstance(connectAttr, list): if isinstance(connectAttr[0], list): for cnt in connectAttr: cmds.connectAttr(control + '.' + cnt[0], deformer[0] + '.' + cnt[1]) cmds.parent(deformer[1], 'Shapes') cmds.setAttr(deformer[1] + '.v', 0)
def createBendToCurve(curve): import math curve = sgModelDag.getTransform(curve) cvs = cmds.ls(curve + '.cv[*]', fl=1) startPoint = cmds.xform(cvs[0], q=1, ws=1, t=1) endPoint = cmds.xform(cvs[-1], q=1, ws=1, t=1) bend, handle = cmds.nonLinear(curve, type='bend', lowBound=0, highBound=1, curvature=0) cmds.xform(handle, ws=1, t=startPoint) vStartPoint = sgModelConvert.convertMVectorFromPointList(startPoint) vEndPoint = sgModelConvert.convertMVectorFromPointList(endPoint) vAim = vEndPoint - vStartPoint yVector = om.MVector(*[0, 1, 0]) zVector = om.MVector(*[1, 0, 0]) dotY = math.fabs(vAim * yVector) dotZ = math.fabs(vAim * zVector) vUp = None if dotY > dotZ: vUp = zVector else: vUp = yVector vCross = vAim ^ vUp vUp = vCross ^ vAim lengthAim = vAim.length() vUp.normalize() vCross.normalize() vUp *= lengthAim vCross *= lengthAim mtx = [ vCross.x, vCross.y, vCross.z, 0, vAim.x, vAim.y, vAim.z, 0, vUp.x, vUp.y, vUp.z, 0, vStartPoint.x, vStartPoint.y, vStartPoint.z, 1 ] cmds.xform(handle, ws=1, matrix=mtx) handle, handleGrp = sgRigDag.addParent(handle) sgRigAttribute.addAttr(curve, ln='globalTwist', k=1) sgRigAttribute.addAttr(curve, ln='globalBend', k=1) sgRigAttribute.addAttr(curve, ln='twist', k=1, dv=0) sgRigAttribute.addAttr(curve, ln='bend', k=1, dv=1) addTwist = cmds.createNode('addDoubleLinear') multBend = cmds.createNode('multDoubleLinear') cmds.connectAttr(curve + '.globalTwist', addTwist + '.input1') cmds.connectAttr(curve + '.twist', addTwist + '.input2') cmds.connectAttr(curve + '.globalBend', multBend + '.input1') cmds.connectAttr(curve + '.bend', multBend + '.input2') cmds.connectAttr(multBend + '.output', bend + '.curvature') cmds.connectAttr(addTwist + '.output', handle + '.ry')
def dpHeadDeformer(self, *args): """ Create the arrow curve and deformers (squash and bends). """ # get a list of selected items selList = cmds.ls(selection=True) if selList: # twist deformer twistDefList = cmds.nonLinear(selList, name="TwistHead", type="twist") defSize = cmds.getAttr(twistDefList[0] + ".highBound") defScale = cmds.getAttr(twistDefList[1] + ".scaleY") defTy = -(defSize * defScale) defTy = ctrls.dpCheckLinearUnit(defTy) cmds.setAttr(twistDefList[0] + ".lowBound", 0) cmds.setAttr(twistDefList[0] + ".highBound", (defSize * 2)) cmds.setAttr(twistDefList[1] + ".ty", defTy) # squash deformer squashDefList = cmds.nonLinear(selList, name="SquashHead", type="squash") cmds.setAttr(squashDefList[0] + ".highBound", (defSize * 4)) cmds.setAttr(squashDefList[1] + ".ty", defTy) cmds.setAttr(squashDefList[0] + ".startSmoothness", 1) # side bend deformer sideBendDefList = cmds.nonLinear(selList, name="BendSideHead", type="bend") cmds.setAttr(sideBendDefList[0] + ".lowBound", 0) cmds.setAttr(sideBendDefList[0] + ".highBound", (defSize * 4)) cmds.setAttr(sideBendDefList[1] + ".ty", defTy) # front bend deformer frontBendDefList = cmds.nonLinear(selList, name="BendFrontHead", type="bend") cmds.setAttr(frontBendDefList[0] + ".lowBound", 0) cmds.setAttr(frontBendDefList[0] + ".highBound", (defSize * 4)) cmds.setAttr(frontBendDefList[1] + ".ry", -90) cmds.setAttr(frontBendDefList[1] + ".ty", defTy) # arrow control curve arrowCtrl = self.dpCvArrow("Deformer_Ctrl") # add control intensite attributes cmds.addAttr(arrowCtrl, longName="intensityX", attributeType='float', keyable=True) cmds.addAttr(arrowCtrl, longName="intensityY", attributeType='float', keyable=True) cmds.addAttr(arrowCtrl, longName="intensityZ", attributeType='float', keyable=True) cmds.setAttr(arrowCtrl + ".intensityX", 0.1) cmds.setAttr(arrowCtrl + ".intensityY", 0.1) cmds.setAttr(arrowCtrl + ".intensityZ", 0.1) # multiply divide in order to intensify influences mdNode = cmds.createNode("multiplyDivide", name="Deformer_MD") mdTwistNode = cmds.createNode("multiplyDivide", name="Deformer_Twist_MD") cmds.setAttr(mdTwistNode + ".input2Y", -1) # connections cmds.connectAttr(arrowCtrl + ".tx", mdNode + ".input1X", force=True) cmds.connectAttr(arrowCtrl + ".ty", mdNode + ".input1Y", force=True) cmds.connectAttr(arrowCtrl + ".tz", mdNode + ".input1Z", force=True) cmds.connectAttr(arrowCtrl + ".ry", mdTwistNode + ".input1Y", force=True) cmds.connectAttr(arrowCtrl + ".intensityX", mdNode + ".input2X", force=True) cmds.connectAttr(arrowCtrl + ".intensityY", mdNode + ".input2Y", force=True) cmds.connectAttr(arrowCtrl + ".intensityZ", mdNode + ".input2Z", force=True) cmds.connectAttr(mdNode + ".outputX", sideBendDefList[0] + ".curvature", force=True) cmds.connectAttr(mdNode + ".outputY", squashDefList[0] + ".factor", force=True) cmds.connectAttr(mdNode + ".outputZ", frontBendDefList[0] + ".curvature", force=True) cmds.connectAttr(mdTwistNode + ".outputY", twistDefList[0] + ".endAngle", force=True) # change squash to be more cartoon cmds.setDrivenKeyframe(squashDefList[0] + ".lowBound", currentDriver=mdNode + ".outputY", driverValue=-1, value=-4, inTangentType="auto", outTangentType="auto") cmds.setDrivenKeyframe(squashDefList[0] + ".lowBound", currentDriver=mdNode + ".outputY", driverValue=0, value=-2, inTangentType="auto", outTangentType="auto") cmds.setDrivenKeyframe(squashDefList[0] + ".lowBound", currentDriver=mdNode + ".outputY", driverValue=2, value=-1, inTangentType="auto", outTangentType="flat") # fix side values axisList = ["X", "Y", "Z"] for axis in axisList: unitConvNode = cmds.listConnections(mdNode + ".output" + axis, destination=True)[0] if unitConvNode: if cmds.objectType(unitConvNode) == "unitConversion": cmds.setAttr(unitConvNode + ".conversionFactor", 1) attrList = ['rx', 'rz', 'sx', 'sy', 'sz', 'v'] for attr in attrList: cmds.setAttr(arrowCtrl + "." + attr, lock=True, keyable=False) cmds.setAttr(arrowCtrl + ".intensityX", edit=True, keyable=False, channelBox=True) cmds.setAttr(arrowCtrl + ".intensityY", edit=True, keyable=False, channelBox=True) cmds.setAttr(arrowCtrl + ".intensityZ", edit=True, keyable=False, channelBox=True) # create groups arrowCtrlGrp = cmds.group(arrowCtrl, name="Deformer_Ctrl_Grp") cmds.setAttr(arrowCtrlGrp + ".ty", -1.75 * defTy) cmds.group((squashDefList[1], sideBendDefList[1], frontBendDefList[1], twistDefList[1]), name="Deformer_Data_Grp") # finish selection the arrow control cmds.select(arrowCtrl) else: mel.eval( "warning" + "\"" + "Select objects to create headDeformers, usually we create in the blendShape RECEPT target" + "\"" + ";")
def buildDeformers(self, ribbonPlane, controls=(), folGrp=()): # Create a target blendshape controlled by deformers flexiBlend = cmds.duplicate(ribbonPlane, n='flexiPlaneSetup_bShp_surface01') flexiBlendNode = cmds.blendShape(flexiBlend, ribbonPlane, n='%s_bShpNode_surface01' % self.name) # Turn blendshape on cmds.setAttr('%s.%s' % (flexiBlendNode[0], flexiBlend[0]), 1) # Create a wire deformer controled by ribbon controls wireCurve = cmds.curve( n='%s_wire_surface01' % self.name, d=2, p=[(-self.numJnts, 0, 0), (0, 0, 0), (self.numJnts, 0, 0)]) topClstr = cmds.cluster('%s.cv[0:1]' % wireCurve, rel=1, n='%s_cl_a01' % self.name) midClstr = cmds.cluster('%s.cv[1]' % wireCurve, rel=1, n='%s_cl_mid01' % self.name) botClstr = cmds.cluster('%s.cv[1:2]' % wireCurve, rel=1, n='%s_cl_b01' % self.name) clsGrp = cmds.group(topClstr, midClstr, botClstr, n='%s_cls01' % self.name) for attr in ['scalePivot', 'rotatePivot']: cmds.setAttr('%s.%s' % (topClstr[1], attr), -self.numJnts, 0, 0) for attr in ['scalePivot', 'rotatePivot']: cmds.setAttr('%s.%s' % (botClstr[1], attr), self.numJnts, 0, 0) cmds.setAttr('%sShape.originX' % topClstr[1], (-self.numJnts)) cmds.setAttr('%sShape.originX' % botClstr[1], (self.numJnts)) cmds.percent(topClstr[0], '%s.cv[1]' % wireCurve, v=0.5) cmds.percent(botClstr[0], '%s.cv[1]' % wireCurve, v=0.5) # Create twist and wire blend shape deformers twistNode = cmds.nonLinear(flexiBlend, type='twist') cmds.wire(flexiBlend, w=wireCurve, dds=[0, 20], foc=0, n='%s_wireAttrs_surface01' % self.name) cmds.xform(twistNode, ro=(0, 0, 90)) twistNode[0] = cmds.rename(twistNode[0], '%s_twistAttrs_surface01' % self.name) twistNode[1] = cmds.rename(twistNode[1], '%s_twist_surface01' % self.name) # Setup squash and stretch via utilitiy nodes arcLen = cmds.arclen(wireCurve, ch=1) arcLen = cmds.rename(arcLen, '%s_curveInfo01' % self.name) arcLenValue = cmds.getAttr('%s.arcLength' % arcLen) squashDivNode = cmds.createNode('multiplyDivide', n='%s_div_squashStretch_length01' % self.name) volDivNode = cmds.createNode('multiplyDivide', n='%s_div_volume01' % self.name) squashCondNode = cmds.createNode('condition', n='%s_cond_volume01' % self.name) cmds.setAttr('%s.operation' % squashDivNode, 2) cmds.setAttr('%s.input2X' % squashDivNode, arcLenValue) cmds.setAttr('%s.operation' % volDivNode, 2) cmds.setAttr('%s.input1X' % volDivNode, 1) cmds.setAttr('%s.secondTerm' % squashCondNode, 1) cmds.connectAttr('%s.arcLength' % arcLen, '%s.input1X' % squashDivNode) cmds.connectAttr('%s.outputX' % squashDivNode, '%s.input2X' % volDivNode) cmds.connectAttr('%s.outputX' % volDivNode, '%s.colorIfTrueR' % squashCondNode) # Set visibility options for obj in [flexiBlend[0], wireCurve, twistNode[1], clsGrp]: cmds.setAttr('%s.visibility' % obj, 0) # Connect controls to cluster deformers if they exist if len(controls) > 1: topCon = controls[0][0] botCon = controls[0][1] midCon = controls[0][2] for con, clstr in zip([topCon, botCon], [topClstr[1], botClstr[1]]): cmds.connectAttr('%s.translate' % con, '%s.translate' % clstr) cmds.connectAttr('%s.translate' % midCon, '%s.translate' % midClstr[1]) # Connect controls to twist deformer cmds.connectAttr('%s.rotateX' % topCon, '%s.endAngle' % twistNode[0]) cmds.connectAttr('%s.rotateX' % botCon, '%s.startAngle' % twistNode[0]) cmds.connectAttr('%s.volEnable' % controls[1], '%s.firstTerm' % squashCondNode) # Scale contraint each follicle to global move group for fol in cmds.listRelatives(folGrp, c=1): cmds.scaleConstraint(self.moveGrp, fol, mo=0) for shape in cmds.listRelatives(fol, s=1): cmds.setAttr('%s.visibility' % shape, 0) # Parent nodes cmds.parent(flexiBlend, wireCurve, clsGrp, twistNode[1], '%s_wire_surface01BaseWire' % self.name, self.extrasGrp)
def create_squash_rig(*args): """ creates a rig around the selected objects. Two squashes are created (upDown/lfRt) :param args: :return: """ sel = cmds.ls(sl=True, type="transform") if not sel: cmds.warning("You need to select some transforms!") return () mainCtrlRaw = rig.bounding_box_ctrl(sel, False) mainCtrl = cmds.rename(mainCtrlRaw, "{0}_CTRL".format(sel[0])) grp = rig.group_freeze(mainCtrl) rig.scaleNurbsCtrl(mainCtrl, 1.2, .2, 1.2) secCtrl = cmds.duplicate(mainCtrl, name="{0}2_CTRL".format(sel[0]))[0] rig.scaleNurbsCtrl(secCtrl, .9, .9, .9) thrdCtrl = cmds.duplicate(mainCtrl, name="{0}3_CTRL".format(sel[0]))[0] rig.scaleNurbsCtrl(thrdCtrl, .8, .8, .8) cmds.parent(thrdCtrl, secCtrl) cmds.parent(secCtrl, mainCtrl) cmds.parent(sel, thrdCtrl) try: rig.assign_color(mainCtrl, "red") except: pass try: rig.assign_color(secCtrl, "pink") except: pass try: rig.assign_color(thrdCtrl, "lightRed") except: pass cmds.addAttr(mainCtrl, ln="__xtraAttrs__", nn="__xtraAttrs__", at="enum", en="------", k=True) cmds.setAttr("{0}.__xtraAttrs__".format(mainCtrl), l=True) cmds.addAttr(mainCtrl, ln="secondaryCtrlVis", at="long", min=0, max=1, dv=0, k=True) secShp = cmds.listRelatives(secCtrl, s=True)[0] cmds.connectAttr("{0}.secondaryCtrlVis".format(mainCtrl), "{0}.visibility".format(secShp)) thrdShp = cmds.listRelatives(thrdCtrl, s=True)[0] cmds.connectAttr("{0}.secondaryCtrlVis".format(mainCtrl), "{0}.visibility".format(thrdShp)) # create squash cmds.select(sel, r=True) sq1Def, sq1Handle = cmds.nonLinear(type="squash", name="{0}_squash1".format(sel[0])) cmds.parent(sq1Handle, thrdCtrl) cmds.addAttr(mainCtrl, ln="squash1Factor", at="float", min=-5, max=5, dv=0, k=True) cmds.addAttr(mainCtrl, ln="squash1Vis", at="long", min=0, max=1, dv=0, k=True) cmds.connectAttr("{0}.squash1Factor".format(mainCtrl), "{0}.factor".format(sq1Def)) cmds.connectAttr("{0}.squash1Vis".format(mainCtrl), "{0}.v".format(sq1Handle)) cmds.select(sel, r=True) sq2Def, sq2Handle = cmds.nonLinear(type="squash", name="{0}_squash1".format(sel[0])) cmds.parent(sq2Handle, thrdCtrl) cmds.addAttr(mainCtrl, ln="squash2Factor", at="float", min=-5, max=5, dv=0, k=True) cmds.addAttr(mainCtrl, ln="squash2Vis", at="long", min=0, max=1, dv=0, k=True) cmds.setAttr("{0}.rz".format(sq2Handle), 90) cmds.connectAttr("{0}.squash2Factor".format(mainCtrl), "{0}.factor".format(sq2Def)) cmds.connectAttr("{0}.squash2Vis".format(mainCtrl), "{0}.v".format(sq2Handle)) cmds.setAttr("{0}.lowBound".format(sq1Def), -1.3) cmds.setAttr("{0}.lowBound".format(sq2Def), -1.3) cmds.setAttr("{0}.highBound".format(sq1Def), 1.3) cmds.setAttr("{0}.highBound".format(sq2Def), 1.3)
pmaNode = cmds.createNode('plusMinusAverage', n = selLs[i] + '_offset_pma') cmds.connectAttr(autoGrps[i-1] + '.rotateY', pmaNode + '.input1D[0]') cmds.connectAttr('flip_ctrl' + '.offset', pmaNode + '.input1D[2]') cmds.connectAttr(pmaNode + '.output1D', autoGrps[i] + '.rotateY') cmds.setAttr(pmaNode + '.operation', 2) geos = cmds.ls(sl = True) for geo in geos: bendGeo = cmds.duplicate(geo, n = geo + '_bend_geo')[0] cmds.parent(bendGeo, w = True) bsNode = cmds.blendShape(bendGeo, geo, frontOfChain = True)[0] cmds.setAttr(bsNode + '.' + bendGeo, 1) cmds.setAttr(bendGeo + '.visibility', False) bendHndl = cmds.nonLinear(bendGeo, type = 'bend', lowBound = 0, highBound = 1, curvature = 0)[1] baseName = geo.split('_bend_geo')[0] bendHndl = cmds.rename(bendHndl, baseName + '_bendHndl') bendNode = cmds.listConnections(bendHndl + '.worldMatrix[0]')[0] ctrlBaseName = bendHndl.split('_bendHndl')[0] cmds.connectAttr(ctrlBaseName + '_ctrl.bend', bendNode + '.curvature') cmds.connectAttr(ctrlBaseName + '_ctrl.twist', bendHndl + '.rotateX') cmds.setAttr(bendHndl + '.translateY', 2.6) cmds.setAttr(bendHndl + '.scaleX', 9.5) cmds.setAttr(bendHndl + '.scaleY', 9.5) cmds.setAttr(bendHndl + '.scaleZ', 9.5)
def wave(self, character = None, mod = None, side = None, name = None, suffix = None, geometry = None, position = [0,0,0], rotation = [0,0,0], envelope = 1, amplitude = 0, wavelength = 1, offset = 0, dropoff = 0, dropoffPosition = 0, minRadius = 0, maxRadius = 1, parent = None, show = True, lockAttr = None, ihi = True): #--- this method creates a wave deformer #--- select the specified geometry cmds.select(geometry) #--- create a wave deformer node = cmds.nonLinear(type = 'wave') #--- filter the individual name filter_name = (name + node[0].split('Handle')[0][0].upper() + node[0].split('Handle')[0][1:]) #--- rename the wave deformer node = self.__rename_node(mod = mod, side = side, name = filter_name, suffix = suffix, obj = node) #--- create a group on top and parent the deformer under the group node_grp = cmds.createNode('transform', parent = node[0]) cmds.parent(node_grp, world = True) cmds.parent(node[0], node_grp) #--- rename the node group node_grp = self.__rename_node(mod = mod, side = side, name = filter_name, suffix = 'GRP', obj = node_grp) #--- reposition the transform of the deformer locally cmds.xform(node[0], translation = position, worldSpace = False) cmds.xform(node[0], rotation = rotation, worldSpace = False) #--- take care of the node's settings #--- envelope cmds.setAttr(node[-1] + '.envelope', envelope) #--- amplitude cmds.setAttr(node[-1] + '.amplitude', amplitude) #--- wavelength cmds.setAttr(node[-1] + '.wavelength', wavelength) #--- offset cmds.setAttr(node[-1] + '.offset', offset) #--- dropoff cmds.setAttr(node[-1] + '.dropoff', dropoff) #--- dropoffPosition cmds.setAttr(node[-1] + '.dropoffPosition', dropoffPosition) #--- minRadius cmds.setAttr(node[-1] + '.minRadius', minRadius) #--- maxRadius cmds.setAttr(node[-1] + '.maxRadius', maxRadius) #--- parent the group under the specified parent if parent: if not isinstance(parent, list): cmds.parent(node_grp, parent) else: raise Exception("Specified parent: " + parent + 'is not a valid') #--- show or hide transform if not show: cmds.setAttr(node[0] + '.v', 0) #--- lock specified attributes if lockAttr: if node[-1]: cmds.setAttr(node[-1] + '.' + lockAttr, lock = True) #--- set isHistoricalInteresting attribute if not ihi: for n in node: cmds.setAttr(n + '.ihi', 0) #--- return node return node
for x in range(0, len(sel)): num = (x%10)+1 thisTarget = "lf_stripWaveDriver%02d_geo"%num BS = cmds.blendShape(thisTarget, sel[x], origin="local") cmds.blendShape(BS, e=True, w=[(0,1)]) #to create bend deformers on each of the driving cards and orient them correctly import maya.cmds as cmds sel = cmds.ls(sl=True) for obj in sel: bend = cmds.nonLinear(obj, type="bend", lowBound=-2.1, highBound=0, curvature=0) bendHandle = "%s_bend"%obj cmds.rename(bend[1], bendHandle) cmds.xform(bendHandle, os=True, r=True, ro=(0,0,0)) cmds.xform(bendHandle, os=True, r=True, t=(0,1,0)) #to replace side card geo with relatively shifted versions of the first one selected (so that can drive blend shapes) import maya.cmds as cmds #get all sel = cmds.ls(sl=True) #first is the base
add lattice non linear etc etc. @ param sel(list): poly mesh objects list """ if not sel: raise RuntimeError('Error:- no object to add stretch squash') sel = cmds.ls(sl=True) for each in sel: cmds.makeIdentity(each, apply=True, t=1, r=1, s=1, n=0) myLattice = cmds.lattice(each, dv=(6, 6, 6), oc=True) myGroup = cmds.createNode('transform', n=each + '_RG') cmds.parent(myLattice[1], myLattice[2], myGroup) cmds.hide(myGroup) myStretchSquash = cmds.nonLinear(each, typ='squash', lowBound=-1, highBound=1) squash = cmds.rename(myStretchSquash[0], 'squash_' + each) squashHandle = cmds.rename(myStretchSquash[1], 'squash_' + each + '_handle') myGroup = cmds.createNode('transform', n='_RG') cmds.parent(squashHandle, myGroup) cmds.hide(myGroup) myCluster = cmds.cluster(each) ctrlGrp = cmds.createNode('transform', n=each + '_grp') myController = cmds.circle(nr=(0, 0, 1), c=(0, 0, 0), r=2, ch=False, n=each + '_CTRL') cmds.parent(myController[0], ctrlGrp)
def flexiPlaneSetup(prefix='flexiPlane', numJoints=5): width = numJoints * 2 # Create Nurbs surface flexiPlane = cmds.nurbsPlane(w=width, lr=0.1, u=width / 2, v=1, ax=[0, 1, 0]) flexiPlane = cmds.rename(flexiPlane[0], '%s_surface01' % prefix) cmds.delete(flexiPlane, constructionHistory=1) # Create plane follicles mel.eval('createHair %s 1 2 0 0 0 0 1 0 1 1 1;' % str(width / 2)) for obj in ['hairSystem1', 'pfxHair1', 'nucleus1']: cmds.delete(obj) folChildren = cmds.listRelatives('hairSystem1Follicles', ad=1) cmds.delete([i for i in folChildren if 'curve' in i]) folGrp = cmds.rename('hairSystem1Follicles', '%s_flcs01' % prefix) alphabetList = map(chr, range(97, 123)) folChildren = cmds.listRelatives(str(folGrp), c=1) for obj, letter in zip(folChildren, alphabetList): folJnt = cmds.joint(p=cmds.xform(obj, t=1, q=1), n='%s_bind_%s01' % (prefix, letter)) cmds.parent(folJnt, obj) cmds.rename(obj, '%s_flc_%s01' % (prefix, letter)) # Add controls squareCons = ['%s_cnt_a01' % prefix, '%s_cnt_b01' % prefix, '%s_midBend01' % prefix] for squareCon in squareCons: squareCon = cmds.curve(n=squareCon, d=1, p=[(-1, 0, -1), (1, 0, -1), (1, 0, 1), (-1, 0, 1), (-1, 0, -1)]) cmds.scale(.75, .75, .75, squareCon, r=1) cmds.setAttr('%s.overrideEnabled' % squareCon, 1) cmds.setAttr('%s.overrideColor' % squareCon, 17) cmds.xform(squareCon, roo='xzy') cmds.xform(squareCons[0], t=(-width / 2, 0, 0), ws=1) cmds.xform(squareCons[1], t=(width / 2, 0, 0), ws=1) cmds.xform(squareCons[2], t=(0, 0, 0), ws=1) cmds.makeIdentity(squareCons, a=1) squareConGrp = cmds.group(squareCons[0], squareCons[1], n='%s_cnts01' % prefix) midConGrp = cmds.group(squareCons[2], n='%s_midCnt01' % prefix) cmds.parent(midConGrp, squareConGrp) cmds.pointConstraint(squareCons[1], squareCons[0], midConGrp, mo=0) # Create a target blendshape controlled by deformers flexiBlend = cmds.duplicate(flexiPlane, n='flexiPlaneSetup_bShp_surface01') flexiBlendNode = cmds.blendShape(flexiBlend, flexiPlane, n='%s_bShpNode_surface01' % prefix) cmds.setAttr('%s.%s' % (flexiBlendNode[0], flexiBlend[0]), 1) wireCurve = cmds.curve(n='%s_wire_surface01' % prefix, d=2, p=[(-width / 2, 0, 0), (0, 0, 0), (width / 2, 0, 0)]) topClstr = cmds.cluster('%s.cv[0:1]' % wireCurve, rel=1, n='%s_cl_a01' % prefix) midClstr = cmds.cluster('%s.cv[1]' % wireCurve, rel=1, n='%s_cl_mid01' % prefix) botClstr = cmds.cluster('%s.cv[1:2]' % wireCurve, rel=1, n='%s_cl_b01' % prefix) clsGrp = cmds.group(topClstr, midClstr, botClstr, n='%s_cls01' % prefix) for attr in ['scalePivot', 'rotatePivot']: cmds.setAttr('%s.%s' % (topClstr[1], attr), -width / 2, 0, 0) for attr in ['scalePivot', 'rotatePivot']: cmds.setAttr('%s.%s' % (botClstr[1], attr), width / 2, 0, 0) cmds.setAttr('%sShape.originX' % topClstr[1], (-width / 2)) cmds.setAttr('%sShape.originX' % botClstr[1], (width / 2)) cmds.percent(topClstr[0], '%s.cv[1]' % wireCurve, v=0.5) cmds.percent(botClstr[0], '%s.cv[1]' % wireCurve, v=0.5) # Create twist and wire blend shape deformers twistNode = cmds.nonLinear(flexiBlend, type='twist') cmds.wire(flexiBlend, w=wireCurve, dds=[0, 20], foc=0, n='%s_wireAttrs_surface01' % prefix) cmds.xform(twistNode, ro=(0, 0, 90)) twistNode[0] = cmds.rename(twistNode[0], '%s_twistAttrs_surface01' % prefix) twistNode[1] = cmds.rename(twistNode[1], '%s_twist_surface01' % prefix) # Connect controls to cluster deformers cmds.connectAttr('%s.translate' % squareCons[0], '%s.translate' % topClstr[1]) cmds.connectAttr('%s.translate' % squareCons[1], '%s.translate' % botClstr[1]) cmds.connectAttr('%s.translate' % squareCons[2], '%s.translate' % midClstr[1]) # Connect controls to twist deformer cmds.connectAttr('%s.rotateX' % squareCons[0], '%s.endAngle' % twistNode[0]) cmds.connectAttr('%s.rotateX' % squareCons[1], '%s.startAngle' % twistNode[0]) # Organize hiearchy nodes and groups rootGrp = cmds.group(em=1, n='%s01' % prefix) moveGrp = cmds.group(em=1, n='%s_globalMove01' % prefix) extrasGrp = cmds.group(em=1, n='%s_extraNodes01' % prefix) cmds.parent(flexiBlend, folGrp, wireCurve, twistNode[1], clsGrp, '%s_wire_surface01BaseWire' % prefix, extrasGrp) cmds.parent(flexiPlane, squareConGrp, moveGrp) cmds.parent(moveGrp, extrasGrp, rootGrp) # Scale contraint each follicle to global move group for fol in cmds.listRelatives(folGrp, c=1): cmds.scaleConstraint(moveGrp, fol, mo=0)
def dpHeadDeformer(self, *args): """ Create the arrow curve and deformers (squash and bends). """ # get a list of selected items selList = cmds.ls(selection=True) if selList: # twist deformer twistDefList = cmds.nonLinear(selList, name="TwistHead", type="twist") defSize = cmds.getAttr(twistDefList[0]+".highBound") defScale = cmds.getAttr(twistDefList[1]+".scaleY") defTy = -(defSize * defScale) defTy = self.dpCheckLinearUnit(defTy) cmds.setAttr(twistDefList[0]+".lowBound", 0) cmds.setAttr(twistDefList[0]+".highBound", (defSize * 2)) cmds.setAttr(twistDefList[1]+".ty", defTy) # squash deformer squashDefList = cmds.nonLinear(selList, name="SquashHead", type="squash") cmds.setAttr(squashDefList[0]+".highBound", (defSize * 4)) cmds.setAttr(squashDefList[1]+".ty", defTy) cmds.setAttr(squashDefList[0]+".startSmoothness", 1) # side bend deformer sideBendDefList = cmds.nonLinear(selList, name="BendSideHead", type="bend") cmds.setAttr(sideBendDefList[0]+".lowBound", 0) cmds.setAttr(sideBendDefList[0]+".highBound", (defSize * 4)) cmds.setAttr(sideBendDefList[1]+".ty", defTy) # front bend deformer frontBendDefList = cmds.nonLinear(selList, name="BendFrontHead", type="bend") cmds.setAttr(frontBendDefList[0]+".lowBound", 0) cmds.setAttr(frontBendDefList[0]+".highBound", (defSize * 4)) cmds.setAttr(frontBendDefList[1]+".ry", -90) cmds.setAttr(frontBendDefList[1]+".ty", defTy) # arrow control curve arrowCtrl = self.dpCvArrow(self.headName+"Deformer_Ctrl") # add control intensite attributes cmds.addAttr(arrowCtrl, longName="intensityX", attributeType='float', keyable=True) cmds.addAttr(arrowCtrl, longName="intensityY", attributeType='float', keyable=True) cmds.addAttr(arrowCtrl, longName="intensityZ", attributeType='float', keyable=True) cmds.setAttr(arrowCtrl+".intensityX", 0.1) cmds.setAttr(arrowCtrl+".intensityY", 0.1) cmds.setAttr(arrowCtrl+".intensityZ", 0.1) # multiply divide in order to intensify influences mdNode = cmds.createNode("multiplyDivide", name=self.headName+"Deformer_MD") mdTwistNode = cmds.createNode("multiplyDivide", name=self.headName+"Deformer_Twist_MD") cmds.setAttr(mdTwistNode+".input2Y", -1) # connections cmds.connectAttr(arrowCtrl+".tx", mdNode+".input1X", force=True) cmds.connectAttr(arrowCtrl+".ty", mdNode+".input1Y", force=True) cmds.connectAttr(arrowCtrl+".tz", mdNode+".input1Z", force=True) cmds.connectAttr(arrowCtrl+".ry", mdTwistNode+".input1Y", force=True) cmds.connectAttr(arrowCtrl+".intensityX", mdNode+".input2X", force=True) cmds.connectAttr(arrowCtrl+".intensityY", mdNode+".input2Y", force=True) cmds.connectAttr(arrowCtrl+".intensityZ", mdNode+".input2Z", force=True) cmds.connectAttr(mdNode+".outputX", sideBendDefList[0]+".curvature", force=True) cmds.connectAttr(mdNode+".outputY", squashDefList[0]+".factor", force=True) cmds.connectAttr(mdNode+".outputZ", frontBendDefList[0]+".curvature", force=True) cmds.connectAttr(mdTwistNode+".outputY", twistDefList[0]+".endAngle", force=True) # change squash to be more cartoon cmds.setDrivenKeyframe(squashDefList[0]+".lowBound", currentDriver=mdNode+".outputY", driverValue=-1, value=-4, inTangentType="auto", outTangentType="auto") cmds.setDrivenKeyframe(squashDefList[0]+".lowBound", currentDriver=mdNode+".outputY", driverValue=0, value=-2, inTangentType="auto", outTangentType="auto") cmds.setDrivenKeyframe(squashDefList[0]+".lowBound", currentDriver=mdNode+".outputY", driverValue=2, value=-1, inTangentType="auto", outTangentType="flat") # fix side values axisList = ["X", "Y", "Z"] for axis in axisList: unitConvNode = cmds.listConnections(mdNode+".output"+axis, destination=True)[0] if unitConvNode: if cmds.objectType(unitConvNode) == "unitConversion": cmds.setAttr(unitConvNode+".conversionFactor", 1) attrList = ['rx', 'rz', 'sx', 'sy', 'sz', 'v'] for attr in attrList: cmds.setAttr(arrowCtrl+"."+attr, lock=True, keyable=False) cmds.setAttr(arrowCtrl+".intensityX", edit=True, keyable=False, channelBox=True) cmds.setAttr(arrowCtrl+".intensityY", edit=True, keyable=False, channelBox=True) cmds.setAttr(arrowCtrl+".intensityZ", edit=True, keyable=False, channelBox=True) # create groups arrowCtrlGrp = cmds.group(arrowCtrl, name=self.headName+"Deformer_Ctrl_Grp") cmds.setAttr(arrowCtrlGrp+".ty", -1.75*defTy) cmds.group((squashDefList[1], sideBendDefList[1], frontBendDefList[1], twistDefList[1]), name=self.headName+"Deformer_Data_Grp") # finish selection the arrow control cmds.select(arrowCtrl) else: mel.eval("warning \""+self.langDic[self.langName]['i034_notSelHeadDef']+"\";")
def rigSpine (crvName,tailCntrlJoints,waveControlObject,splitJoints): """ Rebuild curve - with actual curve in it!""" """ first have to make our reg spine""" mc.rebuildCurve (crvName, ch=0, rpo=1, rt=0, end=0, kr=0, kcp=0, kep=1, kt=0, s=(splitJoints), d=1, tol=5) """ Make joint chains""" spineJoints = joints.createJointsFromCurve (crvName,'spine') """ set joint radius """ joints.setGoodJointRadius (spineJoints,1) """ Orienting the joint chain """ joints.orientJointChain (spineJoints, 'xyz', 'zup') """ Renaming the joint chain """ spineJointsBuffer = names.renameJointChainList (spineJoints, 'tailStart', 'tail') spineJoints = spineJointsBuffer """ removing initial bind from the spine curve """ mc.delete ('bindPose1') mc.delete ('skinCluster1') """ Makes our control surface """ controlSurface = makeJointControlSurfaceFish(spineJoints[0],tailCntrlJoints,'y','tail') """ parenting the tail joints """ rigging.parentListToHeirarchy (tailCntrlJoints) #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>auto swim stuff """ Creating our deformation surface """ deformMeshBuffer = mc.duplicate (controlSurface) deformMesh = mc.rename (deformMeshBuffer[0],(controlSurface[0]+'_defmesh')) """ Creates our wave deformer """ deformerBuffer = mc.nonLinear (deformMesh, type = 'wave', name = 'swimWave') waveDeformer = mc.rename (deformerBuffer[0], 'waveDeformer') waveDeformerHandle = mc.rename (deformerBuffer[1], 'waveDeformerHandle') """ move the handle """ position.movePointSnap (waveDeformerHandle,spineJoints[0]) mc.setAttr ((waveDeformerHandle+'.rx'),90) mc.setAttr ((waveDeformerHandle+'.ry'),90) """ set some variables """ mc.setAttr ((waveDeformer+'.dropoff'),1) mc.setAttr ((waveDeformer+'.dropoffPosition'),1) mc.setAttr ((waveDeformer+'.maxRadius'),2) """ make our blendshape node and reorder things""" blendshapeNode = mc.blendShape (deformMesh, controlSurface[0], name = 'swim_bsNode' ) mc.reorderDeformers ("tweak2", blendshapeNode[0],controlSurface[0]) """ add some attrs to our wave control object """ attributes.addSectionBreakAttrToObj (waveControlObject, 'swim') attributes.addFloatAttributeToObject (waveControlObject, 'auto', min = 0, max = 1, dv =0) attributes.addFloatAttributeToObject (waveControlObject, 'speed', -100, 100, 0) attributes.addFloatAttributeToObject (waveControlObject, 'wavelength', 0, 10, 5) attributes.addFloatAttributeToObject (waveControlObject, 'amplitude', 0, 10, 0) attributes.addFloatAttributeToObject (waveControlObject, 'dropoff', 0, 1, 1) attributes.addFloatAttributeToObject (waveControlObject, 'dropoffPosition', 0, 1, 0) attributes.addFloatAttributeToObject (waveControlObject, 'minRadius', 0, 10, 0) attributes.addFloatAttributeToObject (waveControlObject, 'maxRadius', 0, 10, 10) """ connect a few attrs """ mc.connectAttr ((waveControlObject+'.auto'),(blendshapeNode[0]+'.'+deformMesh)) mc.connectAttr ((waveControlObject+'.wavelength'),(waveDeformer+'.wavelength')) mc.connectAttr ((waveControlObject+'.amplitude'),(waveDeformer+'.amplitude')) mc.connectAttr ((waveControlObject+'.dropoff'),(waveDeformer+'.dropoff')) mc.connectAttr ((waveControlObject+'.dropoffPosition'),(waveDeformer+'.dropoffPosition')) mc.connectAttr ((waveControlObject+'.minRadius'),(waveDeformer+'.minRadius')) mc.connectAttr ((waveControlObject+'.maxRadius'),(waveDeformer+'.maxRadius')) """ set some good base values """ mc.setAttr ((waveControlObject+'.speed'),1) mc.setAttr ((waveControlObject+'.wavelength'),4) mc.setAttr ((waveControlObject+'.amplitude'),.3) mc.setAttr ((waveControlObject+'.dropoff'),1) mc.setAttr ((waveControlObject+'.dropoffPosition'),1) mc.setAttr ((waveControlObject+'.maxRadius'),2) """ sets up swim speed """ nodes.offsetCycleSpeedControlNodeSetup (waveDeformer,(waveControlObject+'.speed'),90,-10) #>>>>>>>>>>>>>>>>>>>>>>>>>>>> Head control and joint headJointBuffer = mc.duplicate ('head_anim') headJoint = mc.rename (headJointBuffer, 'head_jnt') headCtrlGrp = rigging.groupMeObject ('head_anim',True) #mc.parent (headJoint, spineJoints[0]) mc.parent (headJoint, 'move_anim') contsBuffer = mc.parentConstraint (spineJoints[0], headCtrlGrp, maintainOffset = True) mc.rename (contsBuffer,(headCtrlGrp+'_prntConst')) contsBuffer = mc.parentConstraint ('head_anim', headJoint, maintainOffset = True) mc.rename (contsBuffer,(headJoint+'_prntConst')) mc.parent (headCtrlGrp,'move_anim') #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Clean stuff """ deform group """ deformGrp = mc.group (n= 'swimDeform_grp', w=True, empty=True) mc.parent (waveDeformerHandle,deformGrp) mc.parent (deformMesh,deformGrp) mc.setAttr ((deformGrp+'.v'), 0) mc.setAttr ((controlSurface[0]+'.v'),0) """ delete placement stuff """ mc.delete ('curvePlacementStuff') mc.parent (tailCntrlJoints[0],waveControlObject) mc.parent (deformGrp, 'rigStuff_grp') #>>>>>>>>>>>>>>>>>>>>>>>>>>>> Ctrl Joints to Ctrls ctrlSize = (distance.returnAverageDistanceBetweenObjects (tailCntrlJoints)) curves.parentShape ('head_anim', 'sampleCtrlZ') for ctrl in tailCntrlJoints: rigging.makeObjCtrl (ctrl,ctrlSize) #>>>>>>>>>>>>>>>>>>>>>Store skin joint data """ check for master skin info group """ name = 'spine' if mc.objExists ('master_skinJntList_grp'): masterSkinJointList = ('master_skinJntList_grp') else: masterSkinJointList = mc.group (n= ('master_skinJntList_grp'), w=True, empty=True) mc.parent(masterSkinJointList,'rigStuff_grp') """ check for segment skin info group """ if mc.objExists (name+'_skinJntList_grp'): skinJointList = (name+'_skinJntList_grp') else: skinJointList = mc.group (n= (name+'_skinJntList_grp'), w=True, empty=True) mc.parent (skinJointList,masterSkinJointList) attributes.storeObjNameToMessage (skinJointList,masterSkinJointList) """ store the skin joint data """ for jnt in spineJoints: attributes.storeObjNameToMessage (jnt,skinJointList) attributes.storeObjNameToMessage (headJoint,skinJointList)
def createBendToCurve( curve ): import math curve = sgModelDag.getTransform( curve ) cvs = cmds.ls( curve+'.cv[*]', fl=1 ) startPoint= cmds.xform( cvs[0], q=1, ws=1, t=1 ) endPoint = cmds.xform( cvs[-1], q=1, ws=1, t=1 ) bend, handle = cmds.nonLinear( curve, type='bend', lowBound=0, highBound=1, curvature=0) cmds.xform( handle, ws=1, t=startPoint ) vStartPoint = sgModelConvert.convertMVectorFromPointList( startPoint ) vEndPoint = sgModelConvert.convertMVectorFromPointList( endPoint ) vAim = vEndPoint - vStartPoint yVector = om.MVector( *[0,1,0] ) zVector = om.MVector( *[1,0,0] ) dotY = math.fabs(vAim * yVector) dotZ = math.fabs(vAim * zVector) vUp = None if dotY > dotZ: vUp = zVector else: vUp = yVector vCross = vAim ^ vUp vUp = vCross ^ vAim lengthAim = vAim.length() vUp.normalize() vCross.normalize() vUp *= lengthAim vCross *= lengthAim mtx = [ vCross.x, vCross.y, vCross.z, 0, vAim.x, vAim.y, vAim.z, 0, vUp.x, vUp.y, vUp.z, 0, vStartPoint.x, vStartPoint.y, vStartPoint.z, 1 ] cmds.xform( handle, ws=1, matrix=mtx ) handle, handleGrp = sgRigDag.addParent( handle ) sgRigAttribute.addAttr( curve, ln='globalTwist', k=1 ) sgRigAttribute.addAttr( curve, ln='globalBend', k=1 ) sgRigAttribute.addAttr( curve, ln='twist', k=1, dv=0 ) sgRigAttribute.addAttr( curve, ln='bend', k=1, dv=1 ) addTwist = cmds.createNode( 'addDoubleLinear' ) multBend = cmds.createNode( 'multDoubleLinear' ) cmds.connectAttr( curve+'.globalTwist', addTwist+'.input1' ) cmds.connectAttr( curve+'.twist', addTwist+'.input2' ) cmds.connectAttr( curve+'.globalBend', multBend+'.input1' ) cmds.connectAttr( curve+'.bend', multBend+'.input2' ) cmds.connectAttr( multBend+'.output', bend+'.curvature' ) cmds.connectAttr( addTwist+'.output', handle+'.ry' )
def twist(self, character = None, mod = None, side = None, name = None, suffix = None, geometry = None, position = [0,0,0], rotation = [0,0,0], envelope = 1, startAngle = 0, endAngle = 0, lowBound = -1, highBound = 1, parent = None, show = True, lockAttr = None, ihi = True): #--- this method creates a twist deformer #--- select the specified geometry cmds.select(geometry) #--- create a twist deformer node = cmds.nonLinear(type = 'twist') #--- filter the individual name filter_name = (name + node[0].split('Handle')[0][0].upper() + node[0].split('Handle')[0][1:]) #--- rename the twist deformer node = self.__rename_node(mod = mod, side = side, name = filter_name, suffix = suffix, obj = node) #--- create a group on top and parent the deformer under the group node_grp = cmds.createNode('transform', parent = node[0]) cmds.parent(node_grp, world = True) cmds.parent(node[0], node_grp) #--- rename the node group node_grp = self.__rename_node(mod = mod, side = side, name = filter_name, suffix = 'GRP', obj = node_grp)[0] #--- reposition the transform of the deformer locally cmds.xform(node[0], translation = position, worldSpace = False) cmds.xform(node[0], rotation = rotation, worldSpace = False) #--- take care of the node's settings #--- envelope cmds.setAttr(node[-1] + '.envelope', envelope) #--- startAngle cmds.setAttr(node[-1] + '.startAngle', startAngle) #--- endAngle cmds.setAttr(node[-1] + '.endAngle', endAngle) #--- lowBound cmds.setAttr(node[-1] + '.lowBound', lowBound) #--- highBound cmds.setAttr(node[-1] + '.highBound', highBound) #--- parent the group under the specified parent if parent: if not isinstance(parent, list): cmds.parent(node_grp, parent) else: raise Exception("Specified parent: " + parent + 'is not a valid') #--- show or hide transform if not show: cmds.setAttr(node[0] + '.v', 0) #--- lock specified attributes if lockAttr: if node[-1]: cmds.setAttr(node[-1] + '.' + lockAttr, lock = True) #--- set isHistoricalInteresting attribute if not ihi: for n in node: cmds.setAttr(n + '.ihi', 0) #--- return node return node
import maya.cmds as cmds sels = cmds.ls( sl=1 ) source = sels[0] targets = sels[1:] hists = cmds.listHistory( source, pdo=1 ) hists.reverse() for hist in hists: print hist, cmds.nodeType( hist ) if cmds.nodeType( hist ) == 'nonLinear': for target in targets: cmds.nonLinear( hist, e=1, geometry=target ) elif cmds.nodeType( hist ) == 'wire': for target in targets: cmds.wire( hist, e=1, geometry=target ) elif cmds.nodeType( hist ) == 'ffd': for target in targets: cmds.lattice( hist, e=1, geometry=target )
def nonLinear(*args, **kwargs): res = cmds.nonLinear(*args, **kwargs) if not kwargs.get('query', kwargs.get('q', False)): res = _factories.maybeConvert(res, _general.PyNode) return res
def ribbonBuild(): # check for matrixNodes.mll plug (comes with Maya, but might be off) if cmds.pluginInfo('matrixNodes.mll', q=True) == False: cmds.loadPlugin('matixNodes.mll') max = 3 rstats = ["castsShadows", "receiveShadows", "motionBlur", "primaryVisibility", "smoothShading", "smoothShading", "visibleInReflections", "visibleInRefractions"] locGrp = cmds.group( em=True, n="ribbon_grp_#" ) # set primary vector (down the chain, i.e: x, y or z) and other default values jointDown = 'x' divisions = 3 planeW = divisions * 2 posIncr = 0 increment = 0.5 v = 0.5 # create the ribbon nurb surface nameFP = cmds.nurbsPlane( ch=False, u=divisions, v=1, ax=[0,1,0], p=[0,0,0], lr=0.2, w=planeW, n="ribbonPlane1" )[0] # diag print print( increment ) print( posIncr ) for i in xrange(0, divisions): posNode = cmds.pointOnSurface( nameFP, ch=True, top=1, u=posIncr, v=0.5 ) posLoc = cmds.group(em=True, n='posNode_'+ str(i)) cmds.connectAttr( '{0}.position'.format(posNode), '{0}.translate'.format(posLoc) ) posIncr += 0.5 posX = cmds.getAttr( '{0}.positionX'.format(posNode) ) posY = cmds.getAttr( '{0}.positionY'.format(posNode) ) posZ = cmds.getAttr( '{0}.positionZ'.format(posNode) ) newJoint = cmds.joint(p=[posX, posY, posZ], n='ribbon_jnt_bn') # set-up parent rotations for joints to follow surface correctly # this follows a process similar to Michael Bazhutkin's river script aimCon = cmds.createNode('aimConstraint') cmds.connectAttr( '{0}.normal'.format(posNode), '{0}.target[0].targetTranslate'.format(aimCon), f=True ) cmds.connectAttr( '{0}.tangentV'.format(posNode), '{0}.worldUpVector'.format(aimCon), f=True ) cmds.connectAttr( '{0}.constraintRotate'.format(aimCon), '{0}.rotate'.format(posLoc), f=True ) cmds.parent(aimCon, posLoc) cmds.parent(posLoc, locGrp) # switch statement look-alike for py.. for case in switch(jointDown): if case('x'): cmds.setAttr( '{0}.aimVector'.format(aimCon), type='double3', *list( (0,1,0) ) ) cmds.setAttr( '{0}.upVector'.format(aimCon), type='double3', *list( (0,0,1) ) ) break if case('y'): cmds.setAttr( '{0}.aimVector'.format(aimCon), type='double3', *list( (0,1,0) ) ) cmds.setAttr( '{0}.upVector'.format(aimCon), type='double3', *list( (0,0,1) ) ) break if case('z'): cmds.setAttr( '{0}.aimVector'.format(aimCon), type='double3', *list( (0,1,0) ) ) cmds.setAttr( '{0}.upVector'.format(aimCon), type='double3', *list( (0,0,1) ) ) break if case(): #default print("Couldn't found a valid joint down value (x, y, z") #print 'lol' topCtrl = cmds.circle( n='ribbon1_top_ctrl', ch=False )[0] botCtrl = cmds.circle( n='ribbon1_bottom_ctrl', ch=False )[0] midCtrl = cmds.circle( n='ribbon1_mid_ctrl', ch=False )[0] # set to origin (creation points were recorded away from origin, otherwise this would be unnecessary) setToOrigin(topCtrl) setToOrigin(botCtrl) # two more curves that will serve as the god ctrl leftMainCurve = cmds.circle( n='pHolder_1', ch=False, r=0.3)[0] rightMainCurve = cmds.circle( n='pHolder_2',ch=False, r=0.3)[0] setToOrigin(leftMainCurve) setToOrigin(rightMainCurve) # groupFreeze stuff topOffset = grpFreeze(topCtrl) botOffset = grpFreeze(botCtrl) midOffset = grpFreeze(midCtrl) # position things topCtrlPOS = cmds.pointOnSurface(nameFP, ch=False, p=True, u=1, v=0.5) midCtrlPOS = cmds.pointOnSurface(nameFP, ch=False, p=True, u=0.5, v=0.5) botCtrlPOS = cmds.pointOnSurface(nameFP, ch=False, p=True, u=0, v=0.5) cmds.setAttr('{0}.translate'.format(topOffset), *topCtrlPOS ) cmds.setAttr('{0}.translate'.format(midOffset), *midCtrlPOS ) cmds.setAttr('{0}.translate'.format(botOffset), *botCtrlPOS ) midCtrlPOS[2] -= 1.5 cmds.setAttr('{0}.translate'.format(rightMainCurve), *midCtrlPOS ) midCtrlPOS[2] += 3.0 cmds.setAttr('{0}.translate'.format(leftMainCurve), *midCtrlPOS ) midCtrlPOS[2] -= 1.5 # create god ctrl for ribbon mainCtrl = cmds.group(em=True, n='ribbon_main_ctrl') parentShape(rightMainCurve, mainCtrl) parentShape(leftMainCurve, mainCtrl) mainCtrlOffset = grpFreeze(mainCtrl) # point constraint god ctrl freeze grp between top and bot midCtrlPC = cmds.pointConstraint( topCtrl, botCtrl, midOffset, mo=False, w=1) # create bShape for surface bShape = cmds.duplicate(nameFP, n='ribbon_bShape_1')[0] cmds.xform(bShape, ws=True, t=[0,0,5]) bShapeNode = cmds.blendShape(bShape, nameFP, en=1, n='ribbon_blendNode_1') cmds.setAttr('{0}.{1}'.format(bShapeNode[0],bShape), 1) # get POSI position of 0%, 50% and 100% of surface to get wire curve positions cInitPOS = cmds.pointOnSurface(bShape, p=True, top=1, u=0.0, v=0.5) cMidPOS = cmds.pointOnSurface(bShape, p=True, top=1, u=0.5, v=0.5) cEndPOS = cmds.pointOnSurface(bShape, p=True, top=1, u=1, v=0.5) # wire, clusters rWireCurve = cmds.curve( n='ribbon_wire_curve_1', p=[ cInitPOS, cMidPOS, cEndPOS ], d=2, k=[0,0,1,1] ) wireCIn = cmds.cluster('{0}.cv[0:1]'.format(rWireCurve), rel=True, en=1, n='ribbon_wireCL_init_1') wireCMid = cmds.cluster('{0}.cv[1]'.format(rWireCurve), rel=True, en=1, n='ribbon_wireCL_mid_1') wireCEnd = cmds.cluster('{0}.cv[1:2]'.format(rWireCurve), rel=True, en=1, n='ribbon_wireCL_end_1') # cluster pivots and origins cDict = { wireCIn[1] : cInitPOS, wireCMid[1] : cMidPOS, wireCEnd[1] : cEndPOS } for cl, pos in cDict.items(): #print pos cmds.xform(cl, pivots= pos) cmds.setAttr('{0}Shape.origin'.format(cl), *pos) # cluster weights cmds.percent(wireCIn[0], '{0}.cv[1]'.format(rWireCurve), v=0.5 ) cmds.percent(wireCEnd[0], '{0}.cv[1]'.format(rWireCurve), v=0.5 ) # bShape deformers [could also just skin surface to previously created joints..] wireDeformer = cmds.wire(bShape, dds=[(1,25), (0,25)], en=1, ce=0, li=0, w=rWireCurve, n='ribbon_bShape_wireNode_1') twistDeformer = cmds.nonLinear( bShape, type='twist', foc=1, n='ribbon_bShape_twistNode_1') cmds.setAttr('{0}.rotateZ'.format(twistDeformer[1]), 90) cmds.hide(twistDeformer[1]) for attr in rstats: cmds.setAttr('{0}Shape.{1}'.format(bShape, attr), 0) cmds.setAttr('{0}Shape.{1}'.format(nameFP, attr), 0) # connect controls to cluster handles ctrlDict = {topCtrl : wireCEnd[1], midCtrl : wireCMid[1], botCtrl : wireCIn[1] } for ctrl, cl in ctrlDict.items(): cmds.connectAttr('{0}.translate'.format(ctrl), '{0}.translate'.format(cl), f=True ) cmds.connectAttr('{0}.rotateX'.format(botCtrl), '{0}.endAngle'.format(twistDeformer[0]) ) cmds.connectAttr('{0}.rotateX'.format(topCtrl), '{0}.startAngle'.format(twistDeformer[0]) ) # group stuff controlsGrp = cmds.group(em=True, n='ribbon_controls_grp_1') cmds.parent( topOffset, midOffset, botOffset, controlsGrp ) clustersGrp = cmds.group(em=True, n='ribbon_clusters_grp_1') cmds.parent( wireCIn[1], wireCMid[1], wireCEnd[1], clustersGrp ) moveGrp = cmds.group(em=True, n='ribbon_move_grp_1') cmds.parent(controlsGrp, nameFP, moveGrp) extraGrp = cmds.group(em=True, n='ribbon_extras_grp_1') cmds.parent( clustersGrp, locGrp, rWireCurve, '{0}BaseWire'.format(rWireCurve), bShape, twistDeformer[1], extraGrp) godGrp = cmds.group(em=True, n='ribbon_main_grp_1') cmds.parent( extraGrp, mainCtrlOffset, godGrp ) cmds.parent( moveGrp, mainCtrl ) toHideList = [ bShape, rWireCurve, clustersGrp ] for object in toHideList: cmds.hide(object) locators = cmds.listRelatives(locGrp, c=True) for loc in locators: cmds.scaleConstraint(moveGrp, loc, offset=[1,1,1])
def buildDeformers(self, ribbonPlane, controls=(), folGrp=()): # Create a target blendshape controlled by deformers flexiBlend = cmds.duplicate(ribbonPlane, n='flexiPlaneSetup_bShp_surface01') flexiBlendNode = cmds.blendShape(flexiBlend, ribbonPlane, n='%s_bShpNode_surface01' % self.name) # Turn blendshape on cmds.setAttr('%s.%s' % (flexiBlendNode[0], flexiBlend[0]), 1) # Create a wire deformer controled by ribbon controls wireCurve = cmds.curve(n='%s_wire_surface01' % self.name, d=2, p=[(-self.numJnts, 0, 0), (0, 0, 0), (self.numJnts, 0, 0)]) topClstr = cmds.cluster('%s.cv[0:1]' % wireCurve, rel=1, n='%s_cl_a01' % self.name) midClstr = cmds.cluster('%s.cv[1]' % wireCurve, rel=1, n='%s_cl_mid01' % self.name) botClstr = cmds.cluster('%s.cv[1:2]' % wireCurve, rel=1, n='%s_cl_b01' % self.name) clsGrp = cmds.group(topClstr, midClstr, botClstr, n='%s_cls01' % self.name) for attr in ['scalePivot', 'rotatePivot']: cmds.setAttr('%s.%s' % (topClstr[1], attr), -self.numJnts, 0, 0) for attr in ['scalePivot', 'rotatePivot']: cmds.setAttr('%s.%s' % (botClstr[1], attr), self.numJnts, 0, 0) cmds.setAttr('%sShape.originX' % topClstr[1], (-self.numJnts)) cmds.setAttr('%sShape.originX' % botClstr[1], (self.numJnts)) cmds.percent(topClstr[0], '%s.cv[1]' % wireCurve, v=0.5) cmds.percent(botClstr[0], '%s.cv[1]' % wireCurve, v=0.5) # Create twist and wire blend shape deformers twistNode = cmds.nonLinear(flexiBlend, type='twist') cmds.wire(flexiBlend, w=wireCurve, dds=[0, 20], foc=0, n='%s_wireAttrs_surface01' % self.name) cmds.xform(twistNode, ro=(0, 0, 90)) twistNode[0] = cmds.rename(twistNode[0], '%s_twistAttrs_surface01' % self.name) twistNode[1] = cmds.rename(twistNode[1], '%s_twist_surface01' % self.name) # Setup squash and stretch via utilitiy nodes arcLen = cmds.arclen(wireCurve, ch=1) arcLen = cmds.rename(arcLen, '%s_curveInfo01' % self.name) arcLenValue = cmds.getAttr('%s.arcLength' % arcLen) squashDivNode = cmds.createNode('multiplyDivide', n='%s_div_squashStretch_length01' % self.name) volDivNode = cmds.createNode('multiplyDivide', n='%s_div_volume01' % self.name) squashCondNode = cmds.createNode('condition', n='%s_cond_volume01' % self.name) cmds.setAttr('%s.operation' % squashDivNode, 2) cmds.setAttr('%s.input2X' % squashDivNode, arcLenValue) cmds.setAttr('%s.operation' % volDivNode, 2) cmds.setAttr('%s.input1X' % volDivNode, 1) cmds.setAttr('%s.secondTerm' % squashCondNode, 1) cmds.connectAttr('%s.arcLength' % arcLen, '%s.input1X' % squashDivNode) cmds.connectAttr('%s.outputX' % squashDivNode, '%s.input2X' % volDivNode) cmds.connectAttr('%s.outputX' % volDivNode, '%s.colorIfTrueR' % squashCondNode) # Set visibility options for obj in [flexiBlend[0], wireCurve, twistNode[1], clsGrp]: cmds.setAttr('%s.visibility' % obj, 0) # Connect controls to cluster deformers if they exist if len(controls) > 1: topCon = controls[0][0] botCon = controls[0][1] midCon = controls[0][2] for con, clstr in zip([topCon, botCon], [topClstr[1], botClstr[1]]): cmds.connectAttr('%s.translate' % con, '%s.translate' % clstr) cmds.connectAttr('%s.translate' % midCon, '%s.translate' % midClstr[1]) # Connect controls to twist deformer cmds.connectAttr('%s.rotateX' % topCon, '%s.endAngle' % twistNode[0]) cmds.connectAttr('%s.rotateX' % botCon, '%s.startAngle' % twistNode[0]) cmds.connectAttr('%s.volEnable' % controls[1], '%s.firstTerm' % squashCondNode) # Scale contraint each follicle to global move group for fol in cmds.listRelatives(folGrp, c=1): cmds.scaleConstraint(self.moveGrp, fol, mo=0) for shape in cmds.listRelatives(fol, s=1): cmds.setAttr('%s.visibility' % shape, 0) # Parent nodes cmds.parent(flexiBlend, wireCurve, clsGrp, twistNode[1], '%s_wire_surface01BaseWire' % self.name, self.extrasGrp)
def twist(self, character=None, mod=None, side=None, name=None, suffix=None, geometry=None, position=[0, 0, 0], rotation=[0, 0, 0], envelope=1, startAngle=0, endAngle=0, lowBound=-1, highBound=1, parent=None, show=True, lockAttr=None, ihi=True): #--- this method creates a twist deformer #--- select the specified geometry cmds.select(geometry) #--- create a twist deformer node = cmds.nonLinear(type='twist') #--- filter the individual name filter_name = (name + node[0].split('Handle')[0][0].upper() + node[0].split('Handle')[0][1:]) #--- rename the twist deformer node = self.__rename_node(mod=mod, side=side, name=filter_name, suffix=suffix, obj=node) #--- create a group on top and parent the deformer under the group node_grp = cmds.createNode('transform', parent=node[0]) cmds.parent(node_grp, world=True) cmds.parent(node[0], node_grp) #--- rename the node group node_grp = self.__rename_node(mod=mod, side=side, name=filter_name, suffix='GRP', obj=node_grp)[0] #--- reposition the transform of the deformer locally cmds.xform(node[0], translation=position, worldSpace=False) cmds.xform(node[0], rotation=rotation, worldSpace=False) #--- take care of the node's settings #--- envelope cmds.setAttr(node[-1] + '.envelope', envelope) #--- startAngle cmds.setAttr(node[-1] + '.startAngle', startAngle) #--- endAngle cmds.setAttr(node[-1] + '.endAngle', endAngle) #--- lowBound cmds.setAttr(node[-1] + '.lowBound', lowBound) #--- highBound cmds.setAttr(node[-1] + '.highBound', highBound) #--- parent the group under the specified parent if parent: if not isinstance(parent, list): cmds.parent(node_grp, parent) else: raise Exception("Specified parent: " + parent + 'is not a valid') #--- show or hide transform if not show: cmds.setAttr(node[0] + '.v', 0) #--- lock specified attributes if lockAttr: if node[-1]: cmds.setAttr(node[-1] + '.' + lockAttr, lock=True) #--- set isHistoricalInteresting attribute if not ihi: for n in node: cmds.setAttr(n + '.ihi', 0) #--- return node return node
def wave(self, character=None, mod=None, side=None, name=None, suffix=None, geometry=None, position=[0, 0, 0], rotation=[0, 0, 0], envelope=1, amplitude=0, wavelength=1, offset=0, dropoff=0, dropoffPosition=0, minRadius=0, maxRadius=1, parent=None, show=True, lockAttr=None, ihi=True): #--- this method creates a wave deformer #--- select the specified geometry cmds.select(geometry) #--- create a wave deformer node = cmds.nonLinear(type='wave') #--- filter the individual name filter_name = (name + node[0].split('Handle')[0][0].upper() + node[0].split('Handle')[0][1:]) #--- rename the wave deformer node = self.__rename_node(mod=mod, side=side, name=filter_name, suffix=suffix, obj=node) #--- create a group on top and parent the deformer under the group node_grp = cmds.createNode('transform', parent=node[0]) cmds.parent(node_grp, world=True) cmds.parent(node[0], node_grp) #--- rename the node group node_grp = self.__rename_node(mod=mod, side=side, name=filter_name, suffix='GRP', obj=node_grp) #--- reposition the transform of the deformer locally cmds.xform(node[0], translation=position, worldSpace=False) cmds.xform(node[0], rotation=rotation, worldSpace=False) #--- take care of the node's settings #--- envelope cmds.setAttr(node[-1] + '.envelope', envelope) #--- amplitude cmds.setAttr(node[-1] + '.amplitude', amplitude) #--- wavelength cmds.setAttr(node[-1] + '.wavelength', wavelength) #--- offset cmds.setAttr(node[-1] + '.offset', offset) #--- dropoff cmds.setAttr(node[-1] + '.dropoff', dropoff) #--- dropoffPosition cmds.setAttr(node[-1] + '.dropoffPosition', dropoffPosition) #--- minRadius cmds.setAttr(node[-1] + '.minRadius', minRadius) #--- maxRadius cmds.setAttr(node[-1] + '.maxRadius', maxRadius) #--- parent the group under the specified parent if parent: if not isinstance(parent, list): cmds.parent(node_grp, parent) else: raise Exception("Specified parent: " + parent + 'is not a valid') #--- show or hide transform if not show: cmds.setAttr(node[0] + '.v', 0) #--- lock specified attributes if lockAttr: if node[-1]: cmds.setAttr(node[-1] + '.' + lockAttr, lock=True) #--- set isHistoricalInteresting attribute if not ihi: for n in node: cmds.setAttr(n + '.ihi', 0) #--- return node return node
def CreateBookRig(self, AffectedObject): affected = AffectedObject self.widthValue = RMRigTools.RMPointDistance(self.width, self.origin) self.heightValue = RMRigTools.RMPointDistance(self.height, self.origin) parentGroup = cmds.group(empty=True, name="BookRig") self.NameConv.DefaultNames["System"] = parentGroup RMRigTools.RMAlign(self.origin, parentGroup, 3) cmds.select(affected) self.flare2, self.flareHandle2 = cmds.nonLinear( type="flare", lowBound=0, highBound=self.widthValue, name="FlareLeafsThick" ) self.flare2 = self.NameConv.RMRenameNameInFormat(self.flare2) self.flareHandle2 = self.NameConv.RMRenameNameInFormat(self.flareHandle2) RMRigTools.RMAlign(self.origin, self.flareHandle2, 3) cmds.xform(self.flareHandle2, objectSpace=True, rotation=[180, 0, 90]) cmds.setAttr(self.flareHandle2 + ".scale", 1, 1, 1) cmds.select(affected) self.flare, self.flareHandle = cmds.nonLinear( type="flare", lowBound=0, highBound=self.heightValue, name="FlareBorderRefinement" ) # endFlareX self.flare = self.NameConv.RMRenameNameInFormat(self.flare) self.flareHandle = self.NameConv.RMRenameNameInFormat(self.flareHandle) RMRigTools.RMAlign(self.origin, self.flareHandle, 3) cmds.setAttr(self.flareHandle + ".scale", 1, 1, 1) cmds.xform(self.flareHandle, objectSpace=True, translation=[self.widthValue / 2, 0, 0]) cmds.select(affected) self.bendSpread, self.bendHandleSpread = cmds.nonLinear( type="bend", lowBound=-self.widthValue, highBound=self.widthValue, curvature=0, name="bendSpread" ) # curvature self.bendSpread = self.NameConv.RMRenameNameInFormat(self.bendSpread) self.bendHandleSpread = self.NameConv.RMRenameNameInFormat(self.bendHandleSpread) RMRigTools.RMAlign(self.origin, self.bendHandleSpread, 3) cmds.xform(self.bendHandleSpread, objectSpace=True, rotation=[0, 0, 90]) cmds.setAttr(self.bendHandleSpread + ".scale", 1, 1, 1) cmds.select(affected) # self.bendMidle, self.bendHandleMiddle = cmds.nonLinear(type = 'bend', lowBound = 0 , highBound = self.heightValue / 2 , curvature = 0,name = "bendCenter")#curvature Hight Bound self.bendMidle, self.bendHandleMiddle = cmds.nonLinear( type="bend", lowBound=0, highBound=1, curvature=0, name="bendCenter" ) # curvature Hight Bound self.bendMidle = self.NameConv.RMRenameNameInFormat(self.bendMidle) self.bendHandleMiddle = self.NameConv.RMRenameNameInFormat(self.bendHandleMiddle) RMRigTools.RMAlign(self.origin, self.bendHandleMiddle, 3) cmds.setAttr(self.bendHandleMiddle + ".scale", 1, 1, 1) cmds.xform(self.bendHandleMiddle, objectSpace=True, translation=[0, self.heightValue / 2, 0]) cmds.select(affected) # self.bendOpen, self.bendHandleOpen = cmds.nonLinear(type = 'bend', lowBound = 0 , highBound = self.heightValue / 2 , curvature = 0,name = "bendOpen")#curvature Hight Bound self.bendOpen, self.bendHandleOpen = cmds.nonLinear( type="bend", lowBound=0, highBound=1, curvature=0, name="bendOpen" ) # curvature Hight Bound self.bendOpen = self.NameConv.RMRenameNameInFormat(self.bendOpen) self.bendHandleOpen = self.NameConv.RMRenameNameInFormat(self.bendHandleOpen) RMRigTools.RMAlign(self.origin, self.bendHandleOpen, 3) cmds.setAttr(self.bendHandleOpen + ".scale", 1, 1, 1) cmds.select(affected) # self.bendOpen, self.bendHandleOpen = cmds.nonLinear(type = 'bend', lowBound = 0 , highBound = self.heightValue / 2 , curvature = 0,name = "bendOpen")#curvature Hight Bound # self.bendOpenOposit, self.bendHandleOpenOposit = cmds.nonLinear(type = 'bend', lowBound = 0 , highBound = 1 , curvature = 0,name = "bendOpenOposit")#curvature Hight Bound # self.bendOpenOposit = self.NameConv.RMRenameNameInFormat(self.bendOpenOposit) # self.bendHandleOpenOposit = self.NameConv.RMRenameNameInFormat(self.bendHandleOpenOposit) # RMRigTools.RMAlign(self.origin, self.bendHandleOpenOposit,3) # cmds.setAttr(self.bendHandleOpenOposit + ".scale", 1 , 1 , 1) self.centerBendLocator = cmds.spaceLocator(name="centerBend")[0] self.centerBendLocator = self.NameConv.RMRenameNameInFormat(self.centerBendLocator) RMRigTools.RMAlign(self.bendHandleMiddle, self.centerBendLocator, 3) cmds.parent(self.bendHandleMiddle, self.centerBendLocator) cmds.parent(self.centerBendLocator, parentGroup) # cmds.xform( self.bendHandleOpen , objectSpace = True, translation = [self.widthValue,0,0]) # cmds.xform( self.bendHandleOpenOposit , objectSpace = True, translation = [-self.widthValue,0,0]) cmds.connectAttr(self.bendHandleOpen + ".scaleX", self.centerBendLocator + ".translateY") # cmds.connectAttr(self.bendHandleOpen+".scale",self.bendHandleOpenOposit+".scale") cmds.parent(self.bendHandleOpen, parentGroup) # cmds.parent( self.bendHandleOpenOposit, parentGroup ) cmds.parent(self.flareHandle, parentGroup) cmds.parent(self.bendHandleSpread, parentGroup) cmds.parent(self.flareHandle2, parentGroup) ControlResetPoint, Control = RMRigShapeControls.RMCircularControl(self.origin, NameConv=self.NameConv) self.AddAttributes(Control) self.LinkAttributes(Control)
def dpHeadDeformer(self, *args): """ Create the arrow curve and deformers (squash and bends). """ # defining variables headDeformerName = self.langDic[self.langName][ "c024_head"] + self.langDic[self.langName]["c097_deformer"] centerSymmetryName = self.langDic[self.langName][ "c098_center"] + self.langDic[self.langName]["c101_symmetry"] topSymmetryName = self.langDic[self.langName][ "c099_top"] + self.langDic[self.langName]["c101_symmetry"] intensityName = self.langDic[self.langName]["c049_intensity"] expandName = self.langDic[self.langName]["c104_expand"] axisList = ["X", "Y", "Z"] # validating namming in order to be possible create more than one setup validName = utils.validateName(headDeformerName + "_FFDSet", "FFDSet") numbering = validName.replace(headDeformerName, "")[:-7] if numbering: headDeformerName = headDeformerName + numbering centerSymmetryName = centerSymmetryName + numbering topSymmetryName = topSymmetryName + numbering # get a list of selected items selList = cmds.ls(selection=True) if selList: # lattice deformer latticeDefList = cmds.lattice( name=headDeformerName + "_FFD", divisions=(6, 6, 6), ldivisions=(6, 6, 6), outsideLattice=1, objectCentered=True) #[Set, Lattice, Base] latticePointsList = latticeDefList[1] + ".pt[0:5][2:5][0:5]" # store initial scaleY in order to avoid lattice rotation bug on non frozen transformations bBoxMaxY = cmds.getAttr( latticeDefList[2] + ".boundingBox.boundingBoxMax.boundingBoxMaxY") bBoxMinY = cmds.getAttr( latticeDefList[2] + ".boundingBox.boundingBoxMin.boundingBoxMinY") initialSizeY = bBoxMaxY - bBoxMinY # force rotate zero to lattice in order to avoid selected non froozen transformations for axis in axisList: cmds.setAttr(latticeDefList[1] + ".rotate" + axis, 0) cmds.setAttr(latticeDefList[2] + ".rotate" + axis, 0) cmds.setAttr(latticeDefList[1] + ".scaleY", initialSizeY) cmds.setAttr(latticeDefList[2] + ".scaleY", initialSizeY) # getting size and distances from Lattice Bounding Box bBoxMaxY = cmds.getAttr( latticeDefList[2] + ".boundingBox.boundingBoxMax.boundingBoxMaxY") bBoxMinY = cmds.getAttr( latticeDefList[2] + ".boundingBox.boundingBoxMin.boundingBoxMinY") bBoxSize = bBoxMaxY - bBoxMinY bBoxMidY = bBoxMinY + (bBoxSize * 0.5) # twist deformer twistDefList = cmds.nonLinear(latticePointsList, name=headDeformerName + "_Twist", type="twist") #[Deformer, Handle] cmds.setAttr(twistDefList[0] + ".lowBound", 0) cmds.setAttr(twistDefList[0] + ".highBound", bBoxSize) cmds.setAttr(twistDefList[1] + ".ty", bBoxMinY) # squash deformer squashDefList = cmds.nonLinear(latticePointsList, name=headDeformerName + "_Squash", type="squash") #[Deformer, Handle] cmds.setAttr(squashDefList[0] + ".highBound", 0.5 * bBoxSize) cmds.setAttr(squashDefList[0] + ".startSmoothness", 1) cmds.setAttr(squashDefList[1] + ".ty", bBoxMidY) # side bend deformer sideBendDefList = cmds.nonLinear(latticePointsList, name=headDeformerName + "_Side_Bend", type="bend") #[Deformer, Handle] cmds.setAttr(sideBendDefList[0] + ".lowBound", 0) cmds.setAttr(sideBendDefList[0] + ".highBound", bBoxSize) cmds.setAttr(sideBendDefList[1] + ".ty", bBoxMinY) # front bend deformer frontBendDefList = cmds.nonLinear(latticePointsList, name=headDeformerName + "_Front_Bend", type="bend") #[Deformer, Handle] cmds.setAttr(frontBendDefList[0] + ".lowBound", 0) cmds.setAttr(frontBendDefList[0] + ".highBound", bBoxSize) cmds.setAttr(frontBendDefList[1] + ".ry", -90) cmds.setAttr(frontBendDefList[1] + ".ty", bBoxMinY) # fix deform transforms scale to 1 defHandleList = [ twistDefList[1], squashDefList[1], sideBendDefList[1], frontBendDefList[1] ] for defHandle in defHandleList: for axis in axisList: cmds.setAttr(defHandle + ".scale" + axis, 1) # force correct rename for Maya versions before 2020: if (int(cmds.about(version=True)[:4]) < 2020): if cmds.objExists(twistDefList[0] + "Set"): cmds.rename(twistDefList[0] + "Set", headDeformerName + "_TwistSet") twistDefList[0] = cmds.rename(twistDefList[0], headDeformerName + "_Twist") twistDefList[1] = cmds.rename( twistDefList[1], headDeformerName + "_TwistHandle") if cmds.objExists(squashDefList[0] + "Set"): cmds.rename(squashDefList[0] + "Set", headDeformerName + "_SquashSet") squashDefList[0] = cmds.rename( squashDefList[0], headDeformerName + "_Squash") squashDefList[1] = cmds.rename( squashDefList[1], headDeformerName + "_SquashHandle") if cmds.objExists(sideBendDefList[0] + "Set"): cmds.rename(sideBendDefList[0] + "Set", headDeformerName + "_Side_BendSet") sideBendDefList[0] = cmds.rename( sideBendDefList[0], headDeformerName + "_Side_Bend") sideBendDefList[1] = cmds.rename( sideBendDefList[1], headDeformerName + "_Side_BendHandle") if cmds.objExists(frontBendDefList[0] + "Set"): cmds.rename(frontBendDefList[0] + "Set", headDeformerName + "_Front_BendSet") frontBendDefList[0] = cmds.rename( frontBendDefList[0], headDeformerName + "_Front_Bend") frontBendDefList[1] = cmds.rename( frontBendDefList[1], headDeformerName + "_Front_BendHandle") # arrow control curve arrowCtrl = self.ctrls.cvControl("id_053_HeadDeformer", headDeformerName + "_Ctrl", 0.25 * bBoxSize, d=0) # add control intensite and calibrate attributes for axis in axisList: cmds.addAttr(arrowCtrl, longName=intensityName + axis, attributeType='float', defaultValue=1) cmds.setAttr(arrowCtrl + "." + intensityName + axis, edit=True, keyable=False, channelBox=True) cmds.addAttr(arrowCtrl, longName=expandName, attributeType='float', min=0, defaultValue=1, max=10, keyable=True) cmds.addAttr(arrowCtrl, longName="calibrateX", attributeType='float', defaultValue=100 / (3 * bBoxSize), keyable=False) cmds.addAttr(arrowCtrl, longName="calibrateY", attributeType='float', defaultValue=300 / bBoxSize, keyable=False) cmds.addAttr(arrowCtrl, longName="calibrateZ", attributeType='float', defaultValue=100 / (3 * bBoxSize), keyable=False) cmds.addAttr(arrowCtrl, longName="calibrateReduce", attributeType='float', defaultValue=100, keyable=False) # multiply divide in order to intensify influences calibrateMD = cmds.createNode("multiplyDivide", name=headDeformerName + "_Calibrate_MD") calibrateReduceMD = cmds.createNode("multiplyDivide", name=headDeformerName + "_CalibrateReduce_MD") intensityMD = cmds.createNode("multiplyDivide", name=headDeformerName + "_" + intensityName.capitalize() + "_MD") twistMD = cmds.createNode("multiplyDivide", name=headDeformerName + "_Twist_MD") cmds.setAttr(twistMD + ".input2Y", -1) cmds.setAttr(calibrateReduceMD + ".operation", 2) # connections for axis in axisList: cmds.connectAttr(arrowCtrl + "." + intensityName + axis, calibrateMD + ".input1" + axis, force=True) cmds.connectAttr(arrowCtrl + ".calibrate" + axis, calibrateReduceMD + ".input1" + axis, force=True) cmds.connectAttr(arrowCtrl + ".calibrateReduce", calibrateReduceMD + ".input2" + axis, force=True) cmds.connectAttr(calibrateReduceMD + ".output" + axis, calibrateMD + ".input2" + axis, force=True) cmds.connectAttr(arrowCtrl + ".translate" + axis, intensityMD + ".input1" + axis, force=True) cmds.connectAttr(calibrateMD + ".output" + axis, intensityMD + ".input2" + axis, force=True) cmds.connectAttr(intensityMD + ".outputX", sideBendDefList[0] + ".curvature", force=True) cmds.connectAttr(intensityMD + ".outputY", squashDefList[0] + ".factor", force=True) cmds.connectAttr(intensityMD + ".outputZ", frontBendDefList[0] + ".curvature", force=True) cmds.connectAttr(arrowCtrl + ".ry", twistMD + ".input1Y", force=True) cmds.connectAttr(twistMD + ".outputY", twistDefList[0] + ".endAngle", force=True) # change squash to be more cartoon cmds.setDrivenKeyframe(squashDefList[0] + ".lowBound", currentDriver=intensityMD + ".outputY", driverValue=-0.25 * bBoxSize, value=-bBoxSize, inTangentType="auto", outTangentType="auto") cmds.setDrivenKeyframe(squashDefList[0] + ".lowBound", currentDriver=intensityMD + ".outputY", driverValue=0, value=-0.5 * bBoxSize, inTangentType="auto", outTangentType="auto") cmds.setDrivenKeyframe(squashDefList[0] + ".lowBound", currentDriver=intensityMD + ".outputY", driverValue=0.5 * bBoxSize, value=-0.25 * bBoxSize, inTangentType="auto", outTangentType="flat") cmds.connectAttr(arrowCtrl + "." + expandName, squashDefList[0] + ".expand", force=True) # fix side values for axis in axisList: unitConvNode = cmds.listConnections(intensityMD + ".output" + axis, destination=True)[0] if unitConvNode: if cmds.objectType(unitConvNode) == "unitConversion": cmds.setAttr(unitConvNode + ".conversionFactor", 1) self.ctrls.setLockHide([arrowCtrl], ['rx', 'rz', 'sx', 'sy', 'sz', 'v']) # create symetry setup centerClusterList = cmds.cluster( latticeDefList[1] + ".pt[0:5][2:3][0:5]", relative=True, name=centerSymmetryName + "_Cls") #[Cluster, Handle] topClusterList = cmds.cluster(latticeDefList[1] + ".pt[0:5][2:5][0:5]", relative=True, name=topSymmetryName + "_Cls") clustersZeroList = utils.zeroOut( [centerClusterList[1], topClusterList[1]]) cmds.delete( cmds.parentConstraint(centerClusterList[1], clustersZeroList[1])) clusterGrp = cmds.group( clustersZeroList, name=headDeformerName + "_" + self.langDic[self.langName]["c101_symmetry"] + "_Grp") # symmetry controls centerSymmetryCtrl = self.ctrls.cvControl("id_068_Symmetry", centerSymmetryName + "_Ctrl", bBoxSize, d=0, rot=(-90, 0, 90)) topSymmetryCtrl = self.ctrls.cvControl("id_068_Symmetry", topSymmetryName + "_Ctrl", bBoxSize, d=0, rot=(0, 90, 0)) symmetryCtrlZeroList = utils.zeroOut( [centerSymmetryCtrl, topSymmetryCtrl]) for axis in axisList: cmds.connectAttr(centerSymmetryCtrl + ".translate" + axis, centerClusterList[1] + ".translate" + axis, force=True) cmds.connectAttr(centerSymmetryCtrl + ".rotate" + axis, centerClusterList[1] + ".rotate" + axis, force=True) cmds.connectAttr(centerSymmetryCtrl + ".scale" + axis, centerClusterList[1] + ".scale" + axis, force=True) cmds.connectAttr(topSymmetryCtrl + ".translate" + axis, topClusterList[1] + ".translate" + axis, force=True) cmds.connectAttr(topSymmetryCtrl + ".rotate" + axis, topClusterList[1] + ".rotate" + axis, force=True) cmds.connectAttr(topSymmetryCtrl + ".scale" + axis, topClusterList[1] + ".scale" + axis, force=True) # create groups arrowCtrlGrp = cmds.group(arrowCtrl, name=arrowCtrl + "_Grp") utils.zeroOut([arrowCtrl]) offsetGrp = cmds.group(name=headDeformerName + "_Offset_Grp", empty=True) dataGrp = cmds.group(name=headDeformerName + "_Data_Grp", empty=True) cmds.delete( cmds.parentConstraint(latticeDefList[2], arrowCtrlGrp, maintainOffset=False)) arrowCtrlHeigh = bBoxMaxY + (bBoxSize * 0.5) cmds.setAttr(arrowCtrlGrp + ".ty", arrowCtrlHeigh) cmds.delete( cmds.parentConstraint(latticeDefList[2], offsetGrp, maintainOffset=False)) cmds.delete( cmds.parentConstraint(latticeDefList[2], symmetryCtrlZeroList[0], maintainOffset=False)) cmds.delete( cmds.parentConstraint(latticeDefList[2], symmetryCtrlZeroList[1], maintainOffset=False)) cmds.parent(symmetryCtrlZeroList, arrowCtrlGrp) latticeGrp = cmds.group(name=latticeDefList[1] + "_Grp", empty=True) cmds.parent(latticeDefList[1], latticeDefList[2], latticeGrp) # try to integrate to Head_Head_Ctrl allTransformList = cmds.ls(selection=False, type="transform") headCtrlList = self.ctrls.getControlNodeById("id_023_HeadHead") if headCtrlList: if len(headCtrlList) > 1: mel.eval("warning" + "\"" + self.langDic[self.langName]["i075_moreOne"] + " Head control.\"" + ";") else: self.headCtrl = headCtrlList[0] if self.headCtrl: # setup hierarchy headCtrlPosList = cmds.xform(self.headCtrl, query=True, rotatePivot=True, worldSpace=True) cmds.xform(dataGrp, translation=(headCtrlPosList[0], headCtrlPosList[1], headCtrlPosList[2]), worldSpace=True) cmds.parentConstraint(self.headCtrl, dataGrp, maintainOffset=True, name=dataGrp + "_ParentConstraint") cmds.scaleConstraint(self.headCtrl, dataGrp, maintainOffset=True, name=dataGrp + "_ScaleConstraint") # influence controls toHeadDefCtrlList = [] for item in allTransformList: if cmds.objExists(item + ".controlID"): if cmds.getAttr(item + ".controlID") == "id_024_HeadJaw": toHeadDefCtrlList.append(item) elif cmds.getAttr( item + ".controlID") == "id_027_HeadLipCorner": toHeadDefCtrlList.append(item) headChildrenList = cmds.listRelatives(self.headCtrl, children=True, allDescendents=True, type="transform") if headChildrenList: for item in headChildrenList: if cmds.objExists(item + ".controlID"): if not cmds.getAttr(item + ".controlID" ) == "id_052_FacialFace": if not cmds.getAttr( item + ".controlID" ) == "id_029_SingleIndSkin": if not cmds.getAttr( item + ".controlID" ) == "id_054_SingleMain": toHeadDefCtrlList.append(item) else: singleMainShapeList = cmds.listRelatives( item, children=True, shapes=True) if singleMainShapeList: for mainShape in singleMainShapeList: toHeadDefCtrlList.append( mainShape) if toHeadDefCtrlList: for item in toHeadDefCtrlList: cmds.sets(item, include=headDeformerName + "_FFDSet") cmds.parent(arrowCtrlGrp, self.headCtrl) cmds.parent(squashDefList[1], sideBendDefList[1], frontBendDefList[1], twistDefList[1], offsetGrp) cmds.parent(offsetGrp, clusterGrp, latticeGrp, dataGrp) # try to integrate to Scalable_Grp for item in allTransformList: if cmds.objExists(item + ".masterGrp") and cmds.getAttr( item + ".masterGrp") == 1: scalableGrp = cmds.listConnections(item + ".scalableGrp")[0] cmds.parent(dataGrp, scalableGrp) break # try to change deformers to get better result cmds.scale(1.25, 1.25, 1.25, offsetGrp) # colorize self.ctrls.colorShape( [arrowCtrl, centerSymmetryCtrl, topSymmetryCtrl], "cyan") # finish selection the arrow control cmds.select(arrowCtrl) print self.langDic[self.langName]["i179_addedHeadDef"], else: mel.eval("warning" + "\"" + self.langDic[self.langName]["i034_notSelHeadDef"] + "\"" + ";")
def buildFoot(name='', numJoints=5, side='rt', blendAttr=None, cleanup=1): # main ik group grp = cmds.group(empty=1, name=(name+'_ik_grp')) noTouch_grp = cmds.group(empty=1, name=(name+'_ik_noTouch_grp')) cmds.parent(noTouch_grp, grp) # Create ik nurbsPlane ikPlane = cmds.nurbsPlane(u=7, v=7, name=(name+'_ikPlane'), axis=[0,1,0])[0] cmds.parent(ikPlane, noTouch_grp) # Create ik follicles ikFollicles=[] for i in range(numJoints): f = rivet.build(mesh=ikPlane, paramV=(1.0/(numJoints-1) * i), paramU=0.5, name=(name + '_ik_' + str(i+1))) ikFollicles.append(f) cmds.parent(f, noTouch_grp) # Create IK Control ##ikCtrl = cmds.circle(name=(name + '_ik_bend_ctrl'))[0] ikCtrl = controls.circleBumpCtrl(radius=5.0, name=(name + '_ik_bend_ctrl'), axis='x')[0] cmds.parent(ikCtrl, grp) common.insertGroup(ikCtrl) cmds.addAttr(ikCtrl, ln='falloff', at='double', keyable=1, minValue=0.01) # Create deformers ikBend1 = cmds.nonLinear(ikPlane, type='bend') ikBend1_bend = cmds.rename(ikBend1[0], name+'_ikBend_1') ikBend1_handle = cmds.rename(ikBend1[1], name+'_ikBend_1_handle') handle_grp = common.insertGroup(ikBend1_handle) driven_grp = common.insertGroup(ikBend1_handle, 'driven') cmds.xform(ikBend1_handle, ws=0, rotation=(90, 0, 90)) cmds.parent(handle_grp, noTouch_grp) uc = cmds.createNode('unitConversion', name=(name + '_ikBend_1_falloff_uc')) cmds.connectAttr(ikCtrl+'.falloff', uc+'.input') cmds.setAttr(uc+'.conversionFactor', -1.0) md = cmds.createNode('multiplyDivide', name=(name+'_ikBend_1_curvature_md')) cmds.setAttr(md+'.operation', 2) cmds.connectAttr(ikCtrl+'.rx', md+'.input1X') cmds.connectAttr(ikCtrl+'.falloff', md+'.input2X') cmds.connectAttr(md+'.outputX', ikBend1_bend+'.curvature') cmds.connectAttr(uc+'.output', ikBend1_bend+'.lowBound') cmds.setAttr(ikBend1_bend+'.highBound', 0.0) cmds.connectAttr(ikCtrl+'.tx', driven_grp+'.tx') cmds.connectAttr(ikCtrl+'.tz', driven_grp+'.tz') cmds.connectAttr(ikCtrl+'.ry', driven_grp+'.ry') # Create IK toe Control ##ikToeCtrl = cmds.circle(name=(name + '_ik_toe_ctrl'))[0] ikToeCtrl = controls.circleBumpCtrl(radius=3.0, name=(name + '_ik_toe_ctrl'), axis='x')[0] cmds.parent(ikToeCtrl, ikCtrl) common.insertGroup(ikToeCtrl) # Create deformers ikToeBend1 = cmds.nonLinear(ikPlane, type='bend') ikToeBend1_bend = cmds.rename(ikToeBend1[0], name+'_ikToeBend_1') ikToeBend1_handle = cmds.rename(ikToeBend1[1], name+'_ikToeBend_1_handle') cmds.parent(ikToeBend1_handle, driven_grp) cmds.xform(ikToeBend1_handle, ws=0, rotation=(90, 0, 90)) uc = cmds.createNode('unitConversion', name=(name + '_ikToeBend_1_curvature_uc')) cmds.connectAttr(ikToeCtrl+'.rx', uc+'.input') cmds.setAttr(uc+'.conversionFactor', -57.296) md = cmds.createNode('multiplyDivide', name=(name+'_ikToeBend_1_curvature_md')) cmds.setAttr(md+'.operation', 2) cmds.connectAttr(uc+'.output', md+'.input1X') cmds.connectAttr(ikCtrl+'.falloff', md+'.input2X') cmds.connectAttr(md+'.outputX', ikToeBend1_bend+'.curvature') cmds.connectAttr(ikCtrl+'.falloff', ikToeBend1_bend+'.highBound') cmds.setAttr(ikToeBend1_bend+'.lowBound', 0.0) # main fk group fk_grp = cmds.group(empty=1, name=(name+'_fk_grp')) fk_noTouch_grp = cmds.group(empty=1, name=(name+'_fk_noTouch_grp')) cmds.parent(fk_noTouch_grp, fk_grp) # fk nurbsPlane fkPlane = cmds.nurbsPlane(u=7, v=7, name=(name+'_fkPlane'), axis=[0,1,0])[0] cmds.parent(fkPlane, fk_noTouch_grp) # Create fk follicles fkFollicles=[] for i in range(numJoints): f = rivet.build(mesh=fkPlane, paramV=(1.0/(numJoints-1) * i), paramU=0.5, name=(name + '_fk_' + str(i+1))) fkFollicles.append(f) cmds.parent(f, fk_noTouch_grp) # Create FK Control ##fkCtrl = cmds.circle(name=(name + '_fk_bend_ctrl'))[0] fkCtrl = controls.circleBumpCtrl(radius=4.0, name=(name + '_fk_bend_ctrl'), axis='x')[0] cmds.parent(fkCtrl, fk_grp) common.insertGroup(fkCtrl) cmds.addAttr(fkCtrl, ln='falloff', at='double', keyable=1, minValue=0.01) # Create fk deformers fkBend1 = cmds.nonLinear(fkPlane, type='bend') fkBend1_bend = cmds.rename(fkBend1[0], name+'_fkBend_1') fkBend1_handle = cmds.rename(fkBend1[1], name+'_fkBend_1_handle') handle_grp = common.insertGroup(fkBend1_handle) driven_grp = common.insertGroup(fkBend1_handle, 'driven') cmds.xform(fkBend1_handle, ws=0, rotation=(90, 0, 90)) cmds.parent(handle_grp, fk_noTouch_grp) uc = cmds.createNode('unitConversion', name=(name + '_fkBend_1_curvature_uc')) cmds.connectAttr(fkCtrl+'.rx', uc+'.input') cmds.setAttr(uc+'.conversionFactor', -57.296) md = cmds.createNode('multiplyDivide', name=(name+'_fkBend_1_curvature_md')) cmds.setAttr(md+'.operation', 2) cmds.connectAttr(uc+'.output', md+'.input1X') cmds.connectAttr(fkCtrl+'.falloff', md+'.input2X') cmds.connectAttr(md+'.outputX', fkBend1_bend+'.curvature') cmds.connectAttr(fkCtrl+'.falloff', fkBend1_bend+'.highBound') cmds.setAttr(fkBend1_bend+'.lowBound', 0.0) cmds.connectAttr(fkCtrl+'.tx', driven_grp+'.tx') cmds.connectAttr(fkCtrl+'.tz', driven_grp+'.tz') cmds.connectAttr(fkCtrl+'.ry', driven_grp+'.ry') # Set up blending attribute ikAttr=None fkAttr=None if not blendAttr: cmds.addAttr(grp, longName='state', at='enum', enumName='ik:fk', keyable=True ) stateRev = cmds.createNode('reverse', name=(name+'_state_rev')) cmds.connectAttr(grp+'.state', stateRev+'.inputX') fkAttr=(grp+'.state') ikAttr=(stateRev+'.outputX') else: fkAttr=blendAttr # Check whether a reverse node is connected to blendAttr revCheck = cmds.listConnections(fkAttr, type='reverse') if revCheck: ikAttr = revCheck[0]+'.outputX' else: stateRev = cmds.createNode('reverse', name=(name+'_state_rev')) cmds.connectAttr(fkAttr, stateRev+'.inputX') ikAttr=(stateRev+'.outputX') joints_grp = cmds.group(empty=1, name=(name+'_joints_grp')) cmds.parent(joints_grp, grp) # Build joints for i in range(numJoints): cmds.select(joints_grp) pos = cmds.xform(ikFollicles[i], q=1, t=1, ws=1) j = cmds.joint(name=(name+'_'+str(i+1)+'_jnt'), p=pos) #Constrain between follicles pc = cmds.parentConstraint([ikFollicles[i], fkFollicles[i]], j)[0] weightAliasList = [str(w) for w in cmds.parentConstraint(j, q=1, weightAliasList=1)] cmds.connectAttr(ikAttr, pc+'.'+weightAliasList[0]) cmds.connectAttr(fkAttr, pc+'.'+weightAliasList[1]) if cleanup: common.attrCtrl(lock=True, keyable=False, channelBox=False, nodeList=[ikCtrl, fkCtrl], attrList=['ty', 'rz', 'sx', 'sy', 'sz', 'visibility']) common.attrCtrl(lock=True, keyable=False, channelBox=False, nodeList=[ikToeCtrl], attrList=['tx', 'ty', 'tz', 'ry', 'rz', 'sx', 'sy', 'sz', 'visibility']) #buildFoot()