Пример #1
0
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
Пример #2
0
    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
Пример #3
0
 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
Пример #4
0
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] )
Пример #5
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
Пример #6
0
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] )
Пример #8
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"])
Пример #9
0
    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
Пример #11
0
def parentToControlsGrp( characterNode ): 
    pymelLogger.debug('Starting: parentToControlsGrp()...') 
    
    pm.parent( characterNode, Names.modules_grp ) 
    
    pymelLogger.debug('End: parentToControlsGrp()...') 
      
Пример #12
0
    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
Пример #13
0
 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)
Пример #14
0
	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)
Пример #15
0
 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}
Пример #16
0
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)
Пример #17
0
	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)
Пример #18
0
    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 )
Пример #19
0
    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
Пример #20
0
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
Пример #21
0
    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)
Пример #22
0
    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
Пример #23
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
Пример #24
0
    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()
Пример #25
0
    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 ) 
Пример #26
0
    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']))
Пример #27
0
    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
Пример #28
0
    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 )
Пример #29
0
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)
Пример #31
0
    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"])
Пример #32
0
    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
Пример #33
0
    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)
Пример #34
0
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))
Пример #35
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
Пример #36
0
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)
Пример #37
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
Пример #38
0
    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)
Пример #39
0
    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)
Пример #40
0
    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])
Пример #41
0
 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')
Пример #42
0
    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)
Пример #43
0
    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]))
Пример #44
0
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)
Пример #45
0
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
Пример #47
0
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)
Пример #49
0
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]
Пример #50
0
def pip():
    toParent = pm.selected()[-1].listRelatives(p=1)[0]
    pm.parent(pm.selected()[:-10], )
Пример #51
0
    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)
Пример #52
0
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
Пример #53
0
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.')
Пример #54
0
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!!'
Пример #55
0
    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
Пример #56
0
    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)
Пример #57
0
    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)
Пример #58
0
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)
Пример #59
0
    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)
Пример #60
0
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