def transfer_shape(source, target, snap_to_target=True, fix_name=False): """ Reparent a shape node from one parent to another @param source: The source dag which contains the shape @param target: The source dag which will have the new shape the shape @param snap_to_target: Should be we reparent with world space or object space @param fix_name: Should we match the name of the shape to the new target @return: """ source = force_pynode(source) target = force_pynode(target) if snap_to_target: snap(source, target) pm.makeIdentity(source, apply=1) if source.getShape().type() != "locator": try: pm.cluster(source) pm.delete(source, ch=1) except RuntimeError: logger.warning("Cannot cluster {}".format(source)) oldShape = source.getShape() pm.parent(oldShape, target, shape=1, relative=1) if fix_name: fix_shape_name(target) return oldShape
def bdCreateFol(self,surfaceRbn,segments,direction,ends): folicles = [] if not ends: flcRange = [i for i in range(1,segments)] else: flcRange = [i for i in range(segments+1)] for i in flcRange: flcShape = pm.createNode('follicle', name = surfaceRbn.name().replace('srf','FLCShape') + '_0' + str(i) ) flcTransform = flcShape.getParent() flcTransform.rename(surfaceRbn.name().replace('srf','flc') + '_0' + str(i) ) folicles.append(flcTransform) surfaceRbn.getShape().local.connect(flcShape.inputSurface) surfaceRbn.getShape().worldMatrix[0].connect(flcShape.inputWorldMatrix) flcShape.outRotate.connect(flcTransform.rotate) flcShape.outTranslate.connect(flcTransform.translate) if(self.direction == 'v'): flcShape.parameterU.set(0.5) flcShape.parameterV.set((i*1.0)/segments) else: flcShape.parameterV.set(0.5) flcShape.parameterU.set((i*1.0)/segments) flcGrp = pm.group(folicles,n=surfaceRbn.name().replace('srf','flc_grp')) pm.parent(flcGrp,self.rbnGrp) return flcGrp
def makeLoc(obj=None): # Place locator as child to jnt and zero it loc = pm.spaceLocator() pm.parent(loc, obj) loc.setTranslation(0) loc.setRotation([0, 0, 0]) return loc
def ExtraControlForJnt( jnts=None ) : if not jnts: jnts = pm.ls( sl=True ) else: jnts = pm.ls( jnts ) for jnt in jnts: # duplicate joint pm.select( clear=True ) newJnt = pm.joint( p = [0,0,0], name= '%s_extra'%jnt.name() ) pm.delete( pm.pointConstraint( jnt, newJnt ) ) pm.delete( pm.orientConstraint( jnt, newJnt ) ) pm.parent( newJnt, jnt ) newJnt.jointOrient.set( jnt.jointOrient.get() ) # create control curve for joint ctrl = CubeCrv( name = '%s_ctrl'%jnt.name() ) pm.delete( pm.pointConstraint( jnt, ctrl ) ) pm.delete( pm.orientConstraint( jnt, ctrl ) ) zeroAndOfs = ZeroGrp( ctrl ) ctrl.translate >> newJnt.translate ctrl.rotate >> newJnt.rotate ctrl.scale >> newJnt.scale # make controls to move with base joints pm.parentConstraint( jnt, zeroAndOfs[0] ) pm.scaleConstraint( jnt, zeroAndOfs[0] )
def jointsOnCurve(crv=None, num=None, name=None): if not crv: return if not num: return if not name: return if num < 1: return param_increment = 1.0/float(num) param = 0 curveShape = pm.PyNode(crv).getShape() prnt = [] for i in range(num): pm.select(clear=1) # Create joint jnt = pm.joint(n=name+'_'+str(i).zfill(2)) # Attach to curve poci = pm.createNode('pointOnCurveInfo') pm.connectAttr('%s.ws'%curveShape,'%s.inputCurve'%poci,f=1) pm.connectAttr('%s.position'%poci,'%s.translate'%jnt,f=1) pm.setAttr('%s.parameter'%poci,param) pm.setAttr('%s.turnOnPercentage'%poci,1) pm.disconnectAttr('%s.position'%poci,'%s.translate'%jnt) pm.delete(poci) if len(prnt): pm.parent(jnt,prnt[-1]) prnt.append(jnt) param += param_increment
def addZero(*args, **kwargs): oblist = makeList(args) results = [] for item in oblist: if item.type() == 'joint': zero = pm.createNode('transform', n=item+'Zero') zero.rotateOrder.set( item.rotateOrder.get() ) snap(zero, item) pm.parent(item, zero) results.append(zero) elif item.type() == 'transform': zero = pm.duplicate(item, rr=True)[0] children = zero.getChildren() if len(children): pm.delete(children) zero.rename(item+'Zero') for attr in 'trs': for axis in 'xyz': pAttr = zero.attr(attr+axis) pAttr.set(lock=False) pAttr.set(k=True) pm.parent(item, zero) results.append(zero) if len(results) == 0: return None elif len(results) == 1: return(results[0]) else: return(results)
def FTM_createRulerPlane( control, axisPlane, isMainDirX, transformParent, dummyRulerTransform ): obj = pm.polyPlane( axis=axisPlane, ch=True, w=1, h=1, sx=1, sy=1 ) if isMainDirX == True: bDir = 'width' bSubDir = 'subdivisionsWidth' sDir = 'height' sSubDir = 'subdivisionsHeight' else: sDir = 'width' sSubDir = 'subdivisionsWidth' bDir = 'height' bSubDir = 'subdivisionsHeight' pm.connectAttr( control+'.controlSize2', obj[1]+'.'+bDir) pm.connectAttr( control+'.rulerDivisions2', obj[1]+'.'+bSubDir) pm.connectAttr( control+'.rulerSmallSize', obj[1]+'.'+sDir) shapeTransformDriver = dummyRulerTransform if shapeTransformDriver is None: shapeTransformDriver = obj[0] outShp = FTM_createTransformedGeometry(obj[0], 'outMesh', 'inMesh', shapeTransformDriver ) #shps = pm.listRelatives(obj[0],s=True) pm.connectAttr( control+'.rulerDisplay', outShp+'.visibility') pm.setAttr(outShp+'.template', 1) if transformParent is None: pm.parent(obj[0], control) return obj[0] else: pm.parent(outShp,transformParent, add=True, s=True) pm.delete( obj[0] )
def rigBook(containers): center = createJointChain(name='center') left = createJointChain(name='left') right = createJointChain(name='right') ctrl = containers["ctrl"] pm.addAttr(containers["ctrl"], ln="_", at="enum", en="______" ) pm.setAttr(containers["ctrl"]+"._", e=1, keyable=1) for page in range(pages): pageName = 'page'+str(page) skin = createJointChain(pageName+"_") rigPage(skin, center, left, right, ctrl, pageName) paper = createPaper(pageName) pm.select(skin, r=1, hi=1) pm.select(paper, add=1, ) pm.bindSkin(toAll = 1, colorJoints = 1) pm.select(cl=1) pm.parent(paper, containers["paper_grp"]) pm.parent(skin[0], containers["pages_grp"]) pm.select(cl=1) print "rigged: %s" % pageName pm.parent(center[0], containers["pageTargets_grp"]) pm.parent(left[0], containers["pageTargets_grp"]) pm.parent(right[0], containers["pageTargets_grp"])
def create(self): grp = self.createGroup( self.groupName ) snap( self.headJnt, grp, type='parent') neck = pm.group(n='neck_hdl',em=True) head = pm.group(n='head_hdl',em=True) headEnd = pm.group(n='headEnd_hdl',em=True) snap( self.headJnt, head, type='parent') snap( self.headEndJnt, headEnd, type='parent') snap( self.neckJnt, neck, type='parent') pm.parent( headEnd, head ) pm.parent( head, neck, grp ) pm.parent( pm.parentConstraint( head, self.headJnt ), head) pm.parent( pm.parentConstraint( headEnd, self.headEndJnt ), headEnd) pm.parent( pm.parentConstraint( neck, self.neckJnt ), neck) setAttrs( head, 'sx','sy','sz','v', lock=True, keyable=False, channelBox=False ) setAttrs( headEnd, 'rx','ry','rz','sx','sy','sz','v', lock=True, keyable=False, channelBox=False ) setAttrs( neck, 'rx','ry','rz','sx','sy','sz','v', lock=True, keyable=False, channelBox=False ) head. displayHandle.set(True) headEnd.displayHandle.set(True) neck. displayHandle.set(True) setColor( neck, head, headEnd, c='red' ) self.neck = neck self.head = head self.headEnd = headEnd
def vis_orbits(self): global vis_orbGrp vis_orbGrp = pm.group(n='olp_visOrbits', em=True) intervValue = self.interv_int.value() distValue = self.distance_float.value() orbitValue = self.orbit_int.value() global all_orbitObjs all_orbitObjs = [] for orbit in range(orbitValue): orbitRot = orbit * 360/float(orbitValue*2) orbit_visObject = pm.circle(n='olp_orbCircle{0}'.format(orbit+1), r=distValue, s=intervValue*2, nr=[1, 0, 0], ch=True)[0] pm.parent(orbit_visObject, vis_orbGrp) orbit_visObject.overrideEnabled.set(1) orbit_visObject.overrideColorRGB.set(0, 1, 1) orbit_visObject.overrideRGBColors.set(1) pm.xform(orbit_visObject, ro=[0, 0, orbitRot]) all_orbitObjs.append(orbit_visObject) pm.xform(vis_orbGrp, a=True, t=sel_center) pm.parent(vis_orbGrp, vis_mainGrp) pm.select(sel_objects, r=True) return vis_orbGrp
def parentToControlsGrp( characterNode ): pymelLogger.debug('Starting: parentToControlsGrp()...') pm.parent( characterNode, Names.modules_grp ) pymelLogger.debug('End: parentToControlsGrp()...')
def create(self): pointA = self.startObj pointB = self.endObj position = (0,0,0) # 커브 생성 crv = pm.curve( d=1, p=[ position, position ], k=[0,1] ) self.curve = crv.getShape() # obj에 커브 쉐입을 종속 시킴 : 커브를 선택해도 오브젝트를 선택한 효과를 줌. pm.parent( self.curve, pointA, r=True, s=True) pm.delete( crv ) # target에 locator를 종속 시킴 self.locator = pm.pointCurveConstraint( self.curve+'.ep[1]', ch=True)[0] self.locator = pm.PyNode(self.locator) pm.pointConstraint( pointB, self.locator ) # 로케이서 속성 조정 self.locator.getShape().localPosition.set(0,0,0) #이 로케이터는 보이지 않음 self.locator.getShape().v.set(False) #이 로케이터는 보이지 않음 self.locator.v.set(False) #이 로케이터는 보이지 않음 self.locator.setParent(pointA) self.locator.rename( pointB+'_CONNLOC' ) # 커브쉐입에 어트리뷰트 추가 self.curve.addAttr( 'curveConnectedTo', at='message' ) self.curve.addAttr( 'curveConnectedLOC', at='message' ) # 어트리뷰트 연결 pointB.message >> self.curve.curveConnectedTo self.locator.message >> self.curve.curveConnectedLOC
def parent_joints_to_root(self): ''' # this will parent all the joints to the root_joint ''' for bound_geo in self.bound_geo_instances: joint = bound_geo.get_joint() pm.parent('%s' % (joint), self.world)
def createIkDynamicJoints(self): pm.select(cl = True) #Iterate jointPositionList and append to ikDynamicJointsList joint at each position self.ikDynamicJointsList = [] for index in range(0, len(self.jointPositionList)): #create Joint #decide jointNames jointName = self.prefix + '_ik_dynamic_j_' + str(index + 1) if( index == 0 ): jointName = self.prefix + '_ik_dynamic_j_' + 'base' if( index + 1 == len(self.jointPositionList) ): jointName = self.prefix + '_ik_dynamic_j_' + 'tip' joint = pm.joint(a = True, p= self.jointPositionList[index] , co = True, n = jointName) self.ikDynamicJointsList.append(joint) pm.select(cl = True) #Create ikDynamicJointsGrp and parent first ik dynamic joint self.ikDynamicJointsGrp = pm.group(n = self.prefix + '_ik_dynamic_joints_grp') pm.select(cl = True) pm.parent(self.ikDynamicJointsList[0] , self.ikDynamicJointsGrp) pm.select(cl = True)
def __armFK__(self, shoulder): self.armFk = self.__armPlaceJnt__(parent=self.gp['arm'], prefix='fk') # create controlor for i in range(len(self.armFk)): # put a better rotate order self.armFk[i].rotateOrder.set(3) # add shape to joint tmp = arShapeBiblio.cube(name=self.armFk[i], color=self.colorOne) pmc.parent(tmp.getShape(), self.armFk[i], shape=True, relative=True) pmc.delete(tmp) # scale shape if i < (len(self.armFk)-1): arShape.scaleShape(self.armFk[i].getShape(), self.armFk[i], self.armFk[i+1]) # clean channel box self.armFk[i].rotateOrder.setKeyable(True) clean.__lockHideTransform__(self.armFk[i], channel=['t', 'v', 'radi']) # add attribut for the first fk bone attribut.addAttrSeparator(self.armFk[0]) # ADD CONSTRAINT ORIENT # pickwalk chain = [shoulder] chain.extend(self.armFk[0:-1]) arPickwalk.setPickWalk(chain, type='UD') return {self.mainSets:self.armFk}
def bdAddExtraGrp(nameMaskCon,grpType,empty): controllers = pm.ls(nameMaskCon,type = 'transform') conPyNodes = [] for con in controllers: conPyNodes.append(con) for node in conPyNodes: if empty: pm.select(cl=True) conGrp = pm.group(name = node.name() + '_' + grpType) pos = node.getTranslation(space='world') rot = node.getRotation(space='world') conGrp.setTranslation(pos) conGrp.setRotation(rot) parent = node.getParent() pm.parent(conGrp,parent) else: conGrp = pm.duplicate(node,name = node.name().replace('CON',grpType)) ''' for axis in ['X','Y','Z']: conGrp[0].attr('translate' + axis).setKeyable(True) conGrp[0].attr('translate' + axis).setLocked(False) ''' conGrpRelatives = pm.listRelatives(conGrp,ad = True) #print sdkConRelatives pm.delete(conGrpRelatives) pm.parent(node,conGrp)
def createIkAnimatedJoints(self): pm.select(cl = True) #Iterate jointPositionList and append to ikAnimatedJointsList joint at each position self.ikAnimatedJointsList = [] for index in range(0, len(self.jointPositionList)): #create Joint #decide jointNames jointName = self.prefix + '_ik_animated_j_' + str(index + 1) if( index == 0 ): jointName = self.prefix + '_ik_animated_j_' + 'base' if( index + 1 == len(self.jointPositionList) ): jointName = self.prefix + '_ik_animated_j_' + 'tip' joint = pm.joint(a = True, p= self.jointPositionList[index] , co = True, n = jointName) #setJointPreferredAngle for correct ikHandle bending pm.setAttr(joint.preferredAngleX, -1.0) self.ikAnimatedJointsList.append(joint) pm.select(cl = True) #Create ikAnimatedJointsGrp and parent first ik animated joint self.ikAnimatedJointsGrp = pm.group(n = self.prefix + '_ik_animated_joints_grp') pm.select(cl = True) pm.parent(self.ikAnimatedJointsList[0] , self.ikAnimatedJointsGrp) pm.select(cl = True)
def __generateMesh( self, mesh, height, radius, iteration ): instanceGroup = pm.group( empty = True, name = "meshInstanceGroup" ) x = 0 y = 0 z = 0 # Top meshInstance1 = mesh meshInstance1[ 0 ].setTranslation( [ x, height, z ] ) # Right meshInstance2 = pm.instance( mesh[ 0 ] ) meshInstance2[ 0 ].setTranslation( [ radius, y, z ] ) # Back meshInstance3 = pm.instance( mesh[ 0 ] ) meshInstance3[ 0 ].setTranslation( [ x, y, -radius ] ) # Left meshInstance4 = pm.instance( mesh[ 0 ] ) meshInstance4[ 0 ].setTranslation( [ -radius, y, z ] ) # Front meshInstance5 = pm.instance( mesh[ 0 ] ) meshInstance5[ 0 ].setTranslation( [ x, y, radius ] ) # Bottom meshInstance6 = pm.instance( mesh[ 0 ] ) meshInstance6[ 0 ].setTranslation( [ x, -height, z ] ) pm.parent( meshInstance1[ 0 ], meshInstance2[ 0 ], meshInstance3[ 0 ], meshInstance4[ 0 ], meshInstance5[ 0 ], meshInstance6[ 0 ], instanceGroup, add = True ) return combineClean( instanceGroup, "Sierpinski_Iteration_%i" % iteration )
def export_hierarchy_obj(self): """Export the individual meshes in the hierarchy""" file_info = {} # Reverse the geo list so that the deepest geo is deleted first in case there is a geo inside geo geo_list = self.geo_list geo_list.reverse() for self.current_target in geo_list: pm.delete(self.current_target, ch=1) parent = pm.listRelatives(self.current_target, parent=True) pm.parent(self.current_target, w=True) pm.select(self.current_target) path = libFile.linux_path(libFile.join(self.export_dir, self.current_target + ".obj")) # Load the obj plugin cmds.file(path, pr=1, typ="OBJexport", force=1, options="groups=0;ptgroups=0;materials=0;smoothing=0;normals=0", es=1) file_info[self.current_target] = path logger.info("Exporting\n%s" % file_info[self.current_target]) if not self.new_scene and self.cleansing_mode: pm.delete(self.current_target) pm.refresh() else: pm.parent(self.current_target, parent) self.update_progress() # Write the geo file_info self.geo_file_info = file_info
def createIKSpline( jntList ): pymelLogger.debug('Starting: createIKSpline()...') # Make IK Spline ikHandleTorso = pm.ikHandle( startJoint=jntList[0], endEffector=jntList[-1], solver = 'ikSplineSolver', numSpans = 4, name = jntList[-1]+'_'+Names.suffixes['ikhandle']) # we should probably rename the object created to know names ...... # CAREFULL // inherits Transform OFF, to avoid double transformation when grouped later on pm.setAttr(ikHandleTorso[2] + '.inheritsTransform', 0) # Duplicate last and first joint to use as Drivers of the spine Ik curve print jntList drvStart = pm.duplicate(jntList[0], parentOnly=True, name = Names.prefixes['driver']+'_'+ jntList[0] +'_'+Names.suffixes['start']) drvEnd = pm.duplicate(jntList[-1], parentOnly=True, name = Names.prefixes['driver']+'_'+ jntList[-1] +'_'+Names.suffixes['end']) pm.parent(drvEnd, w=1) # Make radius bigger pm.joint(drvStart, edit = True, radius = 1) pm.joint(drvEnd, edit = True, radius = 1) # Skin hip/shldr jnt's to back curve pm.skinCluster(drvStart,drvEnd,ikHandleTorso[2],dr=4) # return nedded elements rList = [ikHandleTorso, drvStart, drvEnd ] pymelLogger.debug('End: createIKSpline()...') return rList
def buildGuides(self): """ This function setups our guide system WILL PROBABLY BE ANOTHER CLASS WHEN WE EXPAND AS IT'S GOING TO BE COMPLEX """ self.guides = [] for i,p in enumerate(self.posArray): name = nameUtils.getUniqueName(self.baseNames[i],self.side,"GUIDE") loc = pm.spaceLocator(n=name) loc.t.set(p) loc.r.set(self.rotArray[i]) self.guides.append(loc) tempGuides = list(self.guides) tempGuides.reverse() for i in range(len(tempGuides)): if i != (len(tempGuides)-1): pm.parent(tempGuides[i],tempGuides[i+1]) name = nameUtils.getUniqueName(self.baseName+"_guides",self.side,"grp") self.guidesGrp = pm.createNode("transform",n=name) self.guides[0].setParent(self.guidesGrp)
def importMixamoFbx(self) : print 'importMixamoFbx' pm.newFile(f=1) if self.fbxFile: if os.path.isfile(self.fbxFile): #import the FBX file pm.mel.eval( 'FBXImport -f "' + (self.fbxFile) + '"') #check for a default mesh in T-Pose. If found, replace geometry self.replaceGeometry() #clean its namespace removeNamespace() hips = pm.ls("Hips",type='joint') #add root joint for scale rootJnt = pm.joint(n='Root') pm.parent(hips[0],rootJnt) #clean up textures self.cleanUpTextures() pm.currentUnit(t='ntsc') return 1 else: pm.error('Fbx file %s doesn\'t exist'%self.fbxFile) return 0 else: pm.error('No file was given') return 0
def __transformToBone__(obj): name = obj.name() # create joint jnt = pmc.createNode('joint', name=name+'_') # set parent if obj.getParent(): jnt.setParent(obj.getParent()) # set transformation jnt.setTranslation(obj.getTranslation(space='object'), space='object') jnt.setRotationOrder(obj.getRotationOrder(), reorder=True) jnt.jointOrientX.set(obj.getRotation(space='object')[0]) jnt.jointOrientY.set(obj.getRotation(space='object')[1]) jnt.jointOrientZ.set(obj.getRotation(space='object')[2]) jnt.setScale(obj.getScale()) jnt.setShear(obj.getShear()) # get children children = obj.getChildren() for child in children: child = various.checkObj(child, type=['transform', 'joint'], echo=False) if child: child.setParent(jnt) # parent shape if obj.getShape(): pmc.parent(obj.getShape(), jnt, shape=True, relative=True) # deleting and renaming properly pmc.delete(obj) jnt.rename(name) return jnt
def buildIK(self, *args): """ Build the IK """ #Setup variables if self.normal == 1: self.normal = (1, 0, 0) if self.normal == 2: self.normal = (0, 1, 0) if self.normal == 3: self.normal = (0, 0, 1) #Create IK control self.ikControl = pm.circle(nr=self.normal, r=self.radius, n='%s_ikCnt'%self.prefix) pm.select(self.ikControl[0], r=True) pm.mel.eval("DeleteHistory;") pm.delete( pm.parentConstraint(self.ikChain[2], self.ikControl[0], mo=0) ) self.zero(self.ikControl[0]) #Create RP IK self.arm_ikHandle = pm.ikHandle(sj=self.ikChain[0], ee=self.ikChain[2], solver='ikRPsolver', name=(self.prefix + '_armIkHandle')) pm.setAttr(self.arm_ikHandle[0] + '.visibility', 0) #Parent IK Handle to the ikWrist_cnt pm.parent(self.arm_ikHandle[0], self.ikControl[0]) # Creates: self.pv_cnt self.createPoleVector()
def __generateMesh( self, mesh, positions, radius, iteration ): instanceGroup = pm.group( empty = True, name = "meshInstanceGroup" ) positionsLength = len( positions ) instances = [ None ] * positionsLength for i in range(0, positionsLength): position = scaleVector( positions[ i ], radius ) if i == 0: meshInstance = mesh meshInstance[ 0 ].setTranslation( position ) else: meshInstance = pm.instance( mesh[ 0 ] ) meshInstance[ 0 ].setTranslation(position) instances[ i ] = meshInstance[ 0 ] pm.parent( instances, instanceGroup, add = True ) return combineClean( instanceGroup, "Sierpinski_Iteration_%i" % iteration )
def AlignBindNode(self, **kws): ''' Overwrite the default behaviour: Align the newly made BindNode as required for this bind ''' parentNode = self.SourceNode.listRelatives(p=True)[0] if parentNode: #Parent the BindNode to the Source Driver Node pm.parent(self.BindNode['Root'], self.SourceNode.listRelatives(p=True)[0]) else: pm.parent(self.BindNode['Root'], self.SourceNode) self.BindNode['Main'].rotateOrder.set(self.SourceNode.rotateOrder.get()) self.BindNode['Root'].rotateOrder.set(self.DestinationNode.rotateOrder.get()) #Positional Alignment if self.Settings.AlignToControlTrans: pm.delete(pm.pointConstraint(self.SourceNode, self.BindNode['Root'])) pm.makeIdentity(self.BindNode['Root'], apply=True, t=1, r=0, s=0) pm.delete(pm.pointConstraint(self.DestinationNode, self.BindNode['Root'])) if self.Settings.AlignToSourceTrans: pm.delete(pm.pointConstraint(self.SourceNode, self.BindNode['Root'])) pm.makeIdentity(self.BindNode['Root'], apply=True, t=1, r=0, s=0) #Rotation Alignment if parentNode: pm.orientConstraint(self.SourceNode, self.BindNode['Root']) if self.Settings.AlignToControlRots: pm.delete(pm.orientConstraint(self.DestinationNode, self.BindNode['Main'])) if self.Settings.AlignToSourceRots: pm.delete(pm.orientConstraint(self.SourceNode, self.BindNode['Main']))
def _parentSurfaceFLCL(self, constrained_obj, geo, deleteCPOMS=1): """ Parents object to follicle at closest point on surface. Select child transform, then select mesh to hold parent follicle. """ cpos = pmc.createNode('closestPointOnSurface', n='cpos_flcl_' + geo) mc.connectAttr(pmc.listRelatives(geo, shapes=True, children=True)[0] + '.local', cpos + '.inputSurface') obj_mtx = pmc.xform(constrained_obj, q=True, m=True) pmc.setAttr(cpos + '.inPosition', [obj_mtx[12], obj_mtx[13], obj_mtx[14]]) flclShape = pmc.createNode('follicle', n='flclShape' + geo) flcl = pmc.listRelatives(flclShape, type='transform', parent=True) pmc.rename(flcl, 'flcl_' + geo + '_1') mc.connectAttr(flclShape + '.outRotate', flcl[0] + '.rotate') mc.connectAttr(flclShape + '.outTranslate', flcl[0] + '.translate') mc.connectAttr(geo + '.worldMatrix', flclShape + '.inputWorldMatrix') mc.connectAttr(geo + '.local', flclShape + '.inputSurface') mc.setAttr(flclShape + '.simulationMethod', 0) u = mc.getAttr(cpos + '.result.parameterU') v = mc.getAttr(cpos + '.result.parameterV') pmc.setAttr(flclShape + '.parameterU', u) pmc.setAttr(flclShape + '.parameterV', v) pmc.parent(constrained_obj, flcl) if deleteCPOMS == 1: pmc.delete(cpos) return flcl
def create(self): self.handle = pm.group(em=True) self.result = pm.group(em=True) self.aim = pm.group(em=True) self.up = pm.group(em=True) pm.parent(self.result, self.aim, self.up, self.handle ) # 초기위치 조정 mult = 20 self.aim.t.set(self.aimVec * mult) self.up.t.set(self.upVec * mult) self.aimConstraint = pm.aimConstraint(self.aim, self.result, aim=self.aimVec, u=self.upVec, wut='object', wuo=self.up) # 시각화 self.handle.displayHandle.set(True) #self.result.displayLocalAxis.set(True) # 어트리뷰트 잠금 setAttrs( self.result, 'tx','ty','tz','sx','sy','sz','v' ) setAttrs( self.aim, 'rx','ry','rz','sx','sy','sz','v' ) setAttrs( self.up, 'rx','ry','rz','sx','sy','sz','v' ) # 이름변경 self.setPrefix( self.prefix )
def rtb_remove(highresListDropdown, *args, **kwargs): ''' remove item from the list and delete live-mesh and groups ''' global defaultString high = highresListDropdown.getValue() if not high == defaultString: high = pm.PyNode(high.split("'")[0]) #get rid of unicode crap high.rename(high.rstrip('_high')) pm.parent(high, world=True) high.setScale([1,1,1]) pm.disconnectAttr('persp.translate', high.scalePivot) if pm.displaySurface(high, query=True, xRay=True)[0] == True: pm.displaySurface(high, xRay=False) if not high.visibility.get(): high.visibility.set(True) highShape = high.getShape() highShape.overrideDisplayType.set(0) #sets to normal mode highShape.overrideEnabled.set(0) #disable display overrides pm.delete(str(high)+'_RETOPO') rtb_highres_list_populate(highresListDropdown)
def createBoundJointChain(self): pm.select(cl = True) #Iterate highResCurveCoordList and append to boundJointsList joint at each position self.boundJointsList = [] for index in range(0, len(self.highResCurveCoordList)): #create Joint #decide jointNames jointName = self.prefix + '_bound_j_' + str(index + 1) if( index == 0 ): jointName = self.prefix + '_bound_j_' + 'base' if( index + 1 == len(self.highResCurveCoordList) ): jointName = self.prefix + '_bound_j_' + 'tip' joint = pm.joint(a = True, p= self.highResCurveCoordList[index] , co = True, n = jointName) self.boundJointsList.append(joint) pm.select(cl = True) #Orient boundJoints pm.joint(self.boundJointsList[0], e = True, sao = 'yup', oj='xyz', zso = True, ch = True) pm.select(cl = True) #Create boundJointsGrp and parent first bound joint self.boundJointsGrp = pm.group(n = self.prefix + '_bound_joints_grp') pm.select(cl = True) pm.parent(self.boundJointsList[0] , self.boundJointsGrp) pm.select(cl = True)
def create_ik(self): start_shape = rig_lib.box_curve("{0}_start_ik_CTRL_shape".format( self.model.module_name)) start_ctrl = rig_lib.create_jnttype_ctrl( name="{0}_start_ik_CTRL".format(self.model.module_name), shape=start_shape, drawstyle=2, rotateorder=3) end_shape = rig_lib.box_curve("{0}_end_ik_CTRL_shape".format( self.model.module_name)) end_ctrl = rig_lib.create_jnttype_ctrl(name="{0}_end_ik_CTRL".format( self.model.module_name), shape=end_shape, drawstyle=2, rotateorder=1) start_ofs = pmc.group(start_ctrl, n="{0}_start_ik_ctrl_OFS".format( self.model.module_name)) start_ofs.setAttr("rotateOrder", 3) end_ofs = pmc.group(end_ctrl, n="{0}_end_ik_ctrl_OFS".format( self.model.module_name)) end_ofs.setAttr("rotateOrder", 1) start_ofs.setAttr( "translate", pmc.xform(self.created_fk_ctrls[0], q=1, ws=1, translation=1)) start_ofs.setAttr( "rotate", pmc.xform(self.created_fk_ctrls[0], q=1, ws=1, rotation=1)) end_ofs.setAttr( "translate", pmc.xform(self.created_fk_ctrls[-1], q=1, ws=1, translation=1)) end_ofs.setAttr( "rotate", pmc.xform(self.created_fk_ctrls[-1], q=1, ws=1, rotation=1)) pmc.parent(start_ofs, self.ctrl_input_grp, r=0) pmc.parent(end_ofs, self.created_fk_ctrls[-2], r=0) pmc.parent(self.created_fk_ctrls[-1], end_ctrl, r=0) pmc.parent(self.created_locs[0], start_ctrl, r=0) self.created_fk_ctrls[-1].setAttr("visibility", 0) self.created_ik_ctrls = [start_ctrl, end_ctrl] if not self.model.how_many_ctrls == 2: center_ctrl = (self.model.how_many_ctrls / 2.0) - 0.5 for i, loc in enumerate(self.created_locs): if i == center_ctrl: const = pmc.parentConstraint(start_ctrl, end_ctrl, loc, maintainOffset=1, skipRotate=["x", "y", "z"]) const.setAttr("{0}W0".format(start_ctrl), 1) const.setAttr("{0}W1".format(end_ctrl), 1) elif i < center_ctrl: const = pmc.parentConstraint(start_ctrl, end_ctrl, loc, maintainOffset=1, skipRotate=["x", "y", "z"]) const.setAttr("{0}W0".format(start_ctrl), 1) const.setAttr("{0}W1".format(end_ctrl), ((1 / (self.model.how_many_ctrls / 2.0)) * (i / 2.0))) elif i > center_ctrl: const = pmc.parentConstraint(start_ctrl, end_ctrl, loc, maintainOffset=1, skipRotate=["x", "y", "z"]) const.setAttr("{0}W0".format(start_ctrl), ((1 / (self.model.how_many_ctrls / 2.0)) * (((len(self.created_locs) - 1) - i) / 2.0))) const.setAttr("{0}W1".format(end_ctrl), 1) pmc.parent(self.created_pelvis_ctrl, start_ctrl) pmc.parentConstraint(end_ctrl, self.created_spine_jnts[-1], maintainOffset=1, skipTranslate=["x", "y", "z"])
def create_fk(self): ik_spline_cv_list = [] ik_spline_controlpoints_list = [] for i, cv in enumerate(self.guides[1].cv): ik_spline_cv_list.append(cv) for i, cp in enumerate(self.ik_spline.controlPoints): ik_spline_controlpoints_list.append(cp) for i, cv in enumerate(ik_spline_cv_list): cv_loc = self.create_locators(i, cv, ik_spline_controlpoints_list) self.create_ctrls(i, cv_loc) self.created_locs.append(cv_loc) # for i, cv in enumerate(self.ik_spline.cv): # ik_spline_cv_list.append(cv) # # for i, cp in enumerate(self.ik_spline.controlPoints): # ik_spline_controlpoints_list.append(cp) # # if not self.model.ik_creation_switch: # for i, cv in enumerate(ik_spline_cv_list): # cv_loc = self.create_locators(i, cv, ik_spline_controlpoints_list) # self.create_ctrls(i, cv_loc) # self.created_locs.append(cv_loc) # else: # ik_spline_none_tangent_cv_list = [cv for cv in ik_spline_cv_list if cv != ik_spline_cv_list[1] and cv != ik_spline_cv_list[-2]] # # ik_spline_none_tangent_controlpoints_list = [cp for cp in ik_spline_controlpoints_list if cp != ik_spline_controlpoints_list[1] and cp != ik_spline_controlpoints_list[-2]] # # for i, cv in enumerate(ik_spline_none_tangent_cv_list): # cv_loc = self.create_locators(i, cv, ik_spline_none_tangent_controlpoints_list) # self.create_ctrls(i, cv_loc) # self.created_locs.append(cv_loc) # # start_tangent_loc = self.create_locators(i=1, cv=ik_spline_cv_list[1], # ik_spline_controlpoints=ik_spline_controlpoints_list) # end_tangent_loc = self.create_locators(i=-2, cv=ik_spline_cv_list[-2], # ik_spline_controlpoints=ik_spline_controlpoints_list) # start_tangent_loc.rename("{0}_start_tangent_pos".format(self.model.module_name)) # end_tangent_loc.rename("{0}_end_tangent_pos".format(self.model.module_name)) # self.tangent_locs = [start_tangent_loc, end_tangent_loc] self.ik_spline.setAttr("translate", (0, 0, 0)) self.ik_spline.setAttr("rotate", (0, 0, 0)) self.ik_spline.setAttr("scale", (1, 1, 1)) # pmc.parentConstraint(self.created_fk_ctrls[-1], self.created_spine_jnts[-1], maintainOffset=1, skipTranslate=("x", "y", "z")) pmc.select(cl=1) pelvis_ctrl_shape = pmc.circle(c=(0, 0, 0), nr=(0, 1, 0), sw=360, r=2.5, d=3, s=8, n="{0}_pelvis_CTRL_shape".format( self.model.module_name), ch=0)[0] self.created_pelvis_ctrl = rig_lib.create_jnttype_ctrl( name="{0}_pelvis_CTRL".format(self.model.module_name), shape=pelvis_ctrl_shape, drawstyle=2, rotateorder=1) self.created_pelvis_ctrl.setAttr( "translate", pmc.xform(self.created_pelvis_jnt, q=1, ws=1, translation=1)) pmc.parent(self.created_pelvis_ctrl, self.ctrl_input_grp) # pmc.pointConstraint(self.created_pelvis_ctrl, self.created_pelvis_jnt, maintainOffset=1) # self.created_pelvis_ctrl.rotate >> self.created_pelvis_jnt.rotate pmc.parentConstraint(self.created_pelvis_ctrl, self.created_pelvis_jnt, maintainOffset=1) self.created_pelvis_ctrl.scale >> self.created_pelvis_jnt.scale
def create_vfk(self, name = "", numJoints=20.0, numControls=3.0, controlRadius = 4.0, jointRadius=0.25, jointPrefix = 'joint_', jointGroupPrefix ='vfk_grp_', controlPrefix = 'CTRL_vfk_', controlGroupPrefix = 'OFF_CTRL_vfk_', boneTranslateAxis = '.tx', boneUpAxis = [0,0,1]): ''' if self.close_on_create_chk.checkState() == qc.Qt.Checked: self.close ''' pmc.undoInfo(openChunk=True) ### Get top and end joints, check for parents/children sels = pmc.ls(sl=1) topJoint = sels[0] endJoint = sels[1] try: print topJoint, ' and ', endJoint, ' selected.' ### pmc.listRelatives(topJoint, children=True, type='joint') except IndexError: print 'Error: Select a joint and an immediate child joint.' endChild = pmc.listRelatives(endJoint, c=True) if endChild: linkJointEnd = pmc.duplicate(endJoint, parentOnly=True, n=endJoint + '_LINK') pmc.setAttr(linkJointEnd[0] + '.radius', jointRadius * 2) pmc.parent(endChild, linkJointEnd) pmc.parent(linkJointEnd, w=True) topParent = pmc.listRelatives(topJoint, p=True) if topParent: linkJointTop = pmc.duplicate(topJoint, parentOnly=True, n=topJoint + '_LINK') pmc.setAttr(linkJointTop[0] + '.radius', jointRadius * 2) pmc.parent(linkJointTop, topParent) pmc.parent(topJoint, linkJointTop) ### Check basic user-defined values if self.name_le.text() != "": name = self.name_le.text() else: name = str(topJoint) + '_' if self.joints_le.text() != "": numJoints = float(self.joints_le.text()) if self.controls_le.text() != "": numControls = float(self.controls_le.text()) ### Check advanced user-defined values if self.control_radius_le.text() != "": controlRadius = float(self.control_radius_le.text()) if self.joint_radius_le.text() != "": jointRadius = float(self.joint_radius_le.text()) if self.joint_prefix_le.text() != "": jointPrefix = self.joint_prefix_le.text() if self.joint_grp_prefix_le.text() != "": jointGroupPrefix = self.joint_grp_prefix_le.text() if self.control_prefix_le.text() != "": controlPrefix = self.control_prefix_le.text() if self.control_grp_prefix_le.text() != "": controlGroupPrefix = self.control_grp_prefix_le.text() if self.bone_trans_axis_radX.isChecked() == True and self.bone_up_axis_radX.isChecked() == True: print 'Warning: bone main axis and bone up axis cannot be same.' return if self.bone_trans_axis_radY.isChecked() == True and self.bone_up_axis_radY.isChecked() == True: print 'Warning: bone main axis and bone up axis cannot be same.' return if self.bone_trans_axis_radZ.isChecked() == True and self.bone_up_axis_radZ.isChecked() == True: print 'Warning: bone main axis and bone up axis cannot be same.' return if self.bone_trans_axis_radX.isChecked() == True: boneTranslateAxis = '.tx' if self.bone_trans_axis_radY.isChecked() == True: boneTranslateAxis = '.ty' if self.bone_trans_axis_radZ.isChecked() == True: boneTranslateAxis = '.tz' if self.bone_up_axis_radX.isChecked() == True: boneUpAxis = [1,0,0] if self.bone_up_axis_radY.isChecked() == True: boneUpAxis = [0,1,0] if self.bone_up_axis_radZ.isChecked() == True: boneUpAxis = [0,0,1] #### ACTUAL FUNCTION PART nurbsWidth = pmc.getAttr(endJoint + boneTranslateAxis) self._jointRes(topJoint, endJoint, boneTranslateAxis= boneTranslateAxis, add= numJoints-2) surface = pmc.nurbsPlane(pivot=[0,0,0], axis= boneUpAxis, width=nurbsWidth, lengthRatio=0.1, u=(numJoints-1), ch=0, n= name + 'vfk_surface') ## Uncomment to use as polyPlane instead of nurbsSurface ## surface = pmc.polyPlane(w=20, h=1, sx=20, sy=1, ax=[0,1,0], cuv=2, ch=0, n= name + 'vfk_surface') if boneTranslateAxis == '.ty': if boneUpAxis == [1,0,0]: pmc.setAttr(surface[0] + '.rx', -90) if boneUpAxis == [0,0,1]: pmc.setAttr(surface[0] + '.rz', -90) pmc.makeIdentity(surface[0], apply=True, t=0, r=1, s=0) if boneTranslateAxis == '.tz': if boneUpAxis == [0,1,0]: pmc.setAttr(surface[0] + '.ry', -90) pmc.makeIdentity(surface[0], apply=True, t=0, r=1, s=0) surface_off = pmc.group(surface, n= name + 'OFF_surface') pmc.parent(surface_off, topJoint) if boneTranslateAxis == '.tx': pmc.xform(surface_off, translation = [nurbsWidth/2, 0, 0], rotation=[0,0,0]) if boneTranslateAxis == '.ty': pmc.xform(surface_off, translation = [0, nurbsWidth/2, 0], rotation=[0,0,0]) if boneTranslateAxis == '.tz': pmc.xform(surface_off, translation = [0, 0, nurbsWidth/2], rotation=[0,0,0]) pmc.parent(surface_off, w=True) surface_mtx= pmc.xform(surface, q=True, ws=True, m=True) joints = pmc.listRelatives(topJoint, children=1, allDescendents=1) joints.append(topJoint) joints.reverse() for j in xrange(len(joints)): pmc.select(joints[j]) pmc.rename(joints[j], jointPrefix + str(j+1)) pmc.setAttr(joints[j] + '.radius', jointRadius) pmc.addAttr(joints[j], ln='position', min=0, max=1, dv=0, keyable=True) pmc.setAttr(joints[j] + '.position', j/(numJoints-1)) pmc.select(cl=1) jmtx = pmc.xform(joints[j], q=True, m=True, ws=True) if j == 0: off_vfk = pmc.group(em=True, n= name + 'OFF_vfk') pmc.xform(off_vfk, ws=True, m=jmtx) root = pmc.listRelatives(joints[0], parent=True) for c in xrange(int(numControls)): jparent = pmc.listRelatives(joints[j], parent=True) vfk_grp = pmc.group(em=True, n= name + jointGroupPrefix + 'j' + str(j+1) + '_c' + str(c+1)) pmc.xform(vfk_grp, ws=True, m=jmtx) pmc.parent(joints[j], vfk_grp) pmc.parent(vfk_grp, jparent) if c == 0: pmc.parent(vfk_grp, off_vfk) if root != None: pmc.parent(off_vfk, root) else: for c in xrange(int(numControls)): jparent = pmc.listRelatives(joints[j], parent=True) vfk_grp = pmc.group(em=True, n= name + jointGroupPrefix + 'j' + str(j+1) + '_c' + str(c+1)) pmc.xform(vfk_grp, ws=True, m=jmtx) pmc.parent(joints[j], vfk_grp) pmc.parent(vfk_grp, jparent) ctrlSpacing = (nurbsWidth/(numControls+1)) for i in xrange(int(numControls)): if boneTranslateAxis == '.tx': ctrl_normal = [1,0,0] if boneTranslateAxis == '.ty': ctrl_normal = [0,1,0] if boneTranslateAxis == '.tz': ctrl_normal = [0,0,1] ctrl = pmc.circle(normal=ctrl_normal, sw=360, r=controlRadius, ch=0, n= name + controlPrefix + str(i+1)) ctrl_off = pmc.group(ctrl, n= name + controlGroupPrefix + str(i+1)) pmc.xform(ctrl_off, ws=True, m=surface_mtx) pmc.parent(ctrl_off, surface) pmc.setAttr(ctrl[0] + boneTranslateAxis, ((nurbsWidth/-2) + (ctrlSpacing*(i+1)))) pmc.parent(ctrl_off, w=True) flcl = self._parentSurfaceFLCL(ctrl, surface[0]) ctrl_mtx = pmc.xform(ctrl, q=True, m=True, ws=True) pmc.xform(ctrl_off, ws=True, m=ctrl_mtx) pmc.parent(ctrl_off, flcl[0]) pmc.parent(ctrl, ctrl_off) min_falloff = 1/numJoints pmc.addAttr(ctrl[0], ln='position', min=0, max=10, dv=0, keyable=True) pmc.addAttr(ctrl[0], ln='falloff', min=min_falloff, max=1, dv=0.5, keyable=True) pmc.addAttr(ctrl[0], ln='numberOfJointsAffected', min=0, max=numJoints, dv=0, keyable=True) multD = pmc.createNode('multiplyDivide', n= name + 'multD_jAff_vfk_' + str(i+1)) setR = mc.createNode('setRange', n= name + 'setR_jAff_vfk_' + str(i+1)) pmc.connectAttr(ctrl[0] + '.falloff', multD + '.input1X') pmc.setAttr(multD + '.input2X', 2) pmc.setAttr(multD + '.operation', 1) pmc.connectAttr(multD + '.outputX', setR + '.valueX') pmc.setAttr(setR + '.oldMinX', 0) pmc.setAttr(setR + '.oldMaxX', 1) pmc.setAttr(setR + '.minX', 0) pmc.setAttr(setR + '.maxX', numJoints) pmc.connectAttr(setR + '.outValueX', ctrl[0] + '.numberOfJointsAffected') paramU = pmc.getAttr(flcl[0] + '.parameterU') div_ten = pmc.createNode('multiplyDivide', n="DIV_" + name + controlPrefix + str(i+1)) pmc.setAttr(div_ten.input2X, 10) pmc.setAttr(div_ten.operation, 2) pmc.connectAttr(ctrl[0] + '.position', div_ten.input1X) pmc.connectAttr(div_ten.outputX, flcl[0] + '.parameterU') pmc.setAttr(ctrl[0] + '.position', paramU * 10.0) fPos_plus = pmc.createNode('plusMinusAverage', n= name + 'fPosPlus_vfk_' + str(i+1)) pmc.connectAttr(div_ten.outputX, fPos_plus + '.input1D[0]', f=True) pmc.connectAttr(ctrl[0] + '.falloff', fPos_plus + '.input1D[1]', f=True) pmc.setAttr(fPos_plus + '.operation', 1) fPos_minus = pmc.createNode('plusMinusAverage', n= name + 'fPosMinus_vfk_' + str(i+1)) pmc.connectAttr(div_ten.outputX, fPos_minus + '.input1D[0]', f=True) pmc.connectAttr(ctrl[0] + '.falloff', fPos_minus + '.input1D[1]', f=True) pmc.setAttr(fPos_minus + '.operation', 2) for f in (fPos_plus, fPos_minus): for j in xrange(len(joints)): upperM = pmc.createNode('plusMinusAverage', n= (name + f + '_upperM_j' + str(j+1) + '_c' + str(i+1))) lowerM = pmc.createNode('plusMinusAverage', n= (name + f + '_lowerM_j' + str(j+1) + '_c' + str(i+1))) pmc.setAttr(upperM + '.operation', 2) pmc.setAttr(lowerM + '.operation', 2) pmc.connectAttr(joints[j] + '.position', upperM + '.input1D[0]') pmc.connectAttr(f + '.output1D', upperM + '.input1D[1]') pmc.connectAttr(div_ten.outputX, lowerM + '.input1D[0]') pmc.connectAttr(f + '.output1D', lowerM + '.input1D[1]') divA = pmc.createNode('multiplyDivide', n= f + '_divA_j' + str(j+1) + '_c' + str(i+1)) pmc.setAttr(divA + '.operation', 2) pmc.connectAttr(upperM + '.output1D', divA + '.input1X') pmc.connectAttr(lowerM + '.output1D', divA + '.input2X') multA = pmc.createNode('multiplyDivide', n= f + '_multA_j' + str(j+1) + '_c' + str(i+1)) pmc.setAttr(multA + '.operation', 1) pmc.connectAttr(divA + '.outputX', multA + '.input1X') pmc.setAttr(multA + '.input2X', 2) divB = pmc.createNode('multiplyDivide', n= f + '_divB_j' + str(j+1) + '_c' + str(i+1)) pmc.setAttr(divB + '.operation', 2) pmc.connectAttr(multA + '.outputX', divB + '.input1X') pmc.connectAttr(ctrl[0] + '.numberOfJointsAffected', divB + '.input2X') for j in xrange(len(joints)): cond = pmc.createNode('condition', n= name + 'cond_j' + str(j+1) + '_c' + str(i+1)) pmc.setAttr(cond + '.operation', 3) pmc.connectAttr(div_ten.outputX, cond + '.firstTerm') # then use minus pmc.connectAttr(joints[j] + '.position', cond + '.secondTerm') # then use plus pmc.connectAttr(fPos_minus + '_divB_j' + str(j+1) + '_c' + str(i+1) + '.outputX', cond + '.colorIfTrueR') pmc.connectAttr(fPos_minus + '_divB_j' + str(j+1) + '_c' + str(i+1) + '.outputX', cond + '.colorIfTrueG') pmc.connectAttr(fPos_minus + '_divB_j' + str(j+1) + '_c' + str(i+1) + '.outputX', cond + '.colorIfTrueB') pmc.connectAttr(fPos_plus + '_divB_j' + str(j+1) + '_c' + str(i+1) + '.outputX', cond + '.colorIfFalseR') pmc.connectAttr(fPos_plus + '_divB_j' + str(j+1) + '_c' + str(i+1) + '.outputX', cond + '.colorIfFalseG') pmc.connectAttr(fPos_plus + '_divB_j' + str(j+1) + '_c' + str(i+1) + '.outputX', cond + '.colorIfFalseB') cond_neg = pmc.createNode('condition', n= name + 'cond_neg_j' + str(j+1) + '_c' + str(i+1)) pmc.connectAttr(cond + '.outColorR', cond_neg + '.firstTerm') pmc.setAttr(cond_neg + '.secondTerm', 0) pmc.setAttr(cond_neg + '.operation', 2) pmc.connectAttr(cond + '.outColor', cond_neg + '.colorIfTrue') pmc.setAttr(cond_neg + '.colorIfFalse', [0,0,0]) multiFinalRot = pmc.createNode('multiplyDivide', n= name + 'multiFinalRot_j' + str(j+1) + '_c' + str(i+1)) pmc.setAttr(multiFinalRot + '.operation', 1) pmc.connectAttr(cond_neg + '.outColor', multiFinalRot + '.input1') pmc.connectAttr(ctrl[0] + '.rotate', multiFinalRot + '.input2') pmc.connectAttr(multiFinalRot + '.output', name + jointGroupPrefix + 'j' + str(j+1) + '_c' + str(i+1) + '.rotate') ''' multiFinalScl = pmc.createNode('multiplyDivide', n= name + 'multiFinalScl_j' + str(j+1) + '_c' + str(i+1)) pmc.setAttr(multiFinalScl + '.operation', 1) pmc.connectAttr(cond + '.outColor', multiFinalScl + '.input1') pmc.connectAttr(ctrl[0] + '.scale', multiFinalScl + '.input2') pmc.connectAttr(multiFinalScl + '.output', name + jointGroupPrefix + 'j' + str(j+1) + '_c' + str(i+1) + '.scale') ''' self._ctrlDBL(ctrl) if endChild: pmc.parent(linkJointEnd, endJoint) pmc.undoInfo(closeChunk=True) pmc.undoInfo(openChunk=True) pmc.skinCluster(joints, name + 'vfk_surface', mi=1) pmc.undoInfo(closeChunk=True)
def RigIK(jnts=None, side='L', ctrlSize=1.0, mode='arm', characterMode='biped', mirrorMode=False, poleVectorTransform=None, footRotate=None, rigHandOrFoot=False): # find color of the ctrls color = 'y' if side == 'L': color = 'r' elif side == 'R': color = 'b' # biped mode # ----------------------------------------------------------- if characterMode == 'biped': # biped inputs check if not jnts: jnts = pm.ls(sl=True) if not len(jnts) == 4: pm.error( 'ehm_tools...rigIK: (biped mode) select uparm, elbow, hand and hend end joints.' ) # check mode - arm or leg if mode == 'arm': limbName = 'hand' secondLimb = 'elbow' elif mode == 'leg': limbName = 'foot' secondLimb = 'knee' else: pm.error( 'ehm_tools...rigIK: mode argument must be either "arm" or "leg"!' ) # start rigging biped uparmJnt = jnts[0] elbowJnt = jnts[1] handJnt = jnts[2] handEndJnt = jnts[3] # find control size if mode == 'arm': ctrlSize = Dist(uparmJnt, elbowJnt) * 0.4 * ctrlSize elif mode == 'leg': ctrlSize = Dist(uparmJnt, elbowJnt) * 0.3 * ctrlSize # find arm limbs position uparmPos = pm.xform(uparmJnt, q=True, t=True, ws=True) elbowPos = pm.xform(elbowJnt, q=True, t=True, ws=True) handPos = pm.xform(handJnt, q=True, t=True, ws=True) # create ik handle armIKStuff = pm.ikHandle(sj=uparmJnt, ee=handJnt, solver="ikRPsolver") armIK = pm.rename(armIKStuff[0], (side + "_arm_ikh")) # make Ik Stretchy locs, dists = MakeIkStretchy(ikh=armIK, elbowLock=True) #======================================================================================================== # create and position the IK elbow control curve if mode == 'arm': elbowIKCtrl = SoftSpiralCrv(ctrlSize, '%s_%s_IK_ctrl' % (side, secondLimb)) # rotate elbowIKCtrl to be seen from side view elbowIKCtrl.rotateZ.set(90) elbowIKCtrl.scaleZ.set(-1) if mirrorMode: ReverseShape(objs=elbowIKCtrl, axis='y') ReverseShape(objs=elbowIKCtrl, axis='z') elif mode == 'leg': elbowIKCtrl = SharpSpiralCrv(ctrlSize, '%s_%s_IK_ctrl' % (side, secondLimb)) # rotate elbowIKCtrl to be seen from side view elbowIKCtrl.rotate.set(90, 90, -90) if mirrorMode: ReverseShape(objs=elbowIKCtrl, axis='y') ReverseShape(objs=elbowIKCtrl, axis='z') pm.makeIdentity(elbowIKCtrl, apply=True) # give it color Colorize(shapes=elbowIKCtrl.getShape(), color=color) tmpAim = pm.group(em=True) if poleVectorTransform: # pole vector position is given elbowIKCtrl.translate.set(poleVectorTransform[0]) elbowIKCtrl.rotate.set(poleVectorTransform[1]) else: # pole vector position is NOT given, we'll guess it aimPos = FindPVposition(objs=(uparmJnt, elbowJnt, handJnt)) if aimPos: # if pole vector position was found by FindPVposition def, we're done :) pm.xform(elbowIKCtrl, ws=True, t=aimPos) else: # limb is straight pm.delete(pm.pointConstraint( elbowJnt, elbowIKCtrl)) # position the elbowIKCtrl if mode == 'arm': # find elbow pole vector position and rotation tmpAim.translate.set( elbowPos[0], elbowPos[1], elbowPos[2] - ctrlSize) # position it slightly behind elbow joint pm.delete( pm.aimConstraint( tmpAim, elbowIKCtrl, upVector=(0, 1, 0), aimVector=( 0, 0, -1))) # rotate elbowIKCtrl to point to tmpAim if mode == 'leg': # find knee pole vector position tmpAim.translate.set( elbowPos[0], elbowPos[1], elbowPos[2] + ctrlSize) # position it slightly behind elbow joint pm.delete( pm.aimConstraint(tmpAim, elbowIKCtrl, upVector=(0, 1, 0), aimVector=(0, 0, 1))) # elbow IK control is in place now, parent elbow loc to it and offset it from arm a bit elbowIKCtrlZeros = ZeroGrp(elbowIKCtrl) pm.parent(locs[1], elbowIKCtrl) locs[1].translate.set(0, 0, 0) locs[1].rotate.set(0, 0, 0) ''' if mode=='arm': elbowIKCtrl.translateZ.set( -ctrlSize*2.0 ) if mode=='leg': elbowIKCtrl.translateZ.set( ctrlSize*2.0 ) ''' # use elbow control curve instead of locator as the pole vector TransferOutConnections(source=locs[1], dest=elbowIKCtrl) LockHideAttr(objs=elbowIKCtrl, attrs='r') LockHideAttr(objs=elbowIKCtrl, attrs='s') # create pole vector pm.poleVectorConstraint(locs[1], armIK) #======================================================================================================== # rig hand or foot and position them in the correct place if mode == 'arm': # position the hand control handIKCtrl = Circle3ArrowCrv(ctrlSize, '%s_%s_IK_ctrl' % (side, limbName)) MatchTransform(force=True, folower=handIKCtrl, lead=handJnt) if rigHandOrFoot: RigHand(handJnt, handEndJnt, handIKCtrl) locs[2].setParent(handIKCtrl) elif mode == 'leg': # position the foot control handIKCtrl = CubeCrv(ctrlSize, '%s_%s_IK_ctrl' % (side, limbName)) handIKCtrl.translate.set(pm.xform(handJnt, q=True, ws=True, t=True)) handIKCtrl.rotate.set(footRotate) if rigHandOrFoot: # rig foot ankleJnt = jnts[2] ballJnt = jnts[3] toeEndJnt = jnts[4] ballPos = pm.xform(jnts[3], q=True, t=True, ws=True) toeEndPos = pm.xform(jnts[4], q=True, t=True, ws=True) heelPos = pm.xform(jnts[5], q=True, t=True, ws=True) outsidePos = pm.xform(jnts[6], q=True, t=True, ws=True) insidePos = pm.xform(jnts[7], q=True, t=True, ws=True) # create foot ik handles ankleBallIKStuff = pm.ikHandle(sj=ankleJnt, ee=ballJnt, solver="ikSCsolver") ankleBallIK = pm.rename(ankleBallIKStuff[0], (side + "_ankleBall_ikh")) ballToeEndIKStuff = pm.ikHandle(sj=ballJnt, ee=toeEndJnt, solver="ikSCsolver") ballToeIK = pm.rename(ballToeEndIKStuff[0], (side + "_ballToeEnd_ikh")) # add attributes to foot controler pm.addAttr(handIKCtrl, ln="roll", at='double', min=-10, max=10, dv=0, keyable=True) pm.addAttr(handIKCtrl, ln="sideToSide", at='double', min=-10, max=10, dv=0, keyable=True) pm.addAttr(handIKCtrl, ln="toes", at='double', min=-10, max=10, dv=0, keyable=True) # toe group toeGrp = pm.group(ballToeIK, name='%s_toe_IK_grp' % side) pm.xform(toeGrp, os=True, piv=(ballPos)) # heelUp group heelUpGrp = pm.group(ankleBallIK, locs[2], name='%s_heelUp_IK_grp' % side) pm.xform(heelUpGrp, os=True, piv=(ballPos)) # pivOnToe group outsideGrp = pm.group(toeGrp, heelUpGrp, name='%s_outside_IK_grp' % side) pm.xform(outsideGrp, os=True, piv=(outsidePos)) # pivOnHeel group insideGrp = pm.group(outsideGrp, name='%s_inside_IK_grp' % side) pm.xform(insideGrp, os=True, piv=(insidePos)) # pivOutSide group toeTipGrp = pm.group(insideGrp, name='%s_toeTip_IK_grp' % side) pm.xform(toeTipGrp, os=True, piv=(toeEndPos)) # pivInSide group heelGrp = pm.group(toeTipGrp, name='%s_heel_IK_grp' % side) pm.xform(heelGrp, os=True, piv=(heelPos)) footGrp = pm.group(heelGrp, name='%s_foot_IK_grp' % side) footGrp.setParent(handIKCtrl) # toe set driven keys pm.setDrivenKeyframe(toeGrp.rotateX, currentDriver=handIKCtrl.toes, itt='linear', ott='linear', driverValue=10, value=-90) pm.setDrivenKeyframe(toeGrp.rotateX, currentDriver=handIKCtrl.toes, itt='linear', ott='linear', driverValue=-10, value=90) # roll set driven keys pm.setDrivenKeyframe(heelUpGrp.rotateX, currentDriver=handIKCtrl.roll, itt='linear', ott='linear', driverValue=0, value=0) pm.setDrivenKeyframe(heelUpGrp.rotateX, currentDriver=handIKCtrl.roll, itt='linear', ott='linear', driverValue=-5, value=45) pm.setDrivenKeyframe(heelUpGrp.rotateX, currentDriver=handIKCtrl.roll, itt='linear', ott='linear', driverValue=10, value=0) pm.setDrivenKeyframe(toeTipGrp.rotateX, currentDriver=handIKCtrl.roll, itt='linear', ott='linear', driverValue=-5, value=0) pm.setDrivenKeyframe(toeTipGrp.rotateX, currentDriver=handIKCtrl.roll, itt='linear', ott='linear', driverValue=-10, value=60) pm.setDrivenKeyframe(heelGrp.rotateX, currentDriver=handIKCtrl.roll, itt='linear', ott='linear', driverValue=10, value=-45) pm.setDrivenKeyframe(heelGrp.rotateX, currentDriver=handIKCtrl.roll, itt='linear', ott='linear', driverValue=0, value=0) # sideToSide set driven keys value = 45 if mirrorMode: value = -45 pm.setDrivenKeyframe(outsideGrp.rotateZ, currentDriver=handIKCtrl.sideToSide, itt='linear', ott='linear', driverValue=0, value=0) pm.setDrivenKeyframe(outsideGrp.rotateZ, currentDriver=handIKCtrl.sideToSide, itt='linear', ott='linear', driverValue=10, value=-value) pm.setDrivenKeyframe(insideGrp.rotateZ, currentDriver=handIKCtrl.sideToSide, itt='linear', ott='linear', driverValue=0, value=0) pm.setDrivenKeyframe(insideGrp.rotateZ, currentDriver=handIKCtrl.sideToSide, itt='linear', ott='linear', driverValue=-10, value=value) # delete joint that determine foot's different pivots pm.delete(jnts[-3:]) # hide extras LockHideAttr(objs=(ankleBallIKStuff, ballToeEndIKStuff), attrs='vv') handIKCtrlZeros = ZeroGrp(handIKCtrl) handIKCtrlZero = handIKCtrlZeros[0] TransferOutConnections(source=locs[2], dest=handIKCtrl) # colorize hand control Colorize(shapes=handIKCtrl.getShape(), color=color) # check if joints are mirrored, if so, we must reverse the hand control vertices if mirrorMode: ReverseShape(axis='x', objs=handIKCtrl) # hide extra stuff LockHideAttr(objs=locs, attrs='vv') LockHideAttr(objs=dists, attrs='vv') ikGrp = pm.group(jnts[0], dists, locs[0], name='%s_ik_arm' % side) pm.xform(ikGrp, os=True, piv=(0, 0, 0)) # create guide curves for pole vector elbowGuide = GuideCrv(elbowIKCtrl, elbowJnt) elbowIKCtrl.v >> elbowGuide.getShape().v elbowGuide.setParent(ikGrp) # clean up pm.delete(tmpAim) # return return (handIKCtrl, elbowIKCtrl, jnts, locs, dists, handIKCtrlZeros, elbowIKCtrlZeros, ikGrp) # quadruped mode # ----------------------------------------------------------- if characterMode == 'quadruped': # quadruped inputs check if not jnts: jnts = pm.ls(sl=True) if not len(jnts) == 7: pm.error( 'ehm_tools...rigIK: (quadruped mode) jnts arguments needs 7 joints.' ) # check mode - arm or leg if mode == 'arm': pm.error('ehm_tools...rigIK: quadruped arm is not defined yet!') elif mode == 'leg': firstLimbName = 'pelvis' secondLimbName = 'hip' thirdLimbName = 'stifle' forthLimbName = 'hock' fifthLimbName = 'ankle' sixthLimbName = 'hoof' seventhLimbName = 'hoofEnd' else: pm.error( 'ehm_tools...rigIK: mode argument must be either "arm" or "leg"!' ) # start rigging the quadruped pelvisJnt = jnts[0] hipJnt = jnts[1] stifleJnt = jnts[2] hockJnt = jnts[3] ankleJnt = jnts[4] hoofJnt = jnts[5] hoofEndJnt = jnts[6] # find arm limbs position pelvisPos = pm.xform(pelvisJnt, q=True, t=True, ws=True) hipPos = pm.xform(hipJnt, q=True, t=True, ws=True) stiflePos = pm.xform(stifleJnt, q=True, t=True, ws=True) hockPos = pm.xform(hockJnt, q=True, t=True, ws=True) anklePos = pm.xform(ankleJnt, q=True, t=True, ws=True) hoofPos = pm.xform(hoofJnt, q=True, t=True, ws=True) hoofEndPos = pm.xform(hoofEndJnt, q=True, t=True, ws=True) # find control size ctrlSize = Dist(hipJnt, hockJnt) * 0.2 * ctrlSize # set preferred angle if mode == 'arm': pm.error('ehm_tools...rigIK: quadruped arm is not defined yet!') else: stifleJnt.preferredAngleZ.set(10) hockJnt.preferredAngleZ.set(-10) # create ik handle for main joint chain IKstuff = pm.ikHandle(sj=hipJnt, ee=hockJnt, solver="ikRPsolver") ankleIKstuff = pm.ikHandle(sj=hockJnt, ee=ankleJnt, solver="ikSCsolver") # create 3 extra joint chains for making some auto movements on the leg: # chain 1. upper leg, lower leg, foot # - this chain is used for automatic upper leg bending when foot control is moved pm.select(clear=True) autoUpLegJnt_tmp = pm.duplicate(hipJnt)[0] autoJnts_tmp = GetAllChildren(objs=autoUpLegJnt_tmp, childType='joint') autoUpLegJnt = pm.rename(autoJnts_tmp[0], '%s_autoUpLegJnt' % side) autoLowLegJnt = pm.rename(autoJnts_tmp[1], '%s_autoLowLegJnt' % side) autoKneeJnt = pm.rename(autoJnts_tmp[2], '%s_autoKneeJnt' % side) autoKneeEndJnt = pm.rename(autoJnts_tmp[3], '%s_autoKneeEndJnt' % side) autoIKstuff = pm.ikHandle(sj=autoUpLegJnt, ee=autoKneeEndJnt, solver="ikRPsolver") # chain 2 and 3: # - these chains are needed for automatic pole vector PV = autoPoleVector(baseJnt=hipJnt, endJnt=hockJnt, side=side) autoPV = autoPoleVector(baseJnt=autoUpLegJnt, endJnt=autoKneeEndJnt, side='L') # create automatic pole vector and set the twist parameter pm.poleVectorConstraint(PV[0], IKstuff[0]) pm.poleVectorConstraint(autoPV[0], autoIKstuff[0]) if side == 'L': IKstuff[0].twist.set(90) autoIKstuff[0].twist.set(90) elif side == 'R': IKstuff[0].twist.set(-90) autoIKstuff[0].twist.set(-90) # parent all ikhandles to auto kneeEnd joint. # now we're controling 3 joint chain ik handle with one joint # which itself is being controled by foot control. IKstuffGrp = pm.group(ankleIKstuff[0], IKstuff[0], PV[1][0]) pm.xform(os=True, piv=(pm.xform(ankleJnt, q=True, t=True, ws=True))) IKstuffGrp.setParent(autoKneeEndJnt) autoIKstuffZeros = ZeroGrp(autoIKstuff[0]) autoPV[1][0].setParent(autoIKstuffZeros[1]) # make Ik Stretchy locs, dists = MakeIkStretchy(ikh=autoIKstuff[0], elbowLock=False) # Finally, parent main upLeg joint to autoUpLegJnt. The purpose of whole auto joint chain pm.parent(locs[0], autoUpLegJnt) ZeroGrp() pm.parentConstraint(autoUpLegJnt, hipJnt, mo=True) # create IK hand control if mode == 'arm': pm.error('ehm_tools...rigIK: quadruped arm is not defined yet!') else: IKCtrl = CubeCrv(size=ctrlSize, name='%s_%s_IK_ctrl' % (side, ankleJnt)) # position the hand control pm.addAttr(IKCtrl, ln="upLeg_rotation", at='double', keyable=True) # find color of the ctrls color = 'y' if side == 'L': color = 'r' elif side == 'R': color = 'b' Colorize(shapes=IKCtrl.getShape(), color=color) # position the hand control if mode == 'arm': pm.error('ehm_tools...rigIK: quadruped arm is not defined yet!') else: pm.delete(pm.pointConstraint(ankleJnt, IKCtrl)) IKCtrl.rotateY.set( ProjectedAim(objs=(hipJnt, stifleJnt), fullCircle=False)) IKCtrlZeros = ZeroGrp(IKCtrl) #IKCtrlZero = IKCtrlZeros[0] pm.pointConstraint(IKCtrl, PV[1][0]) pm.parent(autoIKstuff[0], locs[2], IKCtrl) TransferOutConnections(source=locs[2], dest=IKCtrl) # check if joints are mirrored, if so, we must reverse the hand control vertices #x = kneeEndJnt.translateX.get() #y = kneeEndJnt.translateY.get() #z = kneeEndJnt.translateZ.get() #if x < 0: # ReverseShape( axis = 'x', objs = IKCtrl ) #elif y < 0: # ReverseShape( axis = 'y', objs = IKCtrl ) #elif z < 0: # ReverseShape( axis = 'z', objs = IKCtrl ) # hide extra stuff LockHideAttr(objs=locs, attrs='vv') LockHideAttr(objs=dists, attrs='vv') LockHideAttr(objs=PV[0], attrs='vv') LockHideAttr(objs=PV[1], attrs='vv') LockHideAttr(objs=autoIKstuff, attrs='vv') LockHideAttr(objs=autoUpLegJnt, attrs='vv') LockHideAttr(objs=PV[2][0], attrs='vv') # cleaup outliner ikGrp = pm.group(hipJnt, autoUpLegJnt, PV[2][0], dists, locs[1], PV[1][0], IKCtrlZeros[0], name='%s_ik_leg' % side) pm.xform(ikGrp, os=True, piv=(0, 0, 0))
def createRivetTweak(mesh, edgePair, name, parent=None, ctlParent=None, jntParent=None, color=[0, 0, 0], size=.04, defSet=None, ctlSet=None, side=None, gearMulMatrix=True, attach_rot=False, inputMesh=None): """Create a tweak joint attached to the mesh using a rivet Args: mesh (mesh): The object to add the tweak edgePair (pair list): The edge pair to create the rivet name (str): The name for the tweak parent (None or dagNode, optional): The parent for the tweak jntParent (None or dagNode, optional): The parent for the joints ctlParent (None or dagNode, optional): The parent for the tweak control color (list, optional): The color for the control size (float, optional): Size of the control defSet (None or set, optional): Deformer set to add the joints ctlSet (None or set, optional): the set to add the controls side (None, str): String to set the side. Valid values are L, R or C. If the side is not set or the value is not valid, the side will be set automatically based on the world position gearMulMatrix (bool, optional): If False will use Maya default multiply matrix node Returns: PyNode: The tweak control """ blendShape = blendShapes.getBlendShape(mesh) if not inputMesh: inputMesh = blendShape.listConnections(sh=True, t="shape", d=False)[0] oRivet = rivet.rivet() base = oRivet.create(inputMesh, edgePair[0], edgePair[1], parent) # get side if not side or side not in ["L", "R", "C"]: if base.getTranslation(space='world')[0] < -0.01: side = "R" elif base.getTranslation(space='world')[0] > 0.01: side = "L" else: side = "C" nameSide = name + "_tweak_" + side pm.rename(base, nameSide) if not ctlParent: ctlParent = base ctl_parent_tag = None else: ctl_parent_tag = ctlParent # Joints NPO npo = pm.PyNode(pm.createNode("transform", n=nameSide + "_npo", p=ctlParent, ss=True)) if attach_rot: # npo.setTranslation(base.getTranslation(space="world"), space="world") pm.parentConstraint(base, npo, mo=False) else: pm.pointConstraint(base, npo, mo=False) # create joints if not jntParent: jntParent = npo matrix_cnx = False else: # need extra connection to ensure is moving with th npo, even is # not child of npo matrix_cnx = True jointBase = primitive.addJoint(jntParent, nameSide + "_jnt_lvl") joint = primitive.addJoint(jointBase, nameSide + "_jnt") # reset axis and invert behaviour for axis in "XYZ": pm.setAttr(jointBase + ".jointOrient" + axis, 0) pm.setAttr(npo + ".translate" + axis, 0) # pm.setAttr(jointBase + ".translate" + axis, 0) pp = npo.getParent() pm.parent(npo, w=True) for axis in "xyz": npo.attr("r" + axis).set(0) if side == "R": npo.attr("ry").set(180) npo.attr("sz").set(-1) pm.parent(npo, pp) dm_node = None if matrix_cnx: mulmat_node = applyop.gear_mulmatrix_op( npo + ".worldMatrix", jointBase + ".parentInverseMatrix") dm_node = node.createDecomposeMatrixNode( mulmat_node + ".output") m = mulmat_node.attr('output').get() pm.connectAttr(dm_node + ".outputTranslate", jointBase + ".t") pm.connectAttr(dm_node + ".outputRotate", jointBase + ".r") # invert negative scaling in Joints. We only inver Z axis, so is # the only axis that we are checking print(dm_node.attr("outputScaleZ").get()) if dm_node.attr("outputScaleZ").get() < 0: mul_nod_invert = node.createMulNode( dm_node.attr("outputScaleZ"), -1) out_val = mul_nod_invert.attr("outputX") else: out_val = dm_node.attr("outputScaleZ") pm.connectAttr(dm_node.attr("outputScaleX"), jointBase + ".sx") pm.connectAttr(dm_node.attr("outputScaleY"), jointBase + ".sy") pm.connectAttr(out_val, jointBase + ".sz") pm.connectAttr(dm_node + ".outputShear", jointBase + ".shear") # Segment scale compensate Off to avoid issues with the global # scale jointBase.setAttr("segmentScaleCompensate", 0) joint.setAttr("segmentScaleCompensate", 0) jointBase.setAttr("jointOrient", 0, 0, 0) # setting the joint orient compensation in order to have clean # rotation channels jointBase.attr("jointOrientX").set(jointBase.attr("rx").get()) jointBase.attr("jointOrientY").set(jointBase.attr("ry").get()) jointBase.attr("jointOrientZ").set(jointBase.attr("rz").get()) im = m.inverse() if gearMulMatrix: mul_nod = applyop.gear_mulmatrix_op( mulmat_node.attr('output'), im, jointBase, 'r') dm_node2 = mul_nod.output.listConnections()[0] else: mul_nod = node.createMultMatrixNode( mulmat_node.attr('matrixSum'), im, jointBase, 'r') dm_node2 = mul_nod.matrixSum.listConnections()[0] if dm_node.attr("outputScaleZ").get() < 0: negateTransformConnection(dm_node2.outputRotate, jointBase.rotate) else: resetJntLocalSRT(jointBase) # hidding joint base by changing the draw mode pm.setAttr(jointBase + ".drawStyle", 2) if not defSet: try: defSet = pm.PyNode("rig_deformers_grp") except TypeError: pm.sets(n="rig_deformers_grp", empty=True) defSet = pm.PyNode("rig_deformers_grp") pm.sets(defSet, add=joint) controlType = "sphere" o_icon = icon.create(npo, nameSide + "_ctl", datatypes.Matrix(), color, controlType, w=size) attribute.addAttribute(o_icon, "isCtl", "bool", keyable=False) transform.resetTransform(o_icon) if dm_node and dm_node.attr("outputScaleZ").get() < 0: pm.connectAttr(o_icon.scale, joint.scale) negateTransformConnection(o_icon.rotate, joint.rotate) negateTransformConnection(o_icon.translate, joint.translate, [1, 1, -1]) else: for t in [".translate", ".scale", ".rotate"]: pm.connectAttr(o_icon + t, joint + t) # create the attributes to handlde mirror and symetrical pose attribute.addAttribute( o_icon, "invTx", "bool", 0, keyable=False, niceName="Invert Mirror TX") attribute.addAttribute( o_icon, "invTy", "bool", 0, keyable=False, niceName="Invert Mirror TY") attribute.addAttribute( o_icon, "invTz", "bool", 0, keyable=False, niceName="Invert Mirror TZ") attribute.addAttribute( o_icon, "invRx", "bool", 0, keyable=False, niceName="Invert Mirror RX") attribute.addAttribute( o_icon, "invRy", "bool", 0, keyable=False, niceName="Invert Mirror RY") attribute.addAttribute( o_icon, "invRz", "bool", 0, keyable=False, niceName="Invert Mirror RZ") attribute.addAttribute( o_icon, "invSx", "bool", 0, keyable=False, niceName="Invert Mirror SX") attribute.addAttribute( o_icon, "invSy", "bool", 0, keyable=False, niceName="Invert Mirror SY") attribute.addAttribute( o_icon, "invSz", "bool", 0, keyable=False, niceName="Invert Mirror SZ") # magic of doritos connection pre_bind_matrix_connect(mesh, joint, jointBase) # add control tag node.add_controller_tag(o_icon, ctl_parent_tag) if not ctlSet: try: ctlSet = pm.PyNode("rig_controllers_grp") except TypeError: pm.sets(n="rig_controllers_grp", empty=True) ctlSet = pm.PyNode("rig_controllers_grp") pm.sets(ctlSet, add=o_icon) return o_icon
def hairtransfer(hairsrmesh,hairtrmesh): hairsyssels=[] filename =os.path.basename( cmds.file(expandName=1,q=1)).split(".")[0] hairwhole = pm.group(em=1,name=filename+"_hair_G") folwhole = pm.group(em=1,name=filename+"_fols_G") cvswhole = pm.group(em=1,name=filename+"_outputCvs_G") pfxwhole = pm.group(em=1,name=filename+"_pfxHairs_G") try: hairShapesr = hairsrmesh.getShape() hairShapetr = hairtrmesh.getShape() except: hairShapesr=[] hairShapetr=[] pm.warning(selsrs[i]+"'s shapeNode is not exists!!") follicles = pm.listConnections(hairShapesr,s=0,type="follicle") if follicles!=None: for follicle in follicles: follicleshape = follicle.getShape() hairsyssel = pm.listConnections( follicleshape+".outHair",s=0,type="hairSystem")[0] if hairsyssel not in hairsyssels: hairsyssels.append(hairsyssel) pfxhairsel = pm.listConnections( hairsyssel+".outputRenderHairs",s=0,type="pfxHair")[0] pm.parent(pfxhairsel,pfxwhole) folliclesels = pm.listConnections( hairsyssel+".inputHair",d=0) cvs = [pm.listConnections(a+".outCurve",s=0)[0] for a in folliclesels] for cv in cvs: cvsconnects= pm.listConnections(cv.getShape(),c=1,plugs=1)[0] pm.disconnectAttr(cvsconnects[1],cvsconnects[0]) cvsgrp =pm.group(cvs,name=str(hairsyssel)+"_cvs_g") pm.select(hairtrmesh,r=1) pm.select(cvsgrp,tgl=1) mel.eval('makeCurvesDynamic 2 { "1", "1", "1", "1", "1"};') newfollicles = [b.getParent() for b in cvs if b.getParent().getShape()!=None] newcvs = [pm.listConnections(a+".outCurve",s=0)[0] for a in newfollicles ] oldhairsys =[pm.listConnections(a.getShape()+".outHair",s=0,type="hairSystem")[0] for a in newfollicles] oldhairsys = list(set(oldhairsys)) nucleussels =[pm.listConnections(a.getShape(),s=0,type="nucleus")[0] for a in oldhairsys] nucleussels = list(set(nucleussels)) pm.delete(oldhairsys,nucleussels) pm.select(newfollicles,r=1) mel.eval('assignHairSystem %s'%(hairsyssel)) try: pm.parent(hairsyssel+"Follicles",folwhole) pm.parent(hairsyssel+"OutputCurves",cvswhole) pm.setAttr(hairsyssel+"OutputCurves.visibility",0) except: pm.warning('cant not parent Follicles and OutputCurves group!!') hairsystrsgrp = pm.group(hairsyssels,name = filename+"_hairSystems_G") pm.parent(pfxwhole,hairwhole) pm.parent(hairsystrsgrp,hairwhole) pm.setAttr(hairsystrsgrp+".visibility",0) pm.parent(folwhole,hairwhole) pm.setAttr(folwhole+".visibility",0) pm.parent(cvswhole,hairwhole) pm.setAttr(cvswhole+".visibility",0)
def createMultiStereoCamera(root, rootShape, camIndex, nStereoCams=9): ''' create a multi stereo camera and setup control expressions ''' cam, camShape = pc.camera() pc.parent(cam, root) name = str(root) + '_StereoCam%d' % (camIndex+1) cam.rename(name) camShape.renderable.set(False) # Connect the camera attributes from the master, hide them # for attr in [ 'horizontalFilmAperture', 'verticalFilmAperture', 'focalLength', 'lensSqueezeRatio', 'fStop', 'focusDistance', 'shutterAngle', 'cameraPrecompTemplate', 'filmFit', 'displayFilmGate', 'displayResolution', 'nearClipPlane', 'farClipPlane' ] : camShapeAttr = camShape.attr(attr) rootShape.attr(attr) >> camShapeAttr camShapeAttr.set(keyable=False) for attr in [ 'visibility', 'centerOfInterest' ] : cam.attr(attr).set(keyable=False) #stereoOffset = stereoEyeSeparation * (camIndex - nCams/2.0 + 0.5) #shift = -stereoOffset * (fl/10.0) / imageZ * p / (INCHES_TO_MM/10) mult = camIndex - nStereoCams / 2.0 + 0.5 mult *= 2 offsetAttr = 'stereoRightOffset' rotAttr = 'stereoRightAngle' hfoAttr = 'filmBackOutputRight' if mult < 0: offsetAttr = 'stereoLeftOffset' rotAttr = 'stereoLeftAngle' hfoAttr = 'filmBackOutputLeft' mult = abs(mult) offsetAttr = root.attr(offsetAttr) rotAttr = root.attr(rotAttr) hfoAttr = root.attr(hfoAttr) expression = getMultStereoExpression( mult, hfoAttr, offsetAttr, rotAttr, rootShape.zeroParallax, cam.translateX, camShape.hfo, cam.rotateY ) exprNode = pc.expression(s=expression) exprNode.rename(cam.name() + '_expression') lockAndHide(cam) return cam
def h_soft(self, controller, pvc_target=None): """ Soft IK as show on http://hhoughton07.wixsite.com/hazmondo/maya-ik-arm """ # if no IK implemented so run the regular pole vector IK. if not self.ikHandle: self.pvc_ik(controller, pvc_target) # Get length of limb length = self.length() pm.addAttr( controller, shortName='sf', longName='soft', niceName='Soft', defaultValue=0.0, maxValue=1.0, minValue=0.0, hidden=False, keyable=True, readable=True, ) # Create a group at top joint, so we got a source for position in order to avoid cycle checks. translate_output = pm.group(empty=True, name='{}_translate_output'.format( self.name)) pm.parent(translate_output, self.joints[0], relative=True) pm.parent(translate_output, self.joints[0].listRelatives(parent=True)[0].nodeName()) # Get matrices for start and controller position start = pm.createNode('decomposeMatrix', name='{}_start_WMtx'.format(self.name)) target = pm.createNode('decomposeMatrix', name='{}_target_WMtx'.format(self.name)) pm.connectAttr(translate_output.worldMatrix[0], start.inputMatrix) pm.connectAttr(controller.worldMatrix[0], target.inputMatrix) distance = pm.createNode('distanceBetween', name='{}_targetDistance'.format(self.name)) # Hook the world positions to the distance node, order shouldn't matter pm.connectAttr(target.outputTranslate, distance.point1) pm.connectAttr(start.outputTranslate, distance.point2) # Get Limb.length() minus controller.soft len = pm.createNode('plusMinusAverage', name='{}_minLen'.format(self.name)) len.setAttr('operation', 2) # Subtract len.setAttr('input1D[0]', length) pm.connectAttr(controller.soft, len.input1D[1]) # Take the distance minus Soft attribute. dist = pm.createNode('plusMinusAverage', name='{}_minDist'.format(self.name)) dist.setAttr('operation', 2) # Subtract pm.connectAttr(distance.distance, dist.input1D[0]) pm.connectAttr(len.output1D, dist.input1D[1]) # distance-(length-soft)/soft div = pm.createNode('multiplyDivide', name='{}_divSoft'.format(self.name)) div.setAttr('operation', 2) # Set to Divide pm.connectAttr(dist.output1D, div.input1X) pm.connectAttr(controller.soft, div.input2X) inv = pm.createNode('multiplyDivide', name='{}_inv'.format(self.name)) inv.setAttr('operation', 1) # Set to Multiply inv.setAttr('input1X', -1) pm.connectAttr(div.output, inv.input2) # Only X channel carrying data. exp = pm.createNode('multiplyDivide', name='{}_exp'.format(self.name)) exp.setAttr('operation', 3) # Set to Power exp.setAttr('input1X', math.e) pm.connectAttr(inv.output, exp.input2) mul = pm.createNode('multiplyDivide', name='{}_multSoft'.format(self.name)) mul.setAttr('operation', 1) # Set to Multiply pm.connectAttr(controller.soft, mul.input1X) pm.connectAttr(exp.outputX, mul.input2X) magnitude = pm.createNode('plusMinusAverage', name='{}_magnitude'.format(self.name)) magnitude.setAttr('operation', 2) # Subtract magnitude.setAttr('input1D[0]', length) pm.connectAttr(mul.outputX, magnitude.input1D[1]) # If soft, soft factor, else limb length soft = pm.createNode('condition', name='{}_ifSoft'.format(self.name)) soft.setAttr('operation', 2) # Greater than soft.setAttr('secondTerm', 0) soft.setAttr('colorIfFalseR', length) pm.connectAttr(magnitude.output1D, soft.colorIfTrueR) pm.connectAttr(controller.soft, soft.firstTerm) # If distance greater than length, final_magnitude = pm.createNode('condition', name='{}_distGreaterLength'.format( self.name)) final_magnitude.setAttr('operation', 2) # Greater than pm.connectAttr(distance.distance, final_magnitude.colorIfFalseR) pm.connectAttr(soft.outColorR, final_magnitude.colorIfTrueR) pm.connectAttr(distance.distance, final_magnitude.firstTerm) pm.connectAttr(len.output1D, final_magnitude.secondTerm) # Target - Start = vector(start->target) direction = pm.createNode('plusMinusAverage', name='{}_dirVector'.format(self.name)) direction.setAttr('operation', 2) # Subtract pm.connectAttr(target.outputTranslate, direction.input3D[0]) pm.connectAttr(start.outputTranslate, direction.input3D[1]) # Normalize vector so we only get direction. normalized = pm.createNode('vectorProduct', name='{}_normalized'.format( direction.nodeName())) normalized.setAttr('operation', 0) # No Operation normalized.setAttr('normalizeOutput', 1) # Normalize the output pm.connectAttr(direction.output3D, normalized.input1) # Multiply the magnitude with the normalized directional vector. final_vector = pm.createNode('multiplyDivide', name='{}_softIK_output'.format(self.name)) final_vector.setAttr('operation', 1) # Multiply # Connect all the scalar inputs X, Y, Z pm.connectAttr(final_magnitude.outColorR, final_vector.input2X) pm.connectAttr(final_magnitude.outColorR, final_vector.input2Y) pm.connectAttr(final_magnitude.outColorR, final_vector.input2Z) # Connect the Vector pm.connectAttr(normalized.output, final_vector.input1) # Add Position Vector for top joint, and the output from soft IK solution. ik_world_position = pm.createNode('plusMinusAverage', name='{}_target_WPos'.format( self.ikHandle.nodeName())) ik_world_position.setAttr('operation', 1) # Sum pm.connectAttr(start.outputTranslate, ik_world_position.input3D[0]) pm.connectAttr(final_vector.output, ik_world_position.input3D[1]) # TODO Sort the hierarchy for ikHandle, and give ik_world_position.output3D as worldspace transforms. # Temporary Fix pm.parent(self.ikHandle, world=True) pm.connectAttr(ik_world_position.output3D, self.ikHandle.translate)
def soft(self, controller): """ Create node network to set soft IK for limb.""" # TODO Out Vector = Length if distance to ctrl is equal to or less than length... length = self.length() # Add attribute to our controller for soft IK damp factor. pm.addAttr( controller, shortName='sf', longName='soft', niceName='Soft', defaultValue=0.0, maxValue=1.0, minValue=0.0, hidden=False, keyable=True, readable=True, ) # Decompose Matrices to get World Space Position for target and start of limb, then supply a distance node. translate_output = pm.group(empty=True, name='{}_translate_output'.format( self.name)) pm.parent(translate_output, self.joints[0], relative=True) pm.parent(translate_output, self.joints[0].listRelatives(parent=True)[0].nodeName()) start = pm.createNode('decomposeMatrix', name='{}_start_WMtx'.format(self.name)) target = pm.createNode('decomposeMatrix', name='{}_target_WMtx'.format(self.name)) targetDistance = pm.createNode('distanceBetween', name='{}_targetDistance'.format( self.name)) # Connect sources to our decompose matrices pm.connectAttr(controller.worldMatrix[0], target.inputMatrix) pm.connectAttr(translate_output.worldMatrix[0], start.inputMatrix) # Hook the positions to the distance node, order shouldn't matter pm.connectAttr(target.outputTranslate, targetDistance.point1) pm.connectAttr(start.outputTranslate, targetDistance.point2) # Nodes for Soft IK solution. soft_distance = pm.createNode('multiplyDivide', name='{}_softDist'.format(self.name)) soft_distance.setAttr('operation', 1) # Set to Multiply soft_distance.setAttr('input2X', length) pm.connectAttr(controller.soft, soft_distance.input1X) # Hard Distance is the range we want IK to follow fully, which is total length - distance we want soft IK. hard_distance = pm.createNode('plusMinusAverage', name='{}_hardDist'.format(self.name)) hard_distance.setAttr('operation', 2) # Set to Subtract hard_distance.setAttr('input1D[0]', length) pm.connectAttr(soft_distance.outputX, hard_distance.input1D[1]) # Get the Hard distance minus distance to target. subtract_distance = pm.createNode('plusMinusAverage', name='{}_subDist'.format(self.name)) subtract_distance.setAttr('operation', 2) # Subtract pm.connectAttr(hard_distance.output1D, subtract_distance.input1D[0]) pm.connectAttr(targetDistance.distance, subtract_distance.input1D[1]) distance_factor = pm.createNode('multiplyDivide', name='{}_distFac'.format(self.name)) distance_factor.setAttr('operation', 2) # Divide pm.connectAttr(subtract_distance.output1D, distance_factor.input1X) pm.connectAttr(soft_distance.outputX, distance_factor.input2X) # To avoid divide by zero errors we also connect a condition to freeze division node. freeze_division = pm.createNode('condition', name='{}_freezeDivision'.format( self.name)) freeze_division.setAttr('colorIfTrueR', 1) freeze_division.setAttr('colorIfFalseR', 0) freeze_division.setAttr('operation', 0) # Equals freeze_division.setAttr('secondTerm', 0) pm.connectAttr(controller.soft, freeze_division.firstTerm) pm.connectAttr(freeze_division.outColorR, distance_factor.frozen) # Exponential function for our distance factor exp = pm.createNode('multiplyDivide', name='{}_exp'.format(self.name)) exp.setAttr('operation', 3) # Set to Power exp.setAttr('input1X', math.e) pm.connectAttr(distance_factor.outputX, exp.input2X) # 1 - result of exponential function. one_minus = pm.createNode('plusMinusAverage', name='{}_one_minus'.format(self.name)) one_minus.setAttr('operation', 2) one_minus.setAttr('input1D[0]', 1) pm.connectAttr(exp.outputX, one_minus.input1D[1]) # Multiply Soft Distance with the result of the exponential function. mult_soft_distance = pm.createNode('multiplyDivide', name='{}_multSoftExp'.format( self.name)) mult_soft_distance.setAttr('operation', 1) # Multiply pm.connectAttr(soft_distance.outputX, mult_soft_distance.input1X) pm.connectAttr(one_minus.output1D, mult_soft_distance.input2X) # Sum Hard Distance with whatever one can call the node above. final_soft_distance = pm.createNode('plusMinusAverage', name='{}_sum_softDistance'.format( self.name)) final_soft_distance.setAttr('operation', 1) # Sum pm.connectAttr(hard_distance.output1D, final_soft_distance.input1D[0]) pm.connectAttr(mult_soft_distance.outputX, final_soft_distance.input1D[1]) # If Soft distance is greater than length. finalDist = pm.createNode('condition', name='{}_finalDistance'.format(self.name)) finalDist.setAttr('operation', 5) # Less or Equal pm.connectAttr(targetDistance.distance, finalDist.firstTerm) pm.connectAttr(hard_distance.output1D, finalDist.secondTerm) pm.connectAttr(targetDistance.distance, finalDist.colorIfTrueR) pm.connectAttr(final_soft_distance.output1D, finalDist.colorIfFalseR) soft_ratio = pm.createNode('multiplyDivide', name='{}_soft_ratio'.format(self.name)) soft_ratio.setAttr('operation', 2) # Multiply pm.connectAttr(finalDist.outColorR, soft_ratio.input1X) pm.connectAttr(targetDistance.distance, soft_ratio.input2X) # If soft ratio is not 0 soft ratio, else 1. ratio = pm.createNode('condition', name='{}_finalRatio'.format(self.name)) ratio.setAttr('secondTerm', 0) ratio.setAttr('colorIfTrueR', 1) ratio.setAttr('operation', 0) # Equals pm.connectAttr(controller.soft, ratio.firstTerm) pm.connectAttr(soft_ratio.outputX, ratio.colorIfFalseR) # 1 - ratio to get what to multiply vectors with. subtract_ratio = pm.createNode('plusMinusAverage', name='{}_oneMinus_ratio'.format( self.name)) subtract_ratio.setAttr('operation', 2) # Subtract subtract_ratio.setAttr('input1D[0]', 1) pm.connectAttr(ratio.outColorR, subtract_ratio.input1D[1]) # Start Vector * final ratio start_vector = pm.createNode('multiplyDivide', name='{}_sVector'.format(self.name)) start_vector.setAttr('operation', 1) # Multiply pm.connectAttr(start.outputTranslate, start_vector.input1) pm.connectAttr(subtract_ratio.output1D, start_vector.input2X) pm.connectAttr(subtract_ratio.output1D, start_vector.input2Y) pm.connectAttr(subtract_ratio.output1D, start_vector.input2Z) # Target Vector * final ratio target_vector = pm.createNode('multiplyDivide', name='{}_eVector'.format(self.name)) target_vector.setAttr('operation', 1) # Multiply pm.connectAttr(target.outputTranslate, target_vector.input1) pm.connectAttr(ratio.outColorR, target_vector.input2X) pm.connectAttr(ratio.outColorR, target_vector.input2Y) pm.connectAttr(ratio.outColorR, target_vector.input2Z) # Final World Position, sum of altered vectors. final_position = pm.createNode('plusMinusAverage', name='{}_sum_vectors'.format(self.name)) final_position.setAttr('operation', 1) # Sum pm.connectAttr(start_vector.output, final_position.input3D[0]) pm.connectAttr(target_vector.output, final_position.input3D[1]) # Compose Matrix compose_mtx = pm.createNode('composeMatrix', name='{}_final_ws_mtx'.format(self.name)) pm.connectAttr(final_position.output3D, compose_mtx.inputTranslate) # Matrix Multiplication Final * multiply_mtx = pm.createNode('multMatrix', name='{}_cnst_mtx'.format(self.name)) pm.connectAttr(compose_mtx.outputMatrix, multiply_mtx.matrixIn[0]) # Create a null Transform object which we will apply resulting matrix onto. driven = pm.group(empty=True, name='{}_driven_srtBuffer'.format(self.name)) pm.parent(driven, controller, relative=True) pm.parent(driven, world=True) pm.connectAttr(driven.parentInverseMatrix[0], multiply_mtx.matrixIn[1]) # Driven decomposed matrix result_mtx = pm.createNode('decomposeMatrix', name='{}_offset_mtx'.format(self.name)) pm.connectAttr(multiply_mtx.matrixSum, result_mtx.inputMatrix) pm.connectAttr(result_mtx.outputTranslate, driven.translate) # TODO temporary fix make something better... pm.parent(self.ikHandle, driven)
def orient(self): """ Set orientation for limb, blatantly taken method from Pedro Bellini show here: http://lesterbanks.com/2014/04/creating-aim-transformation-maya-python-api/ """ # TODO; avoid makeIdentity and solve using math. # Parent everything but top joint to world, pm.parent(self.joints[1:], world=True) pm.parent(self.children, world=True) # Get vectors for each joint to it's child in limb, aim_vectors = list() for index in range(len(self.joints[:-1])): p1 = self.joints[index].getAttr('worldMatrix').translate p2 = self.joints[index + 1].getAttr('worldMatrix').translate vector = (p2 - p1).normal() aim_vectors.append(vector) # For every two vectors we will get an up vectors from their cross product, up_vectors = list() for v, w in zip(aim_vectors[:-1], aim_vectors[1:]): up_vectors.append((v ^ w).normal()) # Extend the vector arrays, aim_vectors.append(aim_vectors[-1]) up_vectors.insert(0, up_vectors[0]) up_vectors.append(up_vectors[-1]) # For each joint, it's desired aim direction and up direction. for joint, aim, up in zip(self.joints, aim_vectors, up_vectors): # Zero out rotation and orient values for joint, pm.makeIdentity( joint, apply=True, jointOrient=True, rotate=True, ) # Define axis which are to be rotated into position, aim_axis = pm.dt.Vector.xAxis up_axis = pm.dt.Vector.zNegAxis side = (aim ^ up).normal() # Re-evaluate the up vector by taking the cross product of side and aim to get orthogonal vectors, up = (side ^ aim).normal() # Quaternion U describing the rotation to get from aim axis to aim vector, quat_u = pm.dt.Quaternion(aim_axis, aim) # Rotate the up axis with up_rotated = up_axis.rotateBy(quat_u) # Get the angle in radians between up vector and the rotated up vector, angle = math.acos(up_rotated * up) # Get Quaternion V describing angle radians around aim vector, quat_v = pm.dt.Quaternion(angle, aim) # Check rotation didn't go wrong way, if not up.isEquivalent(up_rotated.rotateBy(quat_v), 1.0e-5): angle = (2 * math.pi) - angle quat_v = pm.dt.Quaternion(angle, aim) # Set the final rotation Quaternion, and multiply the inverse of original orientation, final_rotation = quat_u * quat_v joint.setRotation(final_rotation) # Any rotation values will be baked into jointOrient attribute, pm.makeIdentity( joint, apply=True, r=True, ) # Re-parent children to previous parent, for parent, child in zip(self.joints[:-1], self.joints[1:]): pm.parent(child, parent) # And any orphan children as well. for child in self.children: pm.parent(child, self.joints[-1])
def clean_muscle(self): pm.parent(self.skeleton_grp, self.rig_grp) pm.parent(self.muscle_grp, self.rig_grp) pm.parent(self.loa_grp, self.rig_grp) pm.parent(self.zOut_grp, self.rig_grp) pm.rename(self.zMuscleCombined, 'zMuscleCombined_geo')
def clean_rig(self): self.jnt_input_grp.setAttr("visibility", 0) self.parts_grp.setAttr("visibility", 0) self.guides_grp.setAttr("visibility", 0) for loc in self.created_locs: loc_shape = loc.getShape() loc_shape.setAttr("visibility", 0) for ctrl in self.created_fk_ctrls: rig_lib.clean_ctrl(ctrl, 14, trs="ts") for ctrl in self.created_ik_ctrls: rig_lib.clean_ctrl(ctrl, 17, trs="s") rig_lib.clean_ctrl(self.created_pelvis_ctrl, 14, trs="t") if len(self.model.space_list) > 0: if self.model.ik_creation_switch == 0: self.created_fk_ctrls[-1].setAttr("space", len(self.model.space_list)) else: self.created_ik_ctrls[-1].setAttr("space", len(self.model.space_list)) info_crv = rig_lib.signature_shape_curve("{0}_INFO".format( self.model.module_name)) info_crv.getShape().setAttr("visibility", 0) info_crv.setAttr("hiddenInOutliner", 1) info_crv.setAttr("translateX", lock=True, keyable=False, channelBox=False) info_crv.setAttr("translateY", lock=True, keyable=False, channelBox=False) info_crv.setAttr("translateZ", lock=True, keyable=False, channelBox=False) info_crv.setAttr("rotateX", lock=True, keyable=False, channelBox=False) info_crv.setAttr("rotateY", lock=True, keyable=False, channelBox=False) info_crv.setAttr("rotateZ", lock=True, keyable=False, channelBox=False) info_crv.setAttr("scaleX", lock=True, keyable=False, channelBox=False) info_crv.setAttr("scaleY", lock=True, keyable=False, channelBox=False) info_crv.setAttr("scaleZ", lock=True, keyable=False, channelBox=False) info_crv.setAttr("visibility", lock=True, keyable=False, channelBox=False) info_crv.setAttr("overrideEnabled", 1) info_crv.setAttr("overrideDisplayType", 2) pmc.parent(info_crv, self.parts_grp) rig_lib.add_parameter_as_extra_attr(info_crv, "Module", "spine") rig_lib.add_parameter_as_extra_attr(info_crv, "parent_Module", self.model.selected_module) rig_lib.add_parameter_as_extra_attr(info_crv, "parent_output", self.model.selected_output) rig_lib.add_parameter_as_extra_attr(info_crv, "how_many_jnts", self.model.how_many_jnts) rig_lib.add_parameter_as_extra_attr(info_crv, "how_many_ctrls", self.model.how_many_ctrls) rig_lib.add_parameter_as_extra_attr(info_crv, "ik_creation", self.model.ik_creation_switch) rig_lib.add_parameter_as_extra_attr(info_crv, "stretch_creation", self.model.stretch_creation_switch) rig_lib.add_parameter_as_extra_attr(info_crv, "local_spaces", self.model.space_list) if not pmc.objExists("jnts_to_SKN_SET"): skn_set = pmc.createNode("objectSet", n="jnts_to_SKN_SET") else: skn_set = pmc.ls("jnts_to_SKN_SET", type="objectSet")[0] for jnt in self.jnts_to_skin: if type(jnt) == list: for obj in jnt: skn_set.add(obj) else: skn_set.add(jnt)
def create_local_spaces(self): spaces_names = [] space_locs = [] for space in self.model.space_list: name = str(space).replace("_OUTPUT", "") if "local_ctrl" in name: name = "world" spaces_names.append(name) if pmc.objExists("{0}_{1}_SPACELOC".format(self.model.module_name, name)): pmc.delete("{0}_{1}_SPACELOC".format(self.model.module_name, name)) space_loc = pmc.spaceLocator(p=(0, 0, 0), n="{0}_{1}_SPACELOC".format( self.model.module_name, name)) space_locs.append(space_loc) spaces_names.append("local") if len(self.model.space_list) > 0: if self.model.ik_creation_switch == 0: self.created_fk_ctrls[-1].addAttr("space", attributeType="enum", enumName=spaces_names, hidden=0, keyable=1) pmc.group(self.created_fk_ctrls[-1], p=self.created_fk_ctrls[-2], n="{0}_CONSTGRP".format(self.created_fk_ctrls[-1])) else: self.created_ik_ctrls[-1].addAttr("space", attributeType="enum", enumName=spaces_names, hidden=0, keyable=1) for i, space in enumerate(self.model.space_list): space_locs[i].setAttr( "translate", pmc.xform(self.created_spine_jnts[-1], q=1, ws=1, translation=1)) pmc.parent(space_locs[i], space) if self.model.ik_creation_switch == 0: fk_space_const = pmc.orientConstraint( space_locs[i], self.created_fk_ctrls[-1].getParent(), maintainOffset=1) rig_lib.connect_condition_to_constraint( "{0}.{1}W{2}".format(fk_space_const, space_locs[i], i), self.created_fk_ctrls[-1].space, i, "{0}_{1}Space_COND".format(self.created_fk_ctrls[-1], spaces_names[i])) else: ik_space_const = pmc.parentConstraint( space_locs[i], self.created_ik_ctrls[-1].getParent(), maintainOffset=1) rig_lib.connect_condition_to_constraint( "{0}.{1}W{2}".format(ik_space_const, space_locs[i], i), self.created_ik_ctrls[-1].space, i, "{0}_{1}Space_COND".format(self.created_ik_ctrls[-1], spaces_names[i]))
def FollicleByWorldPos(sources=None, surf=None, parent=True): if not (surf and sources): selectedObjs = pm.ls(sl=True) sources = pm.ls(selectedObjs[:-1]) surf = pm.ls(selectedObjs[-1]) else: sources = pm.ls(sources) surf = pm.ls(surf) surfShape = surf[0].getShape() folList = [] folShapeList = [] for source in sources: # create closet point on surface node # in order to find the U and V parameters on the surface for placing follicles #===================================================================== folWorldPos = pm.xform(source, q=True, t=True, ws=True) if surfShape.type() == 'mesh': pOnSurf = pm.createNode('closestPointOnMesh') surfShape.worldMatrix[0] >> pOnSurf.inputMatrix surfShape.worldMesh[0] >> pOnSurf.inMesh pOnSurf.inPosition.set(folWorldPos) uPos = (pOnSurf.result.parameterU.get()) vPos = (pOnSurf.result.parameterV.get()) U = uPos V = vPos elif surfShape.type() == 'nurbsSurface': pOnSurf = pm.createNode('closestPointOnSurface') surfShape.worldSpace >> pOnSurf.inputSurface pOnSurf.inPosition.set(folWorldPos) maxU = surfShape.minMaxRangeU.maxValueU.get() maxV = surfShape.minMaxRangeV.maxValueV.get() pOnSurf.inPosition.set(folWorldPos) uPos = (pOnSurf.result.parameterU.get()) vPos = (pOnSurf.result.parameterV.get()) # U and V parameters are not normalized so we have to calcutate them U = uPos / maxU V = vPos / maxV # now that we have U and V parameters, we can create folliclethe node #===================================================================== folShape = pm.createNode('follicle') folShape.parameterU.set(U) folShape.parameterV.set(V) fol = folShape.getParent() pm.rename(fol, '%s_flc' % source.name()) if surfShape.type() == 'mesh': surfShape.outMesh >> folShape.inputMesh surfShape.worldMatrix[0] >> folShape.inputWorldMatrix elif surfShape.type() == 'nurbsSurface': surfShape.local >> folShape.inputSurface surfShape.worldMatrix[0] >> folShape.inputWorldMatrix folShape.outRotate >> fol.rotate folShape.outTranslate >> fol.translate folList.append(fol) folShapeList.append(folShape) # now that we've created follicle we can clean up extra nodes. pm.delete(pOnSurf) if parent: pm.parent(source, fol) return (folList, folShapeList)
def buildSplineChest(start, end, name='Chest', indexOfRibCage=-1, useTrueZero=True, groupName='', controlSpec={}): ''' Makes a spline from the start to the `indexOfRibCage` joint, and TODO - the remaining joints get fk controllers (so you can make the spine and neck all one card, I guess) ''' srcChain = util.getChain(start, end) chain = util.dupChain(start, end, '{0}_spline') chestBase = chain[indexOfRibCage] chestIndex = chain.index(chestBase) if chestIndex % 2 == 0: # Due to `division`, have to cast to int midPos = xform(chain[int(chestIndex / 2)], q=True, ws=True, t=True) midRot = xform(chain[int(chestIndex / 2)], q=True, ws=True, ro=True) else: tempIndex = int(math.floor(chestIndex / 2)) low = chain[tempIndex] high = chain[tempIndex + 1] midPos = dt.Vector(xform(low, q=True, ws=True, t=True)) midPos += dt.Vector(xform(high, q=True, ws=True, t=True)) midPos = dt.Vector(midPos) * .5 '''&&& To be safe, find the closest axis on the second obj Get average z basis, forward then average y basis, up calc x, side recalc y, up This is the world matrix of the average rotation''' midRot = xform(low, q=True, ws=True, ro=True) #raise Exception('Need to implement even number of stomach joints') container = group(em=True, p=node.mainGroup(), n=name + "_controls") container.inheritsTransform.set(False) container.inheritsTransform.lock() chain[0].setParent(container) mainIk, _effector, crv = ikHandle(sol='ikSplineSolver', sj=chain[0], ee=chestBase, ns=3, simplifyCurve=False) crvShape = crv.getShape() crvShape.overrideEnabled.set(True) crvShape.overrideDisplayType.set(2) parent(mainIk, crv, container) # -- Base -- # I don't think there is any benefit to controlling this, but it might just be my weighting. base = joint(None, n='Base') pdil.dagObj.moveTo(base, chain[0]) base.setParent(container) parentConstraint(start.getParent(), base, mo=True) hide(base) # -- Chest control -- chestCtrl = controllerShape.build(name + '_main', controlSpec['main'], controllerShape.ControlType.SPLINE) chestCtrl.setParent(container) util.makeStretchySpline(chestCtrl, mainIk) chestCtrl.stretch.set(1) chestCtrl.stretch.lock() chestCtrl.stretch.setKeyable(False) pdil.dagObj.lock(chestCtrl, 's') # Put pivot point at the bottom chestCtrl.ty.set(chestCtrl.boundingBox()[1][1]) pdil.sharedShape.remove(chestCtrl, visNode.VIS_NODE_TYPE) chestCtrl.setPivots([0, 0, 0], worldSpace=True) makeIdentity(chestCtrl, a=True, t=True) pdil.sharedShape.use(chestCtrl, visNode.get()) move(chestCtrl, xform(chestBase, q=True, ws=True, t=True), rpr=True) pdil.dagObj.zero(chestCtrl) if useTrueZero: rot = util.determineClosestWorldOrient(chestBase) util.storeTrueZero(chestCtrl, rot) pdil.dagObj.rezero( chestCtrl ) # Not sure why this is needed but otherwise the translate isn't zeroed chestCtrl.r.set(rot) chest = joint(None, n='Chest') chest.setParent(chestCtrl) pdil.dagObj.moveTo(chest, chestBase) pdil.dagObj.lock(chest) hide(chest) chestMatcher = util.createMatcher(chestCtrl, srcChain[chestIndex]) chestMatcher.setParent(container) # Chest spaces need to happen after it's done being manipulated into place space.add(chestCtrl, start.getParent(), 'local') space.add(chestCtrl, start.getParent(), 'local_posOnly', mode=space.Mode.TRANSLATE) space.addMain(chestCtrl) # Not sure this space is useful... space.addTrueWorld(chestCtrl) space.add(chestCtrl, start.getParent(), 'worldRotate', mode=space.Mode.ALT_ROTATE, rotateTarget=find.mainGroup()) # -- Chest Offset -- &&& Currently hard coded to make a single offset joint chestOffsetCtrl = None if chestIndex < (len(chain) - 1): chestOffsetCtrl = controllerShape.build( name + '_bend', controlSpec['offset'], controllerShape.ControlType.SPLINE) chestOffsetCtrl.setParent(chestCtrl) pdil.dagObj.matchTo(chestOffsetCtrl, chain[-1]) #move(chestOffsetCtrl, [0, 0.7, 3], r=True) pdil.dagObj.zero(chestOffsetCtrl) pdil.dagObj.lock(chestOffsetCtrl, 's') parentConstraint(chestOffsetCtrl, chain[-1], mo=True) # -- Mid -- midCtrl = controllerShape.build(name + '_mid', controlSpec['middle'], controllerShape.ControlType.SPLINE) #pdil.dagObj.matchTo( midCtrl, midPoint ) xform(midCtrl, ws=True, t=midPos) pdil.dagObj.lock(midCtrl, 's') midCtrl.setParent(container) mid = joint(None, n='Mid') #pdil.dagObj.moveTo( mid, midPoint ) xform(mid, ws=True, t=midPos) mid.setParent(midCtrl) pdil.dagObj.lock(mid) hide(mid) # Mid control's rotation aims at the chest pdil.dagObj.zero(midCtrl) aimer = util.midAimer(base, chestCtrl, midCtrl) aimer.setParent(container) hide(aimer) space.add(midCtrl, aimer, spaceName='default') userDriven = space.addUserDriven( midCtrl, 'extreme') # Best name I got, extreme poses! parentConstraint(base, chestCtrl, userDriven, mo=True, skipRotate=('x', 'y', 'z')) orientConstraint(base, chestCtrl, userDriven, mo=True) """ # -- Shoulders -- if numChestJoints > 2: # The shoulder control is skipped if there aren't enough joints shoulderCtrl = controllerShape.build( name + '_shoulders', controlSpec['end'], controllerShape.ControlType.SPLINE ) pdil.dagObj.matchTo( shoulderCtrl, srcChain[-2]) # We want to use the penultimate joint orientation pdil.dagObj.moveTo( shoulderCtrl, end) controllerShape.scaleAllCVs( shoulderCtrl, x=0.15 ) shoulderZero = pdil.dagObj.zero(shoulderCtrl) shoulderZero.setParent(chestCtrl) pdil.dagObj.lock(shoulderCtrl, 't s') neck = joint(None, n='Neck') neck.setParent( shoulderCtrl ) pdil.dagObj.moveTo( neck, end ) pdil.dagObj.lock(neck) hide(neck) # -- Neck -- neckCtrl = controllerShape.build( name + '_neck', controlSpec['neck'], controllerShape.ControlType.ROTATE ) pdil.dagObj.matchTo( neckCtrl, end) if numChestJoints > 2: # The shoulder control is skipped if there aren't enough joints pdil.dagObj.zero(neckCtrl).setParent( shoulderCtrl ) pdil.dagObj.lock(neckCtrl, 's t') space.add( neckCtrl, srcChain[-2], 'chest' ) else: pdil.dagObj.zero(neckCtrl).setParent( chestCtrl ) pdil.dagObj.lock(neckCtrl, 't s') space.add( neckCtrl, chestCtrl, 'chest' ) space.addMain(neckCtrl) """ # Constrain to spline proxy, up to the chest... constraints = [] for src, dest in list(zip(chain, srcChain))[:chestIndex]: constraints.append(pdil.constraints.pointConst(src, dest)) constraints.append(pdil.constraints.orientConst(src, dest)) # ... including the chest src = chain[chestIndex] dest = srcChain[chestIndex] # &&& Gotta remove/figure out what is going on here, why can't I just constrain entirely the srcChain to it's dup'd chain? if False: # numChestJoints > 2: # The shoulder control is skipped if there aren't enough joints constraints.append(pdil.constraints.pointConst(src, dest)) constraints.append(pdil.constraints.orientConst(src, dest)) # ... not including the chest else: chestProxy = duplicate(src, po=True)[0] chestProxy.setParent(chestCtrl) constraints.append(pdil.constraints.pointConst(chestProxy, dest)) constraints.append(pdil.constraints.orientConst(chestProxy, dest)) hide(chestProxy) if chestOffsetCtrl: constraints.append(pdil.constraints.pointConst(chain[-1], srcChain[-1])) constraints.append( pdil.constraints.orientConst(chain[-1], srcChain[-1])) #constraints.append( pdil.constraints.pointConst( neckCtrl, srcChain[-1] ) ) #constraints.append( pdil.constraints.orientConst( neckCtrl, srcChain[-1] ) ) """ if numChestJoints > 2: # The shoulder control is skipped if there aren't enough joints # Make a proxy since we can't constrain with maintainOffset=True if we're making fk too. proxy = duplicate(srcChain[-2], po=True)[0] proxy.setParent(neck) pdil.dagObj.lock(proxy) constraints.append( pdil.constraints.pointConst( proxy, srcChain[-2] ) ) constraints.append( pdil.constraints.orientConst( proxy, srcChain[-2] ) ) """ hide(chain, mainIk) # Bind joints to the curve if False: # numChestJoints > 2: # The shoulder control is skipped if there aren't enough joints skinCluster(crv, base, mid, chest, neck, tsb=True) else: skinCluster(crv, base, mid, chest, tsb=True) chestCtrl = pdil.nodeApi.RigController.convert(chestCtrl) chestCtrl.container = container chestCtrl.subControl['mid'] = midCtrl if chestOffsetCtrl: chestCtrl.subControl['offset'] = chestOffsetCtrl #if numChestJoints > 2: # The shoulder control is skipped if there aren't enough joints # chestCtrl.subControl['offset'] = shoulderCtrl #chestCtrl.subControl['neck'] = neckCtrl # Setup advanced twist startAxis = duplicate(start, po=True)[0] startAxis.rename('startAxis') startAxis.setParent(base) pdil.dagObj.lock(startAxis) endAxis = duplicate(start, po=True)[0] endAxis.rename('endAxis') endAxis.setParent(chestCtrl) endAxis.t.set(0, 0, 0) pdil.dagObj.lock(endAxis) hide(startAxis, endAxis) mainIk.dTwistControlEnable.set(1) mainIk.dWorldUpType.set(4) startAxis.worldMatrix[0] >> mainIk.dWorldUpMatrix endAxis.worldMatrix[0] >> mainIk.dWorldUpMatrixEnd hide(startAxis, endAxis) return chestCtrl, constraints '''
def CreateNodes(self): """Creation et settings de mes nodes""" def createloc(sub): """Creates locator at the Pivot of the object selected """ locs = [] for sel in sub: loc_align = pm.spaceLocator(n='{}__pos_loc__'.format(sel)) locs.append(loc_align) pm.matchTransform(loc_align, sel, rot=True, pos=True) pm.select(locs, add=True) return locs self.CurveInfoNode = None posLocs = [] if self.usingCurve: self.spineLenghtCurve = adb.createCurveFrom(self.jointList, curve_name='{}_lenght__CRV'.format(self.NAME)) pm.parent(self.spineLenghtCurve, self.RIG_GRP) self.CurveInfoNode = pm.shadingNode('curveInfo', asUtility=1, n='{}_CurveInfo'.format(self.NAME)) else: posLocs = createloc([self.jointList[0], self.jointList[-1]]) sp = (pm.PyNode(posLocs[0]).translateX.get(), pm.PyNode(posLocs[0]).translateY.get(), pm.PyNode(posLocs[0]).translateZ.get()) ep = (pm.PyNode(posLocs[1]).translateX.get(), pm.PyNode(posLocs[1]).translateY.get(), pm.PyNode(posLocs[1]).translateZ.get()) # create Distances Nodes self.DistanceLoc = pm.distanceDimension(sp=sp, ep=ep) pm.rename(self.DistanceLoc, 'bendy_distDimShape') pm.rename(pm.PyNode(self.DistanceLoc).getParent(), 'bendy_distDim') distance = self.DistanceLoc.distance.get() pm.parent(self.DistanceLoc.getParent(), self.RIG_GRP) pm.parent(posLocs[0], self.ribbon_ctrl[0]) pm.parent(posLocs[1], self.ribbon_ctrl[1]) pm.rename(posLocs[0], 'distance_depart__{}'.format(NC.LOC)) pm.rename(posLocs[1], 'distance_end__{}'.format(NC.LOC)) posLocs[0].v.set(0) posLocs[1].v.set(0) self.DistanceLoc.getParent().v.set(0) # Creation des nodes Multiply Divide self.Stretch_MD = pm.shadingNode('multiplyDivide', asUtility=1, n="StretchMult") self.Squash_MD = pm.shadingNode('multiplyDivide', asUtility=1, n="SquashMult") self.expA_MD = pm.shadingNode('multiplyDivide', asUtility=1, n="{}_ExpA".format(self.NAME)) self.expB_MD = pm.shadingNode('multiplyDivide', asUtility=1, n="{}_ExpB".format(self.NAME)) self.expC_MD = pm.shadingNode('multiplyDivide', asUtility=1, n="{}_ExpC".format(self.NAME)) # blendColor node Toggle self.toggle_node = pm.shadingNode('blendColors', asUtility=1, n='{}_Toggle__{}'.format(self.NAME, NC.BLENDCOLOR_SUFFIX)) self.toggle_node.blender.set(1) # Settings des nodes Multiply Divide self.Stretch_MD.operation.set(2) self.Squash_MD.operation.set(2) self.expA_MD.operation.set(3) self.expA_MD.input1X.set(1) self.expB_MD.operation.set(3) self.expB_MD.input1X.set(1) self.expC_MD.operation.set(3) self.expC_MD.input1X.set(1) return self.expA_MD, self.expB_MD, self.expC_MD, self.Squash_MD, self.Stretch_MD, self.CurveInfoNode, posLocs
def controlShapeAdaptive(controlList, geoList, ctrlSmooth=6, scaleConstant=1.5, rebuildCV=32): adaptiveShapeBuildGrp = pm.group(n='daptiveShapeBuild_GRP', em=True) geoList = pm.ls(geoList) dupliGeo = pm.duplicate(geoList) geoCombined = pm.polyUnite(dupliGeo, ch=False, name='tmpAdaptiveRef_GEO')[0] pm.parent(geoCombined, adaptiveShapeBuildGrp) ctrlList = pm.ls(controlList) for ctrl in ctrlList: ctrlShapeBuildGrp = pm.group(n=ctrl.name() + '_GRP', em=True, p=adaptiveShapeBuildGrp) dupliCtrl = pm.duplicate(ctrl, n='tmpCtrl')[0] pm.delete(pm.ls(dupliCtrl, dagObjects=True, exactType='transform')[1:]) pm.rebuildCurve(dupliCtrl, ch=False, s=rebuildCV) pm.parent(dupliCtrl, ctrlShapeBuildGrp) # extrusion extrudeCircle = pm.circle(r=0.1, ch=0)[0] pm.parent(extrudeCircle, ctrlShapeBuildGrp) motionPathNode = \ pm.ls(pm.pathAnimation(extrudeCircle, curve=dupliCtrl, fractionMode=True, follow=True, followAxis='z', upAxis='y', worldUpType='vector', worldUpVector=[0, 1, 0], inverseUp=False, inverseFront=False, bank=False))[0] pm.disconnectAttr(extrudeCircle.tx) pm.disconnectAttr(extrudeCircle.ty) pm.disconnectAttr(extrudeCircle.tz) pm.disconnectAttr(extrudeCircle.rx) pm.disconnectAttr(extrudeCircle.ry) pm.disconnectAttr(extrudeCircle.rz) pm.disconnectAttr(motionPathNode.u) pm.delete(motionPathNode) extrudedSurface = \ pm.extrude(extrudeCircle, dupliCtrl, ch=False, rn=False, po=0, et=2, ucp=0, fpt=1, upn=0, rotation=0, scale=1, rsp=1)[0] pm.parent(extrudedSurface, ctrlShapeBuildGrp) nurbsToPoly = pm.nurbsToPoly(extrudedSurface, ch=False, polygonType=1, chr=0.9) pm.parent(nurbsToPoly, ctrlShapeBuildGrp) # add deformer wrapNode = deform.wrapDeformer(dupliCtrl, nurbsToPoly) shrinkWrapNode = deform.shrinkWrapDeformer(nurbsToPoly, geoCombined) shrinkWrapNode.projection.set(4) shrinkWrapNode.targetSmoothLevel.set(ctrlSmooth) # delete history common.deleteHistory(nurbsToPoly) common.deleteHistory(dupliCtrl) pm.scale(dupliCtrl.cv[:], [scaleConstant, scaleConstant, scaleConstant]) copyShape(dupliCtrl, ctrl) pm.delete(adaptiveShapeBuildGrp)
def setFinal_hiearchy(self): self.Do_not_touch_grp = pm.group(n=NC.NO_TOUCH, em=1, parent=self.RIG_GRP) pm.parent(self.scale_grp, self.Do_not_touch_grp)
def create(name=None, offsets=2, shape=None, size=None, color=None, switch=None, pos=None, parent=None, typ=None, rot=None): ''' name: String: Control name. Ex: "LeftUpLeg_ctrl" offsets: Int: Number of offset groups shape: String: Name of control curve .ma file. Ex: 'arrow_01' size: [x,y,z]: Scale for control color: Int: Index of color in Names.controls_color. pos: [x,y,z]: Final translational offset added to top group of control parent: String: Name of parent object for control typ: String: Control type: "body", "head" switch: [ [objects], [names], type ]: objects: List of objects to constrain to, names: Name of weight switching attributes, title: "space" or "orient" ''' pymelLogger.debug('Starting: create()...') # Import crv = importCurve(shape) if not crv: return False # rename (verify name?) crv.rename(name) # Color try: cID = Names.controls_color[color] except: cID = 17 # yellow crv.setAttr('overrideEnabled', 1) crv.setAttr('overrideColor', cID) # Position, Group, Parent # pos = [x,y,z] grpList = [] if offsets: index = 0 for offsetName in Names.offset_names: if index == offsets: continue grp = pm.group(em=1, name=crv.name() + '_' + offsetName) grpList.append(grp) index += 1 # parent groups grpList.reverse() last = '' for element in grpList: if last: last.setParent(element) last = element # position top grp null #if pos: # last.setTranslation(pos) # parent curve to last grp crv.setParent(grpList[0]) # Parent if parent: pm.delete(pm.parentConstraint(parent, grpList[-1])) pm.parent(grpList[-1], parent) # pos = [x,y,z] if pos: if not len(grpList) == 0: grpList[-1].setTranslation(pos, space='world') else: crv.setTranslation(pos, space='world') if rot: if not len(grpList) == 0: grpList[-1].setRotation(rot, space='world') else: crv.setRotation(rot, space='world') if size: if not isinstance(size, list): size = [size, size, size] if not len(grpList) == 0: grpList[-1].setScale(size) else: crv.setScale(size) # Register RegisterControl.register(control=crv, name=name, typ=typ) # Switch if switch: if offsets < 2: raise Exception( "Need to use at least two offsets to use space switching.") Switch.create(control=crv, constObj=grpList[-2], objects=switch[0], names=switch[1], typ=switch[2]) pymelLogger.debug('End: create()...') if len(grpList) == 0: return crv else: return grpList[-1]
def pip(): toParent = pm.selected()[-1].listRelatives(p=1)[0] pm.parent(pm.selected()[:-10], )
def clean_rig(self): self.guides_grp.setAttr("visibility", 0) for i, fol in enumerate(self.follicles): fol.getShape().setAttr("visibility", 0) if fol.getAttr("translateX") > 0.02: color_value = 6 elif fol.getAttr("translateX") < -0.02: color_value = 13 else: color_value = 14 rig_lib.clean_ctrl(self.ctrls[i], color_value, trs="s") rig_lib.clean_ctrl(self.ctrls[i].getParent(), color_value, trs="trs") rig_lib.clean_ctrl(self.ctrls[i].getParent().getParent(), color_value, trs="trs") info_crv = rig_lib.signature_shape_curve("{0}_INFO".format( self.model.module_name)) info_crv.getShape().setAttr("visibility", 0) info_crv.setAttr("hiddenInOutliner", 1) info_crv.setAttr("translateX", lock=True, keyable=False, channelBox=False) info_crv.setAttr("translateY", lock=True, keyable=False, channelBox=False) info_crv.setAttr("translateZ", lock=True, keyable=False, channelBox=False) info_crv.setAttr("rotateX", lock=True, keyable=False, channelBox=False) info_crv.setAttr("rotateY", lock=True, keyable=False, channelBox=False) info_crv.setAttr("rotateZ", lock=True, keyable=False, channelBox=False) info_crv.setAttr("scaleX", lock=True, keyable=False, channelBox=False) info_crv.setAttr("scaleY", lock=True, keyable=False, channelBox=False) info_crv.setAttr("scaleZ", lock=True, keyable=False, channelBox=False) info_crv.setAttr("visibility", lock=True, keyable=False, channelBox=False) info_crv.setAttr("overrideEnabled", 1) info_crv.setAttr("overrideDisplayType", 2) pmc.parent(info_crv, self.parts_grp) rig_lib.add_parameter_as_extra_attr(info_crv, "Module", "blendshapes_ctrls") rig_lib.add_parameter_as_extra_attr(info_crv, "mesh_to_follow", self.model.mesh_to_follow) rig_lib.add_parameter_as_extra_attr(info_crv, "how_many_ctrls", self.model.how_many_ctrls)
def trapeziumCtrlShape(name, normalDirection=[0, 0, 0], scale=1): pm.mel.eval('softSelect -sse off;') bottomSquare = pm.nurbsSquare(c=[0, 0, 0], nr=[0, 1, 0], d=1, ch=False) topSquare = pm.nurbsSquare(c=[0, 1, 0], nr=[0, 1, 0], d=1, ch=False) leftSquare = pm.nurbsSquare(c=[-0.5, 0.5, 0], nr=[1, 0, 0], d=1, ch=False) rightSquare = pm.nurbsSquare(c=[0.5, 0.5, 0], nr=[1, 0, 0], d=1, ch=False) squareList = [bottomSquare, topSquare, leftSquare, rightSquare] for square in squareList: segmentList = pm.listRelatives(square, ad=1, type='transform') pm.attachCurve(segmentList[0], segmentList[1], ch=False, rpo=True, kmk=False, m=0, bb=0, bki=False, p=0.1) pm.attachCurve(segmentList[2], segmentList[3], ch=False, rpo=True, kmk=False, m=0, bb=0, bki=False, p=0.1) pm.attachCurve(segmentList[0], segmentList[2], ch=False, rpo=True, kmk=False, m=0, bb=0, bki=False, p=0.1) pm.delete(segmentList[1:]) cubePartsShape = [ pm.listRelatives(square, ad=1, type='transform')[0].getShape() for square in squareList ] for shape in cubePartsShape: pm.parent(shape, cubePartsShape[0].getParent(), r=1, s=1) # scale upper Box ctrl = pm.listRelatives(bottomSquare, ad=1, type='transform')[0] pm.parent(ctrl, w=True) pm.delete(squareList) ctrlShapesList = ctrl.getShapes() for shape in ctrlShapesList: pm.rebuildCurve(shape, ch=False, rpo=True, rt=1, end=1, kr=0, kcp=False, kep=True, kt=False, s=0, d=1, tol=0.01) vertSelection = pm.select(ctrlShapesList[3].cv[0:1], ctrlShapesList[1].cv[0:3], ctrlShapesList[2].cv[0:1]) pm.scale(vertSelection, [0.5, 0.5, 0.5], r=True) allVertSelection = pm.select([shape.cv[:] for shape in ctrlShapesList]) pm.scale(allVertSelection, [4, 1, 1], r=True) pm.select(cl=True) if normalDirection[0] == 1: pm.rotate(ctrl, [90, 0, 0]) elif normalDirection[0] == -1: pm.rotate(ctrl, [-90, 0, 0]) if normalDirection[1] == 1: pm.rotate(ctrl, [0, 90, 0]) elif normalDirection[1] == -1: pm.rotate(ctrl, [0, -90, 0]) if normalDirection[2] == 1: pm.rotate(ctrl, [0, 0, 90]) elif normalDirection[2] == -1: pm.rotate(ctrl, [0, 0, -90]) pm.rename(ctrl, name) ctrl.scale.set(scale, scale, scale) common.freezeTranform(ctrl) return ctrl
def rigDazFigure( name, path='C:/Users/Darrick/Documents/Maya/projects/_UE4-Chars/scenes'): """Need to load DAZ FBX first""" figure = getFigureName() # File paths mesh_path = '{0}/Mesh/Ref/Mesh_{1}.ma'.format(path, name) rig_path = '{0}/Rig/Ref/Rig_{1}.ma'.format(path, name) skel_path = '{0}/Rig/Ref/Skel_{1}.ma'.format(path, name) anim_path = '{0}/Rig/Ref/AnimRig_{1}.mb'.format(path, name) # Build and save meshes print('Converting DAZ figure geometry:') buildDazMeshes() print('Exporting geometry...') meshes = pm.ls(('*Mesh', '*Morphs'), type='transform', r=True) face_sets = pm.ls('Fac*', recursive=True) pm.select(meshes + face_sets, ne=True) pm.exportSelected(mesh_path, force=True) print('Geometry exported to {}'.format(mesh_path)) # Load and setup AS5 skeleton print('Loading and setting up AS5 skeleton...') as5util.preBuild(figure, load=True) # Edit joint placement, if necessary # Remove shading face sets from namespaces so they don't get deleted for sel_set in pm.ls('Fac*', recursive=True): pm.rename(sel_set, sel_set.name().split(':')[1]) # Delete geometry + namespaces for name_space in 'HeadGeo', 'BodyGeo': pm.namespace(rm=name_space, deleteNamespaceContent=True) # Reference geometry pm.createReference(mesh_path, defaultNamespace=True) # Build AS5 rig print('Building AS5 rig...') pm.mel.eval( 'source "C:/Users/Darrick/Documents/Maya/scripts/AdvancedSkeleton5.mel";' ) pm.mel.eval('asBuildAdvancedSkeleton();') print('Executing post-build script...') as5util.postBuild(figure) pm.mel.eval('asSetBuildPose("");') # Skin mesh and apply blendshapes print('Skinning geometry and applying weight drivers...') applySkins() # Add to layers, cleanup print('Cleaning up...') layer = pm.ls('GeoLayer')[0] if pm.ls( 'GeoLayer') else pm.createDisplayLayer(name='GeoLayer') layer.displayType.set(2) for grp in pm.ls(('Mesh', 'Morphs'), r=True): grp.setParent('Geometry') layer.addMembers(grp) pm.delete('Genesis8*') for grp in 'Geometry', 'DeformationSystem': pm.parent(grp, None) # Export skeleton print('Exporting skeleton to {}'.format(skel_path)) pm.select('DeformationSystem', r=True) pm.exportSelected(skel_path, force=True, channels=False) # Save rig file print('Saving rig file to {}'.format(rig_path)) pm.saveAs(rig_path) print('Saving animRig file to {}'.format(anim_path)) refs = pm.ls(type='reference') for ref in refs: file_ref = pm.FileReference(ref) file_ref.importContents() pm.saveAs(anim_path) pm.openFile(rig_path, force=True) print('Conversion complete.')
def nurbsToPolySp(*args, **kwds): """ nurbsToPolySp v0.0.1 - Select nurbsSurface or transform what have nurbsSurfaces before execute this function. - Converted polygon's name will change to nurbsSurface's name. - NurbsSurface's name will add prefix and add suffix. - Converted polygon parent will nurbsSurface's parent. - Converted polygon's polygonType to Quads. - Converted polygon's tessellate will nurbsSurface's matchRenderTesselation. """ # get options from args. selected = False before_sels = None if len(args) > 0: sels = pm.ls(args) before_sels = pm.ls(sl=True) else: sels = pm.ls(sl=True) selected = True if 1 > len(sels): raise Exception( u'Please select one or more what is group have nurbsSurface.') # get options from kwds. if u'prefix' in kwds: prefix = kwds[u'prefix'] else: prefix = u'' if u'suffix' in kwds: suffix = kwds[u'suffix'] else: suffix = u'Nrb' # main compute. message = [] for sel in sels: nurbs_shapes = pm.listRelatives(sel, allDescendents=True, type=u'nurbsSurface') if 1 > len(nurbs_shapes): message.append(u'{0} have not nurbsSurface. skipped.'.format(sel)) continue for nurbs_shape in nurbs_shapes: mesh_name = pm.nurbsToPoly(nurbs_shape, matchRenderTessellation=True, constructionHistory=True) mesh = pm.ls(mesh_name)[0] mesh_shape = mesh.getShape() tessellate = mesh_shape.inputs()[0] tessellate.setAttr('polygonType', lock=False) tessellate.setAttr('polygonType', 1) nurbs = nurbs_shape.getParent() nurbs_parent = nurbs.getParent() if nurbs_parent is not None: pm.parent(mesh, nurbs_parent) name = nurbs.name() pm.rename(nurbs, prefix + name + suffix) message.append(u'NurbsSurface renamed: "{0}" -> "{1}"'.format( name, prefix + name + suffix)) pm.rename(mesh, name) message.append(u'Create polygon mesh:"{0}"'.format(name)) if selected: pm.select(sels) else: pm.select(before_sels) print '\n'.join(message) print u'Finished nurbsToPolySp!!'
def marge_run(self): objects = common.search_polygon_mesh(self.objects, serchChildeNode=True, fullPath=True) #print 'marge target :', objects if len(objects) < 2: self.marged_mesh = objects return True skined_list = [] no_skin_list = [] parent_list = [ cmds.listRelatives(obj, p=True, f=True) for obj in objects ] for obj in objects: skin = cmds.ls(cmds.listHistory(obj), type='skinCluster') if skin: skined_list.append(obj) else: no_skin_list.append(obj) if no_skin_list and skined_list: skined_mesh = skined_list[0] for no_skin_mesh in no_skin_list: weight.transfer_weight(skined_mesh, no_skin_mesh, transferWeight=False, returnInfluences=False, logTransfer=False) if skined_list: marged_mesh = pm.polyUniteSkinned(objects)[0] pm.polyMergeVertex(marged_mesh, d=0.001) target_mesh = pm.duplicate(marged_mesh)[0] weight.transfer_weight(str(marged_mesh), str(target_mesh), transferWeight=True, returnInfluences=False, logTransfer=False) else: marged_mesh = pm.polyUnite(objects, o=True)[0] pm.polyMergeVertex(marged_mesh, d=0.001) target_mesh = pm.duplicate(marged_mesh)[0] #pm.delete(objects) for obj in objects: if pm.ls(obj): pm.delete(obj) pm.delete(marged_mesh) all_attr_list = [['.sx', '.sy', '.sz'], ['.rx', '.ry', '.rz'], ['.tx', '.ty', '.tz']] for p_node in parent_list: if cmds.ls(p_node, l=True): all_lock_list = [] for attr_list in all_attr_list: lock_list = [] for attr in attr_list: lock_list.append( pm.getAttr(target_mesh + attr, lock=True)) pm.setAttr(target_mesh + attr, lock=False) all_lock_list.append(lock_list) pm.parent(target_mesh, p_node[0]) for lock_list, attr_list in zip(all_lock_list, all_attr_list): for lock, attr in zip(lock_list, attr_list): #continue #print 'lock attr :', lock, target_mesh, attr pm.setAttr(target_mesh + attr, lock=lock) break pm.rename(target_mesh, objects[0]) pm.select(target_mesh) self.marged_mesh = str(target_mesh) return True
def create_ctrls(self): self.ctrls = [] for fol in self.follicles: pmc.select(clear=1) ctrl_shape = pmc.circle(c=(0, 0, 0), nr=(0, 0, 1), sw=360, r=1, d=3, s=8, n=str(fol).replace("_FOL", "_ctrl_Shape"), ch=0)[0] ctrl = rig_lib.create_jnttype_ctrl(name=str(fol).replace( "_FOL", "_CTRL"), shape=ctrl_shape) pmc.select(clear=1) ctrl_ofs = pmc.joint(p=(0, 0, 0), n=str(ctrl).replace("_CTRL", "_ctrl_OFS")) ctrl_ofs.setAttr("drawStyle", 2) ctrl_fix_r = pmc.joint(p=(0, 0, 0), n=str(ctrl).replace("_CTRL", "_ctrl_rotate_FIX")) ctrl_fix_r.setAttr("drawStyle", 2) ctrl_fix_r.setAttr("rotateOrder", 5) ctrl_fix_t = pmc.joint(p=(0, 0, 0), n=str(ctrl).replace("_CTRL", "_ctrl_translate_FIX")) ctrl_fix_t.setAttr("drawStyle", 2) pmc.parent(ctrl, ctrl_fix_t) pmc.parent(ctrl_ofs, fol) ctrl_ofs.setAttr("translate", (0, 0, 0)) ctrl_ofs.setAttr("rotate", (0, 0, 0)) ctrl_ofs.setAttr("jointOrient", (0, 0, 0)) invert_ctrl_translate = pmc.createNode("multiplyDivide", n=str(ctrl) + "invert_translate_MDL") invert_ctrl_rotate = pmc.createNode("multiplyDivide", n=str(ctrl) + "invert_rotate_MDL") ctrl.translate >> invert_ctrl_translate.input1 invert_ctrl_translate.setAttr("input2", (-1, -1, -1)) invert_ctrl_translate.output >> ctrl_fix_t.translate ctrl.rotate >> invert_ctrl_rotate.input1 invert_ctrl_rotate.setAttr("input2", (-1, -1, -1)) invert_ctrl_rotate.output >> ctrl_fix_r.rotate ctrl_cvs = ctrl.cv[:] for i, cv in enumerate(ctrl_cvs): pmc.xform(ctrl.getShape().controlPoints[i], translation=(pmc.xform(cv, q=1, translation=1)[0], pmc.xform(cv, q=1, translation=1)[1], pmc.xform(cv, q=1, translation=1)[2] + 1)) self.ctrls.append(ctrl)
def bdRigEye(self): # create IK handles for the bind joints, for now getting the joints based on the name parts = [] if self.templateSide == 'both': parts = ['left', 'right'] else: parts = [self.templateSide] for side in parts: eyeLidsJnt = pm.ls(side + '*eyelid_*_01_jnt') eyeJoint = pm.ls(side + "*eye*jnt")[0] eyeCorners = pm.ls(side + "*eye*corner*01_jnt") eyeAnim = pm.ls(side + '_eye_anim') pm.select(cl=True) eyeAnimGrp = pm.group(n=side + '_eyelids_anim_GRP') pm.select(cl=True) pm.aimConstraint(eyeAnim[0], eyeJoint, offset=[0, 0, 0], weight=1, aimVector=[0, 0, 1], upVector=[0, 1, 0], worldUpType="vector", worldUpVector=[0, 1, 0]) blinkUpJnt = pm.duplicate(eyeJoint, name=side + '_eyelid_upper_blink_jnt', po=True) blinkLowJnt = pm.duplicate(eyeJoint, name=side + '_eyelid_lower_blink_jnt', po=True) baseLidsJnt = pm.ls(side + '*lids*base') pm.parent([blinkUpJnt[0], blinkLowJnt[0]], baseLidsJnt[0]) for joint in (eyeLidsJnt + eyeCorners): endJoint = pm.listRelatives(joint, c=True, type='joint') ikName = endJoint[0].name().replace('02_bnd_jnt', 'ikHandle') ctrlName = endJoint[0].name().replace('02_bnd_jnt', 'anim') bdRigUtils.bdAddIk(joint.name(), endJoint[0].name(), 'ikSCsolver', ikName) eyelidAnim, eyelidAnimGrp = bdRigUtils.bdBuildSquareController( endJoint[0].name(), ctrlName, 0.2) pm.parent(eyelidAnimGrp, eyeAnimGrp) # bdRigUtils.bdBuildBoxController(endJoint[0].name(),ctrlName,0.2) if 'corner' not in ctrlName: bdRigUtils.bdAddAttributeMinMax(ctrlName, ['BlinkPosition'], 'double', -5, 5, 1) pm.parent(ikName, ctrlName) self.bdBuildJointStructure(joint, ctrlName, ikName) ''' allAnimsGrps = pm.ls(self.templateSide + '*eye*CON_??',type='transform') globalAnimGrp = pm.ls('controllers') pm.parent(allAnimsGrps,globalAnimGrp[0]) ''' self.bdAddEyeAttr(eyeAnim[0]) self.bdCreateVerticalFollow(side) self.bdCreateSideFollow(side) self.bdCreateBlink(side) self.bdCleanupGuides(side)
def bdRigLegBones(side): ikAnimCon = pm.ls(side + '*foot*IK_CON', type='transform')[0] legBonesNames = ['thigh', 'knee', 'foot', 'toe'] legBones = [] for bone in legBonesNames: legBone = pm.ls(side + '_' + bone + '_ik')[0] legBones.append(legBone) print legBone.name() toeEnd = pm.ls(side + '_' + 'toe_ik_end')[0] legBones.append(toeEnd) # START setup foot roll footIk = pm.ikHandle(sol='ikRPsolver', sticky='sticky', startJoint=legBones[0], endEffector=legBones[2], name=side + '_foot_ikHandle')[0] footIk.visibility.set(0) ballIk = pm.ikHandle(sol='ikSCsolver', sticky='sticky', startJoint=legBones[2], endEffector=legBones[3], name=side + '_ball_ikHandle')[0] ballIk.visibility.set(0) toeIk = pm.ikHandle(sol='ikSCsolver', sticky='sticky', startJoint=legBones[3], endEffector=legBones[4], name=side + '_toe_ikHandle')[0] toeIk.visibility.set(0) # create the groups that will controll the foot animations ( roll, bend, etc etc) footHelpers = pm.ls(side + '*_helper', type='transform') ankleLoc = bdCreateOffsetLoc(legBones[2], side + '_ankle_loc') footLoc = bdCreateOffsetLoc(legBones[2], side + '_foot_loc') ballLoc = bdCreateOffsetLoc(legBones[3], side + '_ball_loc') ballTwistLoc = bdCreateOffsetLoc(legBones[3], side + '_ball_twist_loc') toeLoc = bdCreateOffsetLoc(legBones[4], side + '_toe_loc') toeBendLoc = bdCreateOffsetLoc(legBones[3], side + '_toe_bend_loc') innerLoc = outerLoc = heelLoc = '' for helper in footHelpers: if 'inner' in helper.name(): innerLoc = bdCreateOffsetLoc(helper, side + '_inner_bank_loc') elif 'outer' in helper.name(): outerLoc = bdCreateOffsetLoc(helper, side + '_outer_bank_loc') elif 'heel' in helper.name(): heelLoc = bdCreateOffsetLoc(helper, side + '_heel_loc') # pm.delete(footHelpers) pm.parent(footIk, footLoc) pm.parent(ballIk, ballLoc) pm.parent(toeIk, toeBendLoc) pm.parent(toeBendLoc, toeLoc) pm.parent(footLoc, ballLoc) pm.parent(ballLoc, toeLoc) pm.parent(toeLoc, ballTwistLoc) pm.parent(ballTwistLoc, innerLoc) pm.parent(innerLoc, outerLoc) pm.parent(outerLoc, heelLoc) pm.parent(heelLoc, ankleLoc) print "start adding attributes" # add atributes on the footGrp - will be conected later to an anim controler autoRollAttrList = ['Roll', 'ToeStart', 'BallStraight'] footAttrList = [ 'HeelTwist', 'BallTwist', 'TipTwist', 'Bank', 'ToeBend', 'KneeTwist' ] normalRollAttrList = ['HeelRoll', 'BallRoll', 'TipRoll'] pm.addAttr(ikAnimCon, ln='__AutoFootRoll__', nn='__AutoFootRoll__', at='bool') ikAnimCon.attr('__AutoFootRoll__').setKeyable(True) ikAnimCon.attr('__AutoFootRoll__').setLocked(True) pm.addAttr(ikAnimCon, ln='Enabled', nn='Enabled', at='long') ikAnimCon.attr('Enabled').setKeyable(True) ikAnimCon.attr('Enabled').setMin(0) ikAnimCon.attr('Enabled').setMax(1) ikAnimCon.attr('Enabled').set(1) pm.addAttr(ikAnimCon, ln='______', nn='______', at='bool') ikAnimCon.attr('______').setKeyable(True) ikAnimCon.attr('______').setLocked(True) for attr in autoRollAttrList: pm.addAttr(ikAnimCon, ln=attr, nn=attr, at='float') ikAnimCon.attr(attr).setKeyable(True) pm.addAttr(ikAnimCon, ln='__FootRoll__', nn='__FootRoll__', at='bool') ikAnimCon.attr('__FootRoll__').setKeyable(True) ikAnimCon.attr('__FootRoll__').setLocked(True) for attr in normalRollAttrList: pm.addAttr(ikAnimCon, ln=attr, nn=attr, at='float') ikAnimCon.attr(attr).setKeyable(True) pm.addAttr(ikAnimCon, ln='__FootAttr__', nn='__FootAttr__', at='bool') ikAnimCon.attr('__FootAttr__').setKeyable(True) ikAnimCon.attr('__FootAttr__').setLocked(True) for attr in footAttrList: pm.addAttr(ikAnimCon, ln=attr, nn=attr, at='float') ikAnimCon.attr(attr).setKeyable(True) ikAnimCon.attr('ToeStart').set(40) ikAnimCon.attr('BallStraight').set(80) bdCreateReverseFootRoll(ikAnimCon, heelLoc, ballLoc, toeLoc) # connect the attributes ikAnimCon.attr('HeelTwist').connect(heelLoc.rotateY) ikAnimCon.attr('BallTwist').connect(ballTwistLoc.rotateY) ikAnimCon.attr('TipTwist').connect(toeLoc.rotateY) ikAnimCon.attr('ToeBend').connect(toeBendLoc.rotateX) bdConnectBank(ikAnimCon, innerLoc, outerLoc) # START no flip knee knee mirror = 1 if side == 'R': mirror = -1 poleVectorLoc = pm.spaceLocator(name=side + '_knee_loc_PV') poleVectorLocGrp = pm.group(poleVectorLoc, n=poleVectorLoc + '_GRP') thighPos = legBones[0].getTranslation(space='world') poleVectorLocGrp.setTranslation( [thighPos[0] + mirror * 5, thighPos[1], thighPos[2]]) pm.poleVectorConstraint(poleVectorLoc, footIk) adlNode = pm.createNode('addDoubleLinear', name=side + '_adl_twist') adlNode.input2.set(mirror * 90) ikAnimCon.attr('KneeTwist').connect(adlNode.input1) adlNode.output.connect(footIk.twist) startTwist = mirror * 90 limit = 0.001 increment = mirror * 0.01 while True: pm.select(cl=True) thighRot = pm.xform(legBones[0], q=True, ro=True, os=True) if ((thighRot[0] > limit)): startTwist = startTwist - increment adlNode.input2.set(startTwist) else: break # END knee pm.parent(ankleLoc, ikAnimCon)
def pvc_ik(self, controller, pvc_target=None): """ Pole Vector IK """ # Parameter validation if not isinstance(controller, pm.nodetypes.Transform): raise ValueError("Bad data type for parameter 'controller'") if pvc_target and not isinstance(pvc_target, pm.nodetypes.Transform): raise ValueError("Bad data type for parameter 'pvc_target'") # Get position vectors for all joints in limb vectors = [ om.MVector(pm.joint(x, q=True, p=True, a=True)) for x in self.joints ] # Define a line between first and last joint line = utils.vectors.Line(vectors[0], vectors[-1]) # Get an average position for all joints excluding first and last in list. avg = utils.vectors.average(vectors[1:-1]) # Get world position along line closest to avg vector. mid = line.closest_point_along_line_to(avg) print("Mid Position: {}".format(mid)) print("Avg Position: {}".format(avg)) # Get a direction along which to place pvc target. direction = om.MVector(avg - mid).normal() print("Dir Pre: {}".format(direction)) # Add magnitude to vector, either closest distance to our line, or length of our limb. if pvc_target: direction *= line.distance_to( pm.xform(pvc_target, q=True, ws=True, t=True)) else: direction *= self.length() print("Dir Post: {}".format(direction)) # TODO Debug Position, am I starting from first joint? # Get position to place our PVC Target position = om.MVector(avg + direction) print("Position: {}".format(position)) if pvc_target: # Position the pvc target controller, pm.xform(pvc_target, ws=True, t=position) # Create the srt buffer group to zero out the controller ctrl.srt_buffer(target=pvc_target, child=pvc_target) else: pvc_target = pm.spaceLocator(p=position, a=True, name="{}_pvc_target".format( self.name)) pm.xform(pvc_target, centerPivots=True) self.ikHandle = pm.ikHandle(name='{}_ikHandle'.format( self.joints[-1].nodeName()), sj=self.joints[0], ee=self.joints[-1], solver='ikRPsolver')[0] pm.poleVectorConstraint(pvc_target, self.ikHandle) pm.parent(self.ikHandle, controller)
def slider(): # # Guide # # guide Shape guide = pm.curve( d=3, p=[(1.6653345369377348e-16, 0.2500000000000002, -1.1102230246251563e-16), (-0.06530099999999994, 0.2500000000000002, -1.2552203720872514e-16), (-0.19590299999999994, 0.19590300000000038, -1.5452150670114405e-16), (-0.27704850000000003, 4.0659597910774894e-16, -1.725394271900882e-16), (-0.19590300000000016, -0.1959029999999996, -1.545215067011441e-16), (-0.06530100000000005, -0.2499999999999997, -1.2552203720872514e-16), (0.0, -0.24999999999999978, -1.1102230246251565e-16), (0.3333333333333333, -0.25000000000000017, -3.7007434154171876e-17), (0.6666666666666665, -0.2500000000000004, 3.7007434154171864e-17), (1.0000000000000002, -0.2500000000000004, 1.1102230246251573e-16), (1.065301, -0.2500000000000003, 1.2552203720872516e-16), (1.195903, -0.19590300000000044, 1.5452150670114405e-16), (1.2770485, -4.0659597910774894e-16, 1.725394271900882e-16), (1.1959030000000002, 0.19590299999999966, 1.545215067011441e-16), (1.0653009999999998, 0.24999999999999978, 1.255220372087251e-16), (1.0, 0.24999999999999983, 1.1102230246251568e-16), (0.6666666666666667, 0.25000000000000017, 3.700743415417189e-17), (0.33333333333333337, 0.2500000000000004, -3.700743415417189e-17), (5.551115123125783e-17, 0.25000000000000033, -1.1102230246251565e-16)], k=[ 2.0, 2.0, 2.0, 3.0, 4.0, 5.0, 6.0, 6.0, 6.0, 8.0, 8.0, 8.0, 9.0, 10.0, 11.0, 12.0, 12.0, 12.0, 14.0, 14.0, 14.0 ]) guide.getShape().overrideEnabled.set(True) guide.getShape().overrideDisplayType.set(1) # Template # snapPoint tmp = pm.spaceLocator() tmp.localScale.set(0, 0, 0) tmp.getShape().overrideEnabled.set(1) tmp.getShape().overrideDisplayType.set(2) # Reference snapLoc = [] snapPnts = [(0, 0), (1, 0)] for x, y in snapPnts: loc = pm.duplicate(tmp)[0] loc.localPositionX.set(x) loc.localPositionY.set(y) pm.parent(loc.getShape(), guide, s=True, r=True) snapLoc.append(loc) pm.delete(snapLoc, tmp) guide.rename('guide') for shp in guide.getShapes(): shp.rename('ctrlGuideShape#') # # Ctrl # # ctrl Shape ctrl = pm.curve(d=3, p=[(-0.2, 0.0, 0.0), (-0.2, -0.052240800000000004, 1.1599787796967576e-17), (-0.1567224, -0.1567224, 3.479936339090273e-17), (0.0, -0.2216388, 4.921369978205803e-17), (0.1567224, -0.1567224, 3.479936339090273e-17), (0.2, -0.052240800000000004, 1.1599787796967576e-17), (0.2, 0.0, 0.0), (0.2, 0.052240800000000004, -1.1599787796967576e-17), (0.1567224, 0.1567224, -3.479936339090273e-17), (0.0, 0.2216388, -4.921369978205803e-17), (-0.1567224, 0.1567224, -3.479936339090273e-17), (-0.2, 0.052240800000000004, -1.1599787796967576e-17), (-0.2, 0.0, 0.0)], k=[ 2.0, 2.0, 2.0, 3.0, 4.0, 5.0, 6.0, 6.0, 6.0, 7.0, 8.0, 9.0, 10.0, 10.0, 10.0 ]) ctrl.setLimit("translateMinX", 0) ctrl.setLimit("translateMinY", 0) ctrl.setLimit("translateMinZ", 0) ctrl.setLimit("translateMaxX", 1) ctrl.setLimit("translateMaxY", 0) ctrl.setLimit("translateMaxZ", 0) ctrl.rename('ctrl') # add Attr for attr in ['output']: ctrl.addAttr(attr, dv=0, min=0, max=1, keyable=True) ctrl.setAttr(attr, keyable=False, lock=False, channelBox=True) # Attr Lock for attr in ['ty', 'tz', 'rx', 'ry', 'rz', 'sx', 'sy', 'sz', 'v']: ctrl.setAttr(attr, keyable=False, lock=True, channelBox=False) # Setdriven #1 sdks = [ # driverAttr, driverVal, drivenAttr, drivenVal (ctrl.tx, 0, ctrl.output, 0), (ctrl.tx, 1, ctrl.output, 1), ] for driverAttr, driverVal, drivenAttr, drivenVal in sdks: pm.setDrivenKeyframe(drivenAttr, currentDriver=driverAttr, driverValue=driverVal, value=drivenVal, inTangentType='linear', outTangentType='linear') # parent pm.parent(ctrl, guide) pm.select(guide) return ctrl, guide