def _visualizer_setup(self):
        """Add a shader to visualize the outValue and the coneAngle."""
        visualize_sdr = pm.shadingNode('surfaceShader', asShader=True,
                                       n='visualize')
        sets = pm.sets(renderable=True, noSurfaceShader=True, empty=True,
                       n='visualize')
        visualize_sdr.outColor >> sets.surfaceShader
        vis_ramp = pm.createNode('ramp', n='visualize')
        vis_ramp.setAttr('type', 1)
        vis_ramp.setAttr('colorEntryList[0].color', 0, 0, 0)
        vis_ramp.setAttr('colorEntryList[1].position', 1)
        vis_ramp.setAttr('colorEntryList[1].color', 0, 0, 0)
        vis_ramp.setAttr('colorEntryList[2].position', 0)
        cmds.setAttr('%s.colorEntryList[2].color' % vis_ramp, 0, 0, 0,
                     type='double3')
        vis_ramp.setAttr('colorEntryList[3].color', 0, 0, 0)
        self.ramp.outColorR >> vis_ramp.colorEntryList[1].color.colorG
        rmv = pm.createNode('remapValue', n='visualize')
        rmv.setAttr('inputMin', -1)
        rmv.setAttr('inputMax', 0)
        rmv.setAttr('outputMin', 1)
        rmv.setAttr('outputMax', 0)
        self.ramp.outColorR >> rmv.inputValue
        rmv.outValue >> vis_ramp.colorEntryList[2].color.colorR

        (self.ramp.colorEntryList[0].position >>
         vis_ramp.colorEntryList[0].position)
        (self.ramp.colorEntryList[3].position >>
         vis_ramp.colorEntryList[3].position)

        vis_ramp.outColor >> visualize_sdr.outColor
        pm.defaultNavigation(source=visualize_sdr,
                             destination=self.sphere.getShape().instObjGroups[0],
                             connectToExisting=True)
	def createEtWorldPosRE(self):
		
		#create etWorldPosRE
		etWorldPosRE = self.createRenderElement('ExtraTexElement')
		pm.rename(etWorldPosRE, 'rbEtWorldPos')
		
		#SetAttrs on etWorldPosRE
		pm.setAttr(etWorldPosRE.vray_name_extratex, 'rbEtWorldPos')
		pm.setAttr(etWorldPosRE.vray_explicit_name_extratex, 'rbEtWorldPos')
		pm.setAttr(etWorldPosRE.vray_affectmattes_extratex, 0)
		pm.setAttr(etWorldPosRE.vray_filtering_extratex, 0)
		
		
		#Create vrayfresnel tex and setAttrs
		pm.select(cl = True)
		
		vrayFresnelTex = pm.createNode('VRayFresnel')
		pm.rename(vrayFresnelTex, 'rbVRayFresnelWorldPos')
		pm.setAttr(vrayFresnelTex.IOR, 1)
		
		pm.select(cl = True)
		
		#Create sampler Info Node
		samplerInfoWorldPos = pm.createNode('samplerInfo')
		pm.rename(samplerInfoWorldPos, 'rbSamplerInfoWorldPos')
		
		#connections
		samplerInfoWorldPos.pointWorld >> vrayFresnelTex.frontColor
		samplerInfoWorldPos.pointWorld >> vrayFresnelTex.sideColor
		vrayFresnelTex.outColor >> etWorldPosRE.vray_texture_extratex
		pm.select(cl = True)
		
		
		#verbose
		if(self.verbose): print('Extra Tex World Pos RE created')
Beispiel #3
0
def bdCreateDistanceCnd():
    jnt = pm.ls(sl=1)[0]
    #loc1,loc2,jnt = pm.ls(sl=1)
    jntCnstr = jnt.listRelatives(type='pointConstraint')[0]
    loc1,loc2 = pm.pointConstraint(jntCnstr,q=1,tl=1)
    
    matrixLoc1 = pm.createNode('decomposeMatrix',name = loc1.name().replace('_loc','_dm'))
    matrixLoc2 = pm.createNode('decomposeMatrix',name = loc2.name().replace('_loc','_dm'))
    pma = pm.createNode('plusMinusAverage',name = loc1.name().replace('_loc','_pma'))
    pma.operation.set(2)
    rv = pm.createNode('remapValue',name = loc1.name().replace('_loc','_rv'))
    rv.inputMin.set(0.1)
    
    rev = pm.createNode('reverse',name = loc1.name().replace('_loc','_rev'))

    
    loc1.worldMatrix[0].connect(matrixLoc1.inputMatrix)
    loc2.worldMatrix[0].connect(matrixLoc2.inputMatrix)
    matrixLoc1.outputTranslateY.connect(pma.input1D[0])
    matrixLoc2.outputTranslateY.connect(pma.input1D[1])
    pma.output1D.connect(rv.inputValue)
    
    rv.outValue.connect(jntCnstr.attr(loc1.name() + 'W0'))
    rv.outValue.connect(rev.inputX)
    rev.outputX.connect(jntCnstr.attr(loc2.name() + 'W1'))
    def build(self, no_subdiv=False, num_ctrl=None, degree=3, create_ctrl=True, constraint=False, rot_fol=True, *args,
              **kwargs):
        super(Ribbon, self).build(create_grp_anm=create_ctrl, *args, **kwargs)
        if num_ctrl is not None:
            self.num_ctrl = num_ctrl

        nomenclature_rig = self.get_nomenclature_rig()

        # Create the plane and align it with the selected bones
        plane_tran = next(
            (input for input in self.input if libPymel.isinstance_of_shape(input, pymel.nodetypes.NurbsSurface)), None)
        if plane_tran is None:
            plane_name = nomenclature_rig.resolve("ribbonPlane")
            if no_subdiv:  # We don't want any subdivision in the plane, so use only 2 bones to create it
                no_subdiv_degree = 2
                if degree < 2:
                    no_subdiv_degree = degree
                plane_tran = libRigging.create_nurbs_plane_from_joints([self.chain_jnt[0], self.chain_jnt[-1]],
                                                                       degree=no_subdiv_degree, width=self.width)
            else:
                plane_tran = libRigging.create_nurbs_plane_from_joints(self.chain_jnt, degree=degree, width=self.width)
            plane_tran.rename(plane_name)
            plane_tran.setParent(self.grp_rig)
        self._ribbon_shape = plane_tran.getShape()

        # Create the follicule needed for the system on the skinned bones
        self.attach_to_plane(rot_fol)
        # TODO : Support aim constraint for bones instead of follicle rotation?

        follicles_grp = pymel.createNode("transform")
        follicle_grp_name = nomenclature_rig.resolve("follicleGrp")
        follicles_grp.rename(follicle_grp_name)
        follicles_grp.setParent(self.grp_rig)
        for n in self._follicles:
            n.setParent(follicles_grp)

        # Create the joints that will drive the ribbon.
        # TODO: Support other shapes than straight lines...
        self._ribbon_jnts = libRigging.create_chain_between_objects(
            self.chain_jnt.start, self.chain_jnt.end, self.num_ctrl, parented=False)

        # Group all the joints
        ribbon_chain_grp_name = nomenclature_rig.resolve('ribbonChainGrp')
        self.ribbon_chain_grp = pymel.createNode('transform', name=ribbon_chain_grp_name, parent=self.grp_rig)
        align_chain = True if len(self.chain_jnt) == len(self._ribbon_jnts) else False
        for i, jnt in enumerate(self._ribbon_jnts):
            # Align the ribbon joints with the real joint to have a better rotation ctrl
            ribbon_jnt_name = nomenclature_rig.resolve('ribbonJnt{0:02d}'.format(i))
            jnt.rename(ribbon_jnt_name)
            jnt.setParent(self.ribbon_chain_grp)
            if align_chain:
                matrix = self.chain_jnt[i].getMatrix(worldSpace=True)
                jnt.setMatrix(matrix, worldSpace=True)

        # TODO - Improve skinning smoothing by setting manually the skin...
        pymel.skinCluster(list(self._ribbon_jnts), plane_tran, dr=1.0, mi=2.0, omi=True)
        try:
            libSkinning.assign_weights_from_segments(self._ribbon_shape, self._ribbon_jnts, dropoff=1.0)
        except ZeroDivisionError, e:
            pass
Beispiel #5
0
def finalize_boxes():
    # collect weights
    boxes = collect_proxy_boxes()
    jnts = [box.getParent() for box in boxes]
    weights = []
    for i, box in enumerate(boxes):
        weights.extend([i] * len(box.vtx))

    # mergeboxes
    polyUnite = pymel.createNode('polyUnite')
    itt = 0
    for box in boxes:
        for shape in box.getShapes():
            pymel.connectAttr(shape.worldMatrix, polyUnite.inputMat[itt])
            pymel.connectAttr(shape.outMesh, polyUnite.inputPoly[itt])
            itt += 1
    outputMesh = pymel.createNode('mesh')
    pymel.connectAttr(polyUnite.output, outputMesh.inMesh)
    #pymel.delete(boxes)

    # set skin weights
    pymel.skinCluster(jnts, outputMesh.getParent(), toSelectedBones=True)
    skinCluster = next((hist for hist in outputMesh.listHistory() if isinstance(hist, pymel.nodetypes.SkinCluster)), None)
    for vtx, inf in zip(iter(outputMesh.vtx), weights):
        skinCluster.setWeights(vtx, [inf], [1])
Beispiel #6
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
Beispiel #7
0
	def _attachRenderProxy( self, objects ):
		path = self.fileInput.text()
		proxy = []
		
		if os.path.isdir(path):
			for file in glob.glob(path+"/*.mib"):
				bipx = pm.createNode('mip_binaryproxy',n=file.split('/').pop().split('.')[0]+'_BINARYPROXY')
				bipx.object_filename.set(file)
				proxy.append(bipx)
		else:
			bipx = pm.createNode('mip_binaryproxy',n=path.split('/').pop().split('.')[0]+'_BINARYPROXY')
			bipx.object_filename.set(path)
			proxy.append( bipx )
			
		if not objects:
			for prx in proxy:
				objects.append(pm.polyCube())
				
		for arg in objects:
			if len(proxy)==0: pm.error('No proxies found in folder. Womp Womp.')
			elif len(proxy)>1:
				print 'more than one proxy'
				#turn the lo geometry shader on
				arg.miExportGeoShader.set(1)
				#connect the proxy to the lo's geo shader
				proxy[random.randint(0,len(proxy)-1)].outValue.connect(arg.miGeoShader, f=True)
			else:
				print 'one proxy'
				#turn the lo geometry shader on
				arg.miExportGeoShader.set(1)
				#connect the proxy to the lo's geo shader
				proxy.pop().outValue.connect(arg.miGeoShader, f=True)
Beispiel #8
0
def makeNodeSet(pointValueList, transNodeType):
    
    for x in pointValueList:
        if transNodeType == 'locator':
            pm.spaceLocator().t.set(x)
        else:
            pm.createNode(transNodeType).t.set(x)
Beispiel #9
0
def createSubdivApproxNode():
    '''
    copy of createApproxNode from mentalrayApproxEditor.mel
    node will be named "mathildaSubdivApprox"
    '''
    # delete existing node if exists
    nodeName = 'mathildaSubdivApprox'
    
    # make sure mental ray is loaded first
    if not pm.pluginInfo('Mayatomr', q=True, loaded=True):
        pm.loadPlugin('Mayatomr', qt=True)
    
    # create approx node
    approxNode = pm.createNode('mentalraySubdivApprox', n=nodeName)
    
    # get listNode
    try:
        mrItemsListNode = pm.ls(type='mentalrayItemsList')[0]
    except IndexError:
        mrItemsListNode = pm.createNode('mentalrayItemsList', n='mentalrayItemsList')
    
    # connect approx to list
    pm.connectAttr(approxNode.message, mrItemsListNode.subdivApproxs, na=True)
    
    return approxNode
    def _create_custom(self):
        self.pos_x_remap.outputMin.set(1)
        self.pos_x_remap.outputMax.set(0)

        self.neg_x_remap.outputMin.set(0)
        self.neg_x_remap.outputMax.set(1)

        NL_mult = pm.createNode("multDoubleLinear", name="%s_NL_mult" % self.prefix)
        NR_mult = pm.createNode("multDoubleLinear", name="%s_NR_mult" % self.prefix)
        SL_mult = pm.createNode("multDoubleLinear", name="%s_SL_mult" % self.prefix)
        SR_mult = pm.createNode("multDoubleLinear", name="%s_SR_mult" % self.prefix)

        self.pos_x_remap.outValue >> NR_mult.input1
        self.pos_y_remap.outValue >> NR_mult.input2
        NR_mult.output >> self.control_group.nShapeR

        self.neg_x_remap.outValue >> NL_mult.input1
        self.pos_y_remap.outValue >> NL_mult.input2
        NL_mult.output >> self.control_group.nShapeL

        self.pos_x_remap.outValue >> SR_mult.input1
        self.neg_y_remap.outValue >> SR_mult.input2
        SR_mult.output >> self.control_group.sShapeR

        self.neg_x_remap.outValue >> SL_mult.input1
        self.neg_y_remap.outValue >> SL_mult.input2
        SL_mult.output >> self.control_group.sShapeL
def createFresnel(out = None):
    #创建菲涅尔节点组合
    #
    #参数out: 属性输出给哪个节点, 连接属性
    #
    #创建节点
    samplerInfo = pm.createNode('samplerInfo', name = 'Fre_samplerInfo_arnold')
    ramp = pm.createNode('ramp', name = 'Fre_ramp_arnold')
    aiUtility, SG = pm.createSurfaceShader('aiUtility', name = 'Fresnel_arnold')
    
    #修改属性
    ramp.interpolation.set("Exponential Down")
    ramp.colorEntryList[2].remove(b=1)
    ramp.colorEntryList[1].position.set(1)
    ramp.colorEntryList[0].color.set(1,1,1)
    ramp.colorEntryList[1].color.set(0,0,0)
    
    aiUtility.shadeMode.set(2)
    
    #链接属性
    samplerInfo.facingRatio >> ramp.uvCoord.uCoord
    samplerInfo.facingRatio >> ramp.uvCoord.vCoord
    
    ramp.outColor >> aiUtility.color

    if out :
        aiUtility.outColor >> out
    else :
        pass
    
    return aiUtility, SG
def createZ(out = None):
    #创建Z通道节点组合
    #
    #参数out: 属性输出给哪个节点, 连接属性
    #
    #创建节点
    samplerInfo = pm.createNode('samplerInfo', name = 'z_samplerInfo_arnold')
    multiplyDivide = pm.createNode('multiplyDivide', name = 'z_multiplyDivide_arnold')
    setRange = pm.createNode('setRange', name = 'z_setRange_arnold')
    aiUtility, SG = pm.createSurfaceShader('aiUtility', name = 'zdp_arnold')
    
    #修改属性
    multiplyDivide.input2X.set(-1)
    
    setRange.minX.set(1)
    setRange.oldMinX.set(0.1)
    setRange.oldMaxX.set(500)
    
    aiUtility.shadeMode.set(2)
    
    #属性链接
    samplerInfo.pointCameraZ >> multiplyDivide.input1X
    multiplyDivide.outputX >> setRange.valueX
    setRange.message >> aiUtility.colorR
    setRange.message >> aiUtility.colorG
    setRange.message >> aiUtility.colorB
    
    if out :
        aiUtility.outColor >> out
    else :
        pass
    
    return aiUtility, SG
Beispiel #13
0
def wiggleJointChain(strPnt, endPnt, side='FL', chainPos='Upper'):
    '''
    create joint chain between two points (strPnt & endPnt). require name string of strPnt & endPnt
    '''
    strPos = pm.xform( strPnt, q=True, ws=True, translation=True )
    endPos = pm.xform( endPnt, q=True, ws=True, translation=True )
    
    if side.endswith('L'):
        sideLabel = 1
    elif side.endswith('R'):
        sideLabel = 2
        
    ikSpCrv = pm.curve( degree=2, editPoint=( strPos, endPos) )
    ikSpCrv.rename( 'wiggle_%s_%s_CRV'%(side, chainPos) )
    ikSpCrvShp = ikSpCrv.listRelatives(shapes=True)[0]
    pm.select(clear=True)
    
    jnt2pos = pm.pointOnCurve( ikSpCrv, pr=0.3333, turnOnPercentage=True)
    jnt3pos = pm.pointOnCurve( ikSpCrv, pr=0.6667, turnOnPercentage=True )
    
    jntPos = ( strPos, jnt2pos, jnt3pos, endPos )
    jntList = []
    for pnt in jntPos:
        jName = 'Wiggle_%s_%s_%02d'%(side, chainPos, jntPos.index(pnt)+1)
        newJoint = pm.joint(name=jName, p=pnt)
        newJoint.side.set(sideLabel)
        newJoint.__getattr__('type').set(18)
        newJoint.otherType.set(jName)
        jntList.append(newJoint)
        
    pm.joint( jntList[0], edit=True, orientJoint='xyz', secondaryAxisOrient='xup', children=True, zeroScaleOrient=True )
    
    ikHandle = pm.ikHandle( name='Wiggle_%s_%s_ikHandle'%(side, chainPos),
                            solver='ikSplineSolver', 
                            createCurve=False, 
                            curve=ikSpCrvShp, 
                            startJoint=jntList[0].name(), 
                            endEffector=jntList[-1].name(), 
                            rootOnCurve=False, 
                            createRootAxis=True, 
                            parentCurve=False )
    
    jntGrp = jntList[0].listRelatives(parent=True)[0]
    jntGrp.rename('Wiggle_%s_%s'%(side, chainPos))
    crvInfo = pm.createNode('curveInfo', name='crvInf_wiggle_%s_%s'%(side, chainPos))
    multDiv1 = pm.createNode('multiplyDivide', name='md_wiggle_%s_%s_01'%(side, chainPos))
    multDiv2 = pm.createNode('multiplyDivide', name='md_wiggle_%s_%s_02'%(side, chainPos))
    ikSpCrvShp.worldSpace >> crvInfo.inputCurve
    arcLgt = crvInfo.arcLength.get()
    multDiv1.input2X.set(arcLgt)
    multDiv1.operation.set(2)
    spacing = jntList[1].tx.get()
    multDiv2.input2X.set(spacing)
    multDiv1.outputX >> multDiv2.input1X
    crvInfo.arcLength >> multDiv1.input1X
    
    for jnt in jntList[1:]:
        multDiv2.outputX >> jnt.tx
    
    return ikSpCrvShp, ikSpCrv, ikHandle[0], jntGrp
Beispiel #14
0
def symmetryLayer():

    allCtrls = pm.PyNode('CT_face_ctrl').getChildren(ad=True, type='nurbsCurve')
    allCtrls = set([crv.getParent() for crv in allCtrls])
    
    # new group to hold mirrored locs
    symLocGrp = pm.group(em=True, n='RT_symmetryLoc_grp')
    
    allRightCtrls = [crv for crv in allCtrls if 'RT_' in crv.name()]
    symMatrix = pm.createNode('fourByFourMatrix', n='CT_symmetryMatrix_mat')
    symMatrix.in00.set(-1)
    
    for rightCtl in allRightCtrls:
        leftCtl = pm.PyNode(rightCtl.replace('RT_', 'LT_'))
        loc = pm.spaceLocator(n=rightCtl+'_symLoc')
        symLocGrp | loc
        # connect to left side
        mm = pm.createNode('multMatrix', n=rightCtl+'_sym_mm')
        symMatrix.output >> mm.matrixIn[0]
        leftCtl.worldMatrix >> mm.matrixIn[1]
        symMatrix.output >> mm.matrixIn[2]
        dcm = pm.createNode('decomposeMatrix', n=rightCtl+'_sym_dcm')
        mm.matrixSum >> dcm.inputMatrix
        dcm.ot >> loc.t
        dcm.outputRotate >> loc.r
        # constrain on anim layer
        pm.parentConstraint(loc, rightCtl, l='Symmetry', weight=1)
Beispiel #15
0
def connectLocRotate():
    '''
    '''
    locGrpNames = ['_back',
                   '_left',
                   '_front',
                   '_right',
                   '_leftBack',
                   '_rightBack',
                   '_rightFront',
                   '_leftFront']
    
    # create one nurb circle for all groups
    circ = pm.createNode('makeNurbCircle', n='CT_jacketLocsAlign_circle')
    circ.normal.set(0,1,0)
    # use the same root ctrl for all groups
    rootCtl = pm.PyNode('Mathilda_root_ctrl')
    
    # create one motionpath for each group
    for grpName in locGrpNames:
        mp = pm.createNode('motionPath', n='CT_jacketLocsAlign'+grpName+'_mp')
        circ.outputCurve >> mp.gp
        # use paramater from lowest npc
        pm.PyNode('torsoReader_3'+grpName+'_npc').parameter >> mp.uValue
        rootCtl.worldMatrix >> mp.worldUpMatrix
        mp.worldUpType.set(2)
        mp.worldUpVector.set(0,1,0)
        mp.frontAxis.set(0)
        mp.upAxis.set(1)
        # connect to all locs in grp
        for locId in range(1,10):
            mp.rotate >> pm.PyNode('torsoReader_%d%s_loc.r' %
                                   (locId, grpName))
Beispiel #16
0
    def addAOV(self, aovName, aovType=None):
        '''
        add an AOV to the active list for this AOV node

        returns the created AOV node
        '''
        if aovType is None:
            aovType = getAOVTypeMap().get(aovName, 'rgba')
        if not isinstance(aovType, int):
            aovType = dict(TYPES)[aovType]
        aovNode = pm.createNode('aiAOV', name='aiAOV_' + aovName, skipSelect=True)
        out = aovNode.attr('outputs')[0]

        pm.connectAttr('defaultArnoldDriver.message', out.driver)
        filter = defaultFiltersByName.get(aovName, None)
        if filter:
            node = pm.createNode('aiAOVFilter', skipSelect=True)
            node.aiTranslator.set(filter)
            filterAttr = node.attr('message')
            import mtoa.hooks as hooks
            hooks.setupFilter(filter, aovName)
        else:
            filterAttr = 'defaultArnoldFilter.message'
        pm.connectAttr(filterAttr, out.filter)

        aovNode.attr('name').set(aovName)
        aovNode.attr('type').set(aovType)
        nextPlug = self.nextAvailableAttr()
        aovNode.message.connect(nextPlug)
        aov = SceneAOV(aovNode, nextPlug)
        addAliases([aov])
        return aov
Beispiel #17
0
def connectJacketLoc(twistCrv, untwistCrv, param, name='', addCrvs=[]):
    '''
    '''
    mp = pm.createNode('motionPath', n=twistCrv+name+'_mp')
    untwistCrv.worldSpace >> mp.geometryPath
    mp.u.set(param)
    
    npc = pm.createNode('nearestPointOnCurve', n=twistCrv+name+'_npc')
    mp.allCoordinates >> npc.inPosition
    twistCrv.worldSpace >> npc.inputCurve
    
    allLocs = []
    loc = pm.spaceLocator(n=twistCrv+name+'_loc')
    npc.position >> loc.translate
    allLocs.append(loc)
    
    for crv in addCrvs:
        pci = pm.createNode('pointOnCurveInfo', n=crv+name+'_pci')
        npc.parameter >> pci.parameter
        crv.worldSpace >> pci.inputCurve
        loc = pm.spaceLocator(n=crv+name+'_loc')
        pci.position >> loc.translate
        allLocs.append(loc)
    
    pm.select(allLocs)
Beispiel #18
0
def connectEyelidLocsToBlinkAttr():
    '''
    '''
    blinkAttr = pm.PyNode('LT_eye_ctl.blink')

    locA, locB = pm.ls(sl=True)[:2]
    
    # get center pt between two locs (from their pocis)
    pociA = locA.t.inputs(type='pointOnCurveInfo', p=True)[0]
    pociB = locB.t.inputs(type='pointOnCurveInfo', p=True)[0]
    pma = pm.createNode('plusMinusAverage', n=locA+'_avgPos_pma')
    pma.operation.set(3)
    pociA >> pma.input3D[0]
    pociB >> pma.input3D[1]
    # blend positions
    blendA = pm.createNode('blendColors', n=locA+'_blendPos_bld')
    pma.output3D >> blendA.color1
    pociA >> blendA.color2
    blinkAttr >> blendA.blender
    blendA.output >> locA.t
    blendB = pm.createNode('blendColors', n=locB+'_blendPos_bld')
    pma.output3D >> blendB.color1
    pociB >> blendB.color2
    blinkAttr >> blendB.blender
    blendB.output >> locB.t
    def test_export_network(self, epsilon=0.00001):
        pynode_a = pymel.createNode('transform')
        pynode_b = pymel.createNode('transform')

        old_instance = A()
        old_instance.ex_int = 42
        old_instance.ex_float = 3.14159
        old_instance.ex_str = 'Hello World'
        old_instance.ex_None = None
        old_instance.ex_list_pynode = [None, pynode_a, None, pynode_b]

        #
        # Ensure consistency when exporting to network
        #
        n = libSerialization.export_network(old_instance)
        network_ex_int = n.ex_int.get()
        network_ex_float = n.ex_float.get()
        network_ex_str = n.ex_str.get()
        self.assertTrue(network_ex_int == old_instance.ex_int)
        self.assertTrue(abs(network_ex_float- old_instance.ex_float) < epsilon)
        self.assertTrue(network_ex_str == old_instance.ex_str)

        # Note: libSerialization will NEVER export a None value since the type cannot be resolved.
        self.assertTrue(not n.hasAttr('ex_None'))

        #
        # Ensure consistency when importing from network
        #
        new_instance = libSerialization.import_network(n)
        self.assertTrue(network_ex_int == new_instance.ex_int)
        self.assertTrue(abs(network_ex_float- new_instance.ex_float) < epsilon)
        self.assertTrue(network_ex_str == new_instance.ex_str)
def transfer_shape(source, target, flip=True):
    """it will replace the shape of selected number 2 with the shapes of selected number 1"""

    target_shape = target.getShape(noIntermediate=True)
    target_shape_orig = get_orig_shape(target_shape)

    dup = pymel.duplicate(source, rc=1)[0]
    tmp = pymel.createNode('transform')
    pymel.parent(tmp, dup)
    pymel.xform(tmp, t=(0, 0, 0), ro=(0, 0, 0), scale=(1, 1, 1))
    pymel.parent(tmp, w=1)
    for sh in dup.getShapes(noIntermediate=True):
        pymel.parent(sh, tmp, r=1, s=1)

    pymel.delete(dup)
    temp_grp_negScale = pymel.createNode('transform')
    pymel.parent(tmp, temp_grp_negScale)
    if flip:
        temp_grp_negScale.scaleX.set(-1)

    pymel.parent(tmp, target)
    pymel.delete(temp_grp_negScale)

    pymel.makeIdentity(tmp, t=True)  # this brings translate values at 0 before scale freezing
    pymel.makeIdentity(tmp, apply=True, t=True, r=True, s=True)
    pymel.parent(tmp, w=1)

    color_info, vis_master = get_previous_controller_info(target)

    shapes_has_been_deleted = False
    for sh in tmp.getShapes():
        if target_shape_orig:
            adapt_to_orig_shape(sh, target.getShape())
        else:
            if not shapes_has_been_deleted:
                shapesDel = target.getShapes()
                if shapesDel: pymel.delete(shapesDel)
                shapes_has_been_deleted = True

            pymel.parent(sh, target, r=1, s=1)
            pymel.rename(sh.name(), target.name() + "Shape")

            if color_info[0]:
                if color_info[1]:
                    sh.overrideEnabled.set(True)
                    sh.overrideRGBColors.set(1)
                    sh.overrideColorRGB.set(color_info[2])

                else:
                    sh.overrideEnabled.set(True)
                    sh.overrideRGBColors.set(0)
                    sh.overrideColor.set(color_info[2])

            else:
                sh.overrideEnabled.set(False)

            if vis_master:
                vis_master.connect(sh.visibility)

    pymel.delete(tmp)
Beispiel #21
0
def create_copier(in_meshes, name='out_geo#', in_array=None, rotate=True):

    # Create output mesh
    out_shape = pm.createNode('mesh')
    out_xform = out_shape.getParent()
    out_xform.rename(name)

    # Create copier node
    copier = pm.createNode('copier')
    copier.orient.set(1)
    copier.toggleUV.set(1)
    copier.outputMesh.connect(out_shape.inMesh)

    # Connect input meshes
    for i, mesh in enumerate(in_meshes):
        shape = mesh.getShape(noIntermediate=True)
        shape.worldMesh[0].connect(copier.inputMesh[i])

    if not in_array:
        # Connect input transforms
        array = pm.createNode('transformsToArrays')
    else:
        array = in_array

    array.outPositionPP.connect(copier.posArray)
    if rotate:
        array.outRotationPP.connect(copier.rotArray)

    return out_xform, copier, array
Beispiel #22
0
def addAOV( aovName, aovType = None ):
	"""docstring for addAov"""
	if aovType is None:
		aovType = aovs.getAOVTypeMap().get(aovName, 'rgba')
	if not isinstance(aovType, int):
		aovType = dict(aovs.TYPES)[aovType]
	aovNode = pm.createNode('aiAOV', name='aiAOV_' + aovName, skipSelect=True)
	out = aovNode.attr('outputs')[0]

	pm.connectAttr('defaultArnoldDriver.message', out.driver)
	filter = aovs.defaultFiltersByName.get(aovName, None)
	if filter:
		node = pm.createNode('aiAOVFilter', skipSelect=True)
		node.aiTranslator.set(filter)
		filterAttr = node.attr('message')
		import mtoa.hooks as hooks
		hooks.setupFilter(filter, aovName)
	else:
		filterAttr = 'defaultArnoldFilter.message'
	pm.connectAttr(filterAttr, out.filter)

	aovNode.attr('name').set(aovName)
	aovNode.attr('type').set(aovType)
	base = pm.PyNode('defaultArnoldRenderOptions')
	aovAttr = base.aovs
	nextPlug = aovAttr.elementByLogicalIndex(aovAttr.numElements())
	aovNode.message.connect(nextPlug)
	aov = aovs.SceneAOV(aovNode, nextPlug)
	return aov
Beispiel #23
0
def closestEndOrStartVertToSurface(targetSurface, transforms):
	'''
	Usage:
		closestEndOrStartVertToSurface(pm.PyNode('r_hand_GEO'), pm.ls(sl=True))
	'''
	cpom = pm.createNode('closestPointOnMesh')
	distBet = pm.createNode('distanceBetween')
	targetSurface.outMesh.connect(cpom.inMesh)
	for transform in transforms:
		closestPointAndVert = {}
		loc = pm.spaceLocator(n=transform.name().replace('GEO','LOC'))
		
		loc.translate.set( transform.getShape().vtx[-1].getPosition() )
		cpom.inPosition.set(loc.translate.get())
		closestVert = cpom.closestVertexIndex.get()
		closestPosEnd = targetSurface.vtx[cpom.closestVertexIndex.get()].getPosition()
		distBet.point1.set( closestPosEnd )
		distBet.point2.set( loc.translate.get() )
		distToEnd = distBet.distance.get()
		closestPointAndVert[distToEnd] = [closestVert, closestPosEnd]
		
		loc.translate.set( transform.getShape().vtx[0].getPosition() )
		cpom.inPosition.set(loc.translate.get())
		closestVert = cpom.closestVertexIndex.get()
		closestPosStart = targetSurface.vtx[cpom.closestVertexIndex.get()].getPosition()
		distBet.point1.set( closestPosStart )
		distBet.point2.set( loc.translate.get() )
		distToStart = distBet.distance.get()
		closestPointAndVert[distToStart] = [closestVert, closestPosEnd]
		
		loc.translate.set( closestPointAndVert[ min(distToStart, distToEnd) ][1] )
Beispiel #24
0
def _gather_exported_alembic_info_():
    cmds.loadPlugin("AbcImport.mll", quiet=True)

    template_obj, fields, tk = _get_shotgun_fields_from_file_name_()

    if not pm.objExists("animatedAlembicGroup"):
        pm.createNode("transform", name="animatedAlembicGroup")

    temp, fields, tk = _get_shotgun_fields_from_file_name_()
    masterAlembicTemplate = tk.templates["master_alembic_cache"]

    alembicFolder = libFile.get_parent_folder(masterAlembicTemplate.apply_fields(fields))

    # Get all the abc files

    exported_alemblic_info = {}
    if libFile.exists(alembicFolder):
        for alembicFile in libFile.listfiles(alembicFolder, "abc"):
            alembicFilePath = libFile.join(alembicFolder, alembicFile)

            # Edited by Chet 
            # Project Kitten Witch 25 May 2016
            # ========================================================
            # Old code that was causing the list of alembics to build
            # niceName =  alembicFile.split(".")[0].split("_")[]

            niceName =  alembicFile.split(".")[0]
            niceName = niceName.split("_")
            niceName = " ".join(niceName[1:])
            exported_alemblic_info[niceName] = alembicFilePath
    return exported_alemblic_info
Beispiel #25
0
    def _setup_node(self, *args, **kwargs):
        """Setup and return the node
        @param args <list> Storing args from config file as list
        @param kwargs <dict> Storing keyword args from config file as dict
        @DONE use logging instead of printing
        """
        node = None
        if args:
            if args[0] == help:
                msg = "\nValid parameters for the %s node:" % self._nodename
                logging.debug(msg)
                for n in self._nodes[self._nodename].items():
                    if not n[0] == '__ABBREVIATION__':
                        logging.debug('-- %s : <%s>' % (n[0], n[1]))
                    # end if exclude abbreviation
                # end for print parameters and types
                return
            # end if help or set name
            if not self.suffix:
                self.suffix = self._nodes[self._nodename]['__ABBREVIATION__']
            # end if not suffix given use abbreviation list
            name = '%s_%s_%s' % (self.side, args[0], self.suffix)
            node = pm.createNode(self._nodename, n=name)
        else:
            node = pm.createNode(self._nodename)
        # end if args exists

        self._setup_attribute(node, **kwargs)
        self.suffix = None
        return node
def orientPlacerOnLoop(pLoc, beforeObj=None, afterObj=None):
    """
    assume pLocs are all in the same space!
    so we don't need to calc worldspace positions!
    
    at this time, aimVec is always +y-axis
    and upVec is always +x-axis
    """

    # create vectors pmas
    if beforeObj:
        beforePma = getVectorBetweenTwoPlacers(beforeObj, pLoc)
        xAxis = beforePma.output3D
    if afterObj:
        afterPma = getVectorBetweenTwoPlacers(pLoc, afterObj)
        xAxis = afterPma.output3D

    # calculate vectors if blend is needed
    if beforeObj and afterObj:
        # slerp blend between the two vectors
        slerp = pm.createNode("animBlendNodeAdditiveRotation", n=pLoc + "_blendBeforeAndAfterVec_slerp")
        beforePma.output3D >> slerp.inputA
        afterPma.output3D >> slerp.inputB
        xAxis = slerp.output

    # yAxis is always (0,1,0)
    # now we also know xAxis
    # calculate zAxis
    zAxisVpd = pm.createNode("vectorProduct", n=pLoc + "_calcZAxis_vpd")
    xAxis >> zAxisVpd.input1
    zAxisVpd.input2.set(0, 1, 0)
    zAxisVpd.operation.set(2)
    zAxis = zAxisVpd.output

    # construct a matrix in worldSpace
    wsMat = pm.createNode("fourByFourMatrix", n=pLoc + "_wsFbfm")
    # x-vector
    try:
        xAxis.outputX >> wsMat.in00
        wsMat.in01.set(0)
        xAxis.outputZ >> wsMat.in02
    except AttributeError:
        xAxis.output3Dx >> wsMat.in00
        wsMat.in01.set(0)
        xAxis.output3Dz >> wsMat.in02

    # y-vector
    wsMat.in10.set(0)
    wsMat.in11.set(1)
    wsMat.in12.set(0)
    # z-vector
    zAxis.outputX >> wsMat.in20
    zAxis.outputY >> wsMat.in21
    zAxis.outputZ >> wsMat.in22

    # decompose
    dcm = pm.createNode("decomposeMatrix", n=pLoc + "_orientMat_dcm")
    wsMat.output >> dcm.inputMatrix
    dcm.outputRotate >> pLoc.r
Beispiel #27
0
def createOptions():
    """
    override this with your own function to set defaults
    """
    import mtoa.aovs as aovs
    import mtoa.hooks as hooks

    # the shared option ensures that it is only created if it does not exist
    options = pm.createNode('aiOptions', skipSelect=True, shared=True, name='defaultArnoldRenderOptions')
    filterNode = pm.createNode('aiAOVFilter', name='defaultArnoldFilter', skipSelect=True, shared=True)
    driverNode = pm.createNode('aiAOVDriver', name='defaultArnoldDriver', skipSelect=True, shared=True)
    displayDriverNode = pm.createNode('aiAOVDriver', name='defaultArnoldDisplayDriver', skipSelect=True, shared=True)

    if (filterNode or driverNode) and not options:
        options = pm.PyNode('defaultArnoldRenderOptions')
        # options previously existed, so we need to upgrade
        upgradeAOVOutput(options, filterNode, driverNode)

    # if we're just creating the options node, then be sure to connect up the driver and filter
    if filterNode:
        # newly created default filter
        hooks.setupFilter(filterNode)
    else:
        filterNode = pm.PyNode('defaultArnoldFilter')

    if driverNode:
        # newly created default driver
        hooks.setupDriver(driverNode)
    else:
        driverNode = pm.PyNode('defaultArnoldDriver')

    if options:
        # newly created options
        hooks.setupDefaultAOVs(aovs.AOVInterface(options))
        hooks.setupOptions(options)
        pm.setAttr('defaultArnoldRenderOptions.version', str(cmds.pluginInfo( 'mtoa', query=True, version=True)))
    else:
        options = pm.PyNode('defaultArnoldRenderOptions')
        if displayDriverNode:
            # options exist, but not display driver: upgrade from older version of mtoa
            hooks.setupDefaultAOVs(aovs.AOVInterface(options))

    if displayDriverNode:
        # newly created default driver
        displayDriverNode.aiTranslator.set('maya')
        # GUI only
        displayDriverNode.outputMode.set(0)
        hooks.setupDriver(displayDriverNode)
        displayDriverNode.message.connect(options.drivers, nextAvailable=True)
    elif not options.drivers.inputs():
        pm.connectAttr('defaultArnoldDisplayDriver.message', options.drivers, nextAvailable=True)
    try:
        pm.connectAttr('%s.message' % filterNode.name(), '%s.filter' % options.name(), force=True)
    except:
        pass
    try:
        pm.connectAttr('%s.message' % driverNode.name(), '%s.driver' % options.name(), force=True)
    except:
        pass
Beispiel #28
0
 def loadStandins(self):
     meshName = self.path.split("/")[-1].replace(".binarymesh", "")
     standInMesh = pm.createNode("mesh")
     standInMesh.getParent().rename(meshName + "_standIn")
     standInMeshNode = pm.createNode("mtap_standinMeshNode")
     standInMeshNode.rename(meshName + "_standInCreator")
     standInMeshNode.binMeshFile.set(self.path)
     standInMeshNode.outputMesh >> standInMesh.inMesh
Beispiel #29
0
    def _ctrlDBL(self, controls):
        
        pmc.undoInfo(openChunk=True)
        
        if controls == []:
            controls = pmc.ls(sl=True)

        for control in controls:
            control_roo = pmc.xform(control, q=True, roo=True)
            control_mtx = pmc.xform(control, q=True, m=True, ws=True)
            control_parent = pmc.listRelatives(control, p=True)
            pmc.select(cl=True)
            
            locdbl_parent = pmc.spaceLocator(n='locDBL_parent_' + control)
            locdbl_offset = pmc.spaceLocator(n='locDBL_offset_' + control)

            pmc.xform(locdbl_parent, ws=True, m=control_mtx)
            pmc.xform(locdbl_offset, ws=True, m=control_mtx)
                
            pmc.parent(locdbl_offset, locdbl_parent)
            pmc.parent(locdbl_parent, control_parent)
            pmc.parent(control, locdbl_offset)
            
            if control_roo == 'xyz':
                pmc.xform(locdbl_offset, roo='zyx')
            if control_roo == 'yzx':
                pmc.xform(locdbl_offset, roo='xzy')        
            if control_roo == 'zxy':
                pmc.xform(locdbl_offset, roo='yxz')        
            if control_roo == 'xzy':
                pmc.xform(locdbl_offset, roo='yzx')
            if control_roo == 'yxz':
                pmc.xform(locdbl_offset, roo='zxy')            
            if control_roo == 'zyx':
                pmc.xform(locdbl_offset, roo='xyz')
                            
            md_trns = pmc.createNode('multiplyDivide', n='mdTRNS_locDBL_' + control)
            md_rot = pmc.createNode('multiplyDivide', n='mdROT_locDBL_' + control)
            md_scl = pmc.createNode('multiplyDivide', n='mdSCL_locDBL_' + control)
            
            pmc.setAttr(md_trns + '.input1', [-1,-1,-1])
            pmc.setAttr(md_rot.input1, [-1,-1,-1])
            pmc.setAttr(md_scl.input1, [ 1, 1, 1])
            pmc.setAttr(md_scl.operation, 2)

            
            pmc.connectAttr(control + '.translate', md_trns + '.input2')
            pmc.connectAttr(control + '.rotate', md_rot + '.input2')
            pmc.connectAttr(control + '.scale', md_scl + '.input2')
            
            pmc.connectAttr(md_trns + '.output', locdbl_offset + '.translate')
            pmc.connectAttr(md_rot + '.output', locdbl_offset + '.rotate')
            pmc.connectAttr(md_scl + '.output', locdbl_offset + '.scale')
            
            pmc.setAttr(locdbl_parent + 'Shape.visibility', 0)
            pmc.setAttr(locdbl_offset + 'Shape.visibility', 0)
            
        pmc.undoInfo(closeChunk=True)
Beispiel #30
0
    def connectChains(self,*args):
        """
            Set elbows to only rotate in one axis, the upAxis.
            Create blend color nodes and connect ik/fk/bind joint chains.
        """

        #Shoulder blendColors creation
        self.shldr_node1 = pm.PyNode((pm.createNode( 'blendColors' )).rename('%s_shldrRotate' % self.prefix))

        #shldr_node1 attributes to connect
        self.ikChain[0].rotate >> self.shldr_node1.color1
        self.fkChain[0].rotate >> self.shldr_node1.color2
        self.shldr_node1.output >> self.jointChain[0].rotate

        #elbow1 blendColors creation
        self.elbow1_node1 = pm.PyNode((pm.createNode( 'blendColors' )).rename('%s_elbow1Rotate' % self.prefix))
        self.elbow1_node2 = pm.PyNode((pm.createNode( 'blendColors' )).rename('%s_elbow1Translate' % self.prefix))

        #elbow1_node1 attributes to connect
        self.ikChain[1].rotate >> self.elbow1_node1.color1
        self.fkChain[1].rotate >> self.elbow1_node1.color2
        self.elbow1_node1.output >> self.jointChain[1].rotate        
        
        #elbow1_node2 attributes to connect
        self.ikChain[1].translate >> self.elbow1_node2.color1
        self.fkChain[1].translate >> self.elbow1_node2.color2
        self.elbow1_node2.output >> self.jointChain[1].translate          

        #wrist blendColors creation
        self.wrist_node1 = pm.PyNode((pm.createNode( 'blendColors' )).rename('%s_elbow1Rotate' % self.prefix))
        self.wrist_node2 = pm.PyNode((pm.createNode( 'blendColors' )).rename('%s_elbow1Translate' % self.prefix))

        #wrist_node1 attributes to connect
        self.ikChain[2].rotate >> self.wrist_node1.color1
        self.fkChain[2].rotate >> self.wrist_node1.color2
        self.wrist_node1.output >> self.jointChain[2].rotate        
        
        #wrist_node2 attributes to connect
        self.ikChain[2].translate >> self.wrist_node2.color1
        self.fkChain[2].translate >> self.wrist_node2.color2
        self.wrist_node2.output >> self.jointChain[2].translate  

        #Lock elbow axis
        if self.up == 1:
            pm.setAttr('%s.rotateY'%self.fkChain[1],lock=True,k=False) 
            pm.setAttr('%s.rotateZ'%self.fkChain[1],lock=True,k=False) 
            pm.setAttr('%s.rotateY'%self.ikChain[1],lock=True,k=False) 
            pm.setAttr('%s.rotateZ'%self.ikChain[1],lock=True,k=False) 
        if self.up == 2:
            pm.setAttr('%s.rotateX'%self.fkChain[1],lock=True,k=False) 
            pm.setAttr('%s.rotateZ'%self.fkChain[1],lock=True,k=False) 
            pm.setAttr('%s.rotateX'%self.ikChain[1],lock=True,k=False) 
            pm.setAttr('%s.rotateZ'%self.ikChain[1],lock=True,k=False) 
        if self.up == 3:
            pm.setAttr('%s.rotateY'%self.fkChain[1],lock=True,k=False) 
            pm.setAttr('%s.rotateX'%self.fkChain[1],lock=True,k=False) 
            pm.setAttr('%s.rotateY'%self.ikChain[1],lock=True,k=False) 
            pm.setAttr('%s.rotateX'%self.ikChain[1],lock=True,k=False)     
Beispiel #31
0
def RigBendyLimb(**kwargs):
    jnts = kwargs.setdefault('jnts')
    volume = kwargs.setdefault('volume', False)
    limbName = kwargs.setdefault('limbName', 'arm')
    side = kwargs.setdefault('side', 'L')
    numOfSegs = kwargs.setdefault('numOfSegs', 5)
    FKIKMode = kwargs.setdefault('FKIKMode', 'FKIK')
    bendyCtrl = kwargs.setdefault('bendyCtrl')
    isMirroredJoint = kwargs.setdefault('isMirroredJoint', False)

    if not (jnts and bendyCtrl):
        objects = pm.ls(sl=True)
        if not len(objects) == 4:
            pm.error(
                'ehm_tools...rigBendyLimb: select 3 joint and a control curve')
        uparmJnt = objects[0]
        elbowJnt = objects[1]
        handJnt = objects[2]
        bendyCtrl = objects[3]
    else:
        uparmJnt = jnts[0]
        elbowJnt = jnts[1]
        handJnt = jnts[2]

    # if limb is not straight, make it so. necessary for for skinning bendy curves.
    if not FKIKMode == "IK":
        tempElbowOri = elbowJnt.jointOrient.get()
        elbowJnt.jointOrient.set(0, 0, 0)
    else:  # find position for putting the ik so that arm gets straight
        tempHandIKLoc = pm.spaceLocator()
        pm.parent(tempHandIKLoc, uparmJnt)
        tempHandIKLoc.rotate.set(0, 0, 0)
        armLen = elbowJnt.translate.translateX.get(
        ) + handJnt.translate.translateX.get()
        tempHandIKLoc.translate.set(armLen, 0, 0)
        tempHandIKPos = pm.xform(tempHandIKLoc,
                                 q=True,
                                 ws=True,
                                 translation=True)
        pm.parent(IKarmDistLocs[1], w=True)
        # straighten the arm for skinning
        IKarmDistLocs[1].translate.set(tempHandIKPos)

    # create bendy joint
    uparmSegStuff = Segmentor(jnt=uparmJnt,
                              numOfSegs=numOfSegs,
                              volume=volume,
                              thicknessPlace='end',
                              isMirroredJoint=isMirroredJoint)

    elbowSegStuff = Segmentor(jnt=elbowJnt,
                              numOfSegs=numOfSegs,
                              volume=volume,
                              thicknessPlace='start',
                              isMirroredJoint=isMirroredJoint)

    # avoid shear on elbow seg joints
    pm.scaleConstraint(uparmJnt, elbowSegStuff[1][2].getParent())

    # create the uparm orientaion loc, point and aim constraint it so that it aims to hand joint
    uparmOriLoc = pm.spaceLocator()
    pm.pointConstraint(uparmJnt, uparmOriLoc)
    pm.aimConstraint(handJnt, uparmOriLoc)

    # create the elbow orientation loc, connect it to uparm ori loc and elbow joint
    elbowOriLoc = pm.spaceLocator()
    pm.pointConstraint(elbowJnt, elbowOriLoc)
    pm.orientConstraint(uparmOriLoc, elbowOriLoc)

    # move second and forth CVs of the bendy curves very close to where joints are.
    uparm_seg_crv = uparmSegStuff[1][2]
    elbow_seg_crv = elbowSegStuff[1][2]

    closeToUparm = FindPosBetween(percent=1, base=uparmJnt, tip=elbowJnt)
    closeToElbow = FindPosBetween(percent=99, base=uparmJnt, tip=elbowJnt)
    closeToElbowAfter = FindPosBetween(percent=1, base=elbowJnt, tip=handJnt)
    closeToHand = FindPosBetween(percent=99, base=elbowJnt, tip=handJnt)

    pm.xform(uparm_seg_crv.cv[1], ws=True, t=closeToUparm)
    pm.xform(uparm_seg_crv.cv[3], ws=True, t=closeToElbow)
    pm.xform(elbow_seg_crv.cv[1], ws=True, t=closeToElbowAfter)
    pm.xform(elbow_seg_crv.cv[3], ws=True, t=closeToHand)

    # create joints, sking to bendy curves and parent the middle one under elbow ori loc.
    bendyJnts_dict = {'one': uparmJnt, 'two': elbowJnt, 'three': handJnt}

    for i in bendyJnts_dict.keys():
        pm.select(clear=True)
        tmp = pm.joint(name='%s_%s_bendy_%s_jnt' % (side, limbName, i))
        tmp.setParent(bendyJnts_dict[i])
        tmp.translate.set(0, 0, 0)
        bendyJnts_dict[i] = tmp

    bendyJnts_dict['two'].setParent(elbowOriLoc)

    # skin the seg_crvs and set the weights
    uparm_seg_crv_skinCluster = (pm.skinCluster(uparm_seg_crv,
                                                bendyJnts_dict['one'],
                                                bendyJnts_dict['two'],
                                                toSelectedBones=True))
    elbow_seg_crv_skinCluster = (pm.skinCluster(elbow_seg_crv,
                                                bendyJnts_dict['two'],
                                                bendyJnts_dict['three'],
                                                toSelectedBones=True))

    pm.skinPercent(uparm_seg_crv_skinCluster, (uparm_seg_crv + ".cv[2:4]"),
                   transformValue=(bendyJnts_dict['two'], 1))
    pm.skinPercent(elbow_seg_crv_skinCluster, (elbow_seg_crv + ".cv[0:2]"),
                   transformValue=(bendyJnts_dict['two'], 1))

    pm.skinPercent(uparm_seg_crv_skinCluster, (uparm_seg_crv + ".cv[0:1]"),
                   transformValue=(bendyJnts_dict['two'], 0))
    pm.skinPercent(elbow_seg_crv_skinCluster, (elbow_seg_crv + ".cv[3:4]"),
                   transformValue=(bendyJnts_dict['two'], 0))

    # setting the twist parameters for the segmenty joints

    # add bendy attribute to finger ctrl and connect it
    if not pm.attributeQuery('bendy', n=bendyCtrl, exists=True):
        try:
            pm.addAttr(bendyCtrl, ln="bendy", at='double', min=0, dv=0)
            pm.setAttr(bendyCtrl.bendy, e=True, keyable=True)
        except:
            pm.error(
                'ehm_tools...rigBendyLimb: could not add bendy attr to %s' %
                bendyCtrl)

    # slow down the bendy attribute by 10 times
    bendySlower_mdn = pm.createNode('multiplyDivide',
                                    name='%s_%s_bendySlower_mdn' %
                                    (side, limbName))
    bendyCtrl.bendy >> bendySlower_mdn.input1X
    bendySlower_mdn.input2X.set(0.1)
    bendySlower_mdn.outputX >> elbowOriLoc.scaleX

    # set the limb back to it's old position.
    if not FKIKMode == "IK":
        elbowJnt.jointOrient.set(tempElbowOri)
    else:
        pm.parent(IKarmDistLocs[1], handIKCtrl)
        IKarmDistLocs[1].translate.set(0, 0, 0)

    segStuffGrp = pm.group(uparmSegStuff[2],
                           elbowSegStuff[2],
                           name='%s_%s_bendyStuff_grp' % (side, limbName))
    pm.xform(os=True, piv=(0, 0, 0))
    # return
    return (uparmSegStuff, elbowSegStuff, segStuffGrp)
Beispiel #32
0
def bs_createModelBase(topGroup,
                       assetName,
                       assetGrade,
                       assetType,
                       episode=None,
                       makeGroups=True):
    """
    @ create asset model
    @ make modeling base hierarchy and add attributes on top group for query purpose.
    Args:
        topGroup (str): Hierarchy Top Group Name.
        assetName (str): Asset Name.
        assetGrade (str): Character Grade (Primary, Secondary, Tertiary).
        assetType (str): Asset Type Character, Prop, Set, Vehicle.
        episode (str): episode number like (ep000,ep001,ep002) format.
        makeGroups (bool): make groups if value is True

    Returns:
            topGrp.
    """
    # raise popup window for current scene will be discarded if maya is not in batch mode.
    if not pm.about(batch=True):
        confirmation = pm.windows.confirmDialog(
            title='Confirm',
            message="Don't Save Current Scene\nAnd Load New Scene?",
            button=['Yes', 'No'],
            defaultButton='Yes')
        if confirmation == 'Yes':
            pm.newFile(f=True)
        else:
            print 'process cancelled',
            return False
    # create group if make hierarchy is True.
    astTypShortCode = {
        'Character': 'ch',
        'Prop': 'pr',
        'Set': 'bg',
        'Vehicle': 'vh',
        'SetElement': 'se'
    }
    if bs_pathGenerator.bs_getEnv()['projectType'] == 'series':
        uid = 'bsw_' + astTypShortCode[
            assetType] + '_' + assetName + '_mod_' + episode
    else:
        uid = 'bsw_' + astTypShortCode[assetType] + '_' + assetName + '_mod'
    pm.select(cl=True)
    if makeGroups:
        # make groups.
        topGrp = pm.createNode('transform', n=topGroup, ss=True)
        modelGrp = pm.createNode('transform', n=assetName + '_grp', ss=True)
        if assetType == 'Character':
            bodyGrp = pm.createNode('transform', n='body_grp', ss=True)
            eyeGrp = pm.createNode('transform', n='eye_grp', ss=True)
            eyeBrowGrp = pm.createNode('transform', n='eyeBrow_grp', ss=True)
            innerMouthGrp = pm.createNode('transform',
                                          n='innerMouth_grp',
                                          ss=True)
            hairGrp = pm.createNode('transform', n='hair_grp', ss=True)
            clothGrp = pm.createNode('transform', n='cloth_grp', ss=True)
            propsGrp = pm.createNode('transform', n='props_grp', ss=True)
            shoeGrp = pm.createNode('transform', n='shoe_grp', ss=True)
            # make parent.
            pm.parent(bodyGrp, clothGrp, propsGrp, shoeGrp, modelGrp)
            pm.parent(eyeGrp, eyeBrowGrp, innerMouthGrp, hairGrp, bodyGrp)
        elif assetType == 'Set':
            setElementGrp = pm.createNode('transform', n='setElements_grp')
            pm.parent(modelGrp, setElementGrp, topGrp)
        pm.parent(modelGrp, topGrp)
    else:
        topGrp = topGroup
    # add attributes for query asset details purpose.
    pm.addAttr(topGrp, ln='assetBase', dt='string', k=True)
    pm.addAttr(topGrp, ln='assetType', dt='string', k=True)
    pm.addAttr(topGrp, ln='assetName', dt='string', k=True)
    pm.addAttr(topGrp, ln='assetGrade', dt='string', k=True)
    if bs_pathGenerator.bs_getEnv()['projectType'] == 'series':
        pm.addAttr(topGrp, ln='assetEpisode', dt='string', k=True)
    pm.addAttr(topGrp, ln='assetUID', dt='string', k=True)
    # add asset details in top group attributes.
    pm.setAttr(topGrp + '.assetBase', 'Asset')
    pm.setAttr(topGrp + '.assetBase', l=True)
    pm.setAttr(topGrp + '.assetType', assetType)
    pm.setAttr(topGrp + '.assetType', l=True)
    pm.setAttr(topGrp + '.assetName', assetName)
    pm.setAttr(topGrp + '.assetName', l=True)
    pm.setAttr(topGrp + '.assetGrade', assetGrade)
    pm.setAttr(topGrp + '.assetGrade', l=True)
    if bs_pathGenerator.bs_getEnv()['projectType'] == 'series':
        pm.setAttr(topGrp + '.assetEpisode', episode)
        pm.setAttr(topGrp + '.assetEpisode', l=True)
    pm.setAttr(topGrp + '.assetUID', uid)
    pm.setAttr(topGrp + '.assetUID', l=True)
    pm.select(topGrp, r=True)
    if bs_pathGenerator.bs_getEnv()['projectType'] == 'series':
        bs_pathGenerator.bs_createAssetDirectories(assetType,
                                                   assetName,
                                                   episode=episode)
    else:
        bs_pathGenerator.bs_createAssetDirectories(assetType, assetName)
    bs_qui.bs_displayMessage('success', 'Asset Created Successfully....')
    return topGrp
Beispiel #33
0
    def addJoint(self,
                 obj,
                 name,
                 newActiveJnt=None,
                 UniScale=False,
                 segComp=0,
                 gearMulMatrix=True):
        """Add joint as child of the active joint or under driver object.

        Args:
            obj (dagNode): The input driver object for the joint.
            name (str): The joint name.
            newActiveJnt (bool or dagNode): If a joint is pass, this joint will
                be the active joint and parent of the newly created joint.
            UniScale (bool): Connects the joint scale with the Z axis for a
                unifor scalin, if set Falsewill connect with each axis
                separated.
            segComp (bool): Set True or False the segment compensation in the
                joint..
            gearMulMatrix (bool): Use the custom gear_multiply matrix node, if
                False will use Maya's default mulMatrix node.

        Returns:
            dagNode: The newly created joint.

        """

        customName = self.getCustomJointName(len(self.jointList))

        if self.options["joint_rig"]:
            if newActiveJnt:
                self.active_jnt = newActiveJnt

            jnt = primitive.addJoint(self.active_jnt, 
                customName or self.getName(str(name) + "_jnt"), 
                transform.getTransform(obj))

            # Disconnect inversScale for better preformance
            if isinstance(self.active_jnt, pm.nodetypes.Joint):
                try:
                    pm.disconnectAttr(self.active_jnt.scale, jnt.inverseScale)

                except RuntimeError:
                    # This handle the situation where we have in between joints
                    # transformation due a negative scaling
                    pm.ungroup(jnt.getParent())
            # All new jnts are the active by default
            self.active_jnt = jnt

            if gearMulMatrix:
                mulmat_node = applyop.gear_mulmatrix_op(
                    obj + ".worldMatrix", jnt + ".parentInverseMatrix")
                dm_node = node.createDecomposeMatrixNode(
                    mulmat_node + ".output")
                m = mulmat_node.attr('output').get()
            else:
                mulmat_node = node.createMultMatrixNode(
                    obj + ".worldMatrix", jnt + ".parentInverseMatrix")
                dm_node = node.createDecomposeMatrixNode(
                    mulmat_node + ".matrixSum")
                m = mulmat_node.attr('matrixSum').get()
            pm.connectAttr(dm_node + ".outputTranslate", jnt + ".t")
            pm.connectAttr(dm_node + ".outputRotate", jnt + ".r")
            # TODO: fix squash stretch solver to scale the joint uniform
            # the next line cheat the uniform scaling only fo X or Y axis
            # oriented joints
            if self.options["force_uniScale"]:
                UniScale = True

            # invert negative scaling in Joints. We only inver Z axis, so is
            # the only axis that we are checking
            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")

            # connect scaling
            if UniScale:
                pm.connectAttr(out_val, jnt + ".sx")
                pm.connectAttr(out_val, jnt + ".sy")
                pm.connectAttr(out_val, jnt + ".sz")
            else:
                pm.connectAttr(dm_node.attr("outputScaleX"), jnt + ".sx")
                pm.connectAttr(dm_node.attr("outputScaleY"), jnt + ".sy")
                pm.connectAttr(out_val, jnt + ".sz")
                pm.connectAttr(dm_node + ".outputShear", jnt + ".shear")

            # Segment scale compensate Off to avoid issues with the global
            # scale
            jnt.setAttr("segmentScaleCompensate", segComp)

            jnt.setAttr("jointOrient", 0, 0, 0)

            # setting the joint orient compensation in order to have clean
            # rotation channels
            jnt.attr("jointOrientX").set(jnt.attr("rx").get())
            jnt.attr("jointOrientY").set(jnt.attr("ry").get())
            jnt.attr("jointOrientZ").set(jnt.attr("rz").get())

            im = m.inverse()

            if gearMulMatrix:
                mul_nod = applyop.gear_mulmatrix_op(
                    mulmat_node.attr('output'), im, jnt, 'r')
                dm_node2 = mul_nod.output.listConnections()[0]
            else:
                mul_nod = node.createMultMatrixNode(
                    mulmat_node.attr('matrixSum'), im, jnt, 'r')
                dm_node2 = mul_nod.matrixSum.listConnections()[0]

            # if jnt.attr("sz").get() < 0:
            if dm_node.attr("outputScaleZ").get() < 0:
                # if negative scaling we have to negate some axis for rotation
                neg_rot_node = pm.createNode("multiplyDivide")
                pm.setAttr(neg_rot_node + ".operation", 1)
                pm.connectAttr(dm_node2.outputRotate,
                               neg_rot_node + ".input1",
                               f=True)
                for v, axis in zip([-1, -1, 1], "XYZ"):
                    pm.setAttr(neg_rot_node + ".input2" + axis, v)
                pm.connectAttr(neg_rot_node + ".output",
                               jnt + ".r",
                               f=True)

            # set not keyable
            attribute.setNotKeyableAttributes(jnt)

        else:
            jnt = primitive.addJoint(obj, 
                customName or self.getName(str(name) + "_jnt"), 
                transform.getTransform(obj))
            pm.connectAttr(self.rig.jntVis_att, jnt.attr("visibility"))
            attribute.lockAttribute(jnt)

        self.addToGroup(jnt, "deformers")

        # This is a workaround due the evaluation problem with compound attr
        # TODO: This workaround, should be removed onces the evaluation issue
        # is fixed
        # github issue: Shifter: Joint connection: Maya evaluation Bug #210
        dm = jnt.r.listConnections(p=True, type="decomposeMatrix")
        if dm:
            at = dm[0]
            dm_node = at.node()
            pm.disconnectAttr(at, jnt.r)
            pm.connectAttr(dm_node.outputRotateX, jnt.rx)
            pm.connectAttr(dm_node.outputRotateY, jnt.ry)
            pm.connectAttr(dm_node.outputRotateZ, jnt.rz)

        dm = jnt.t.listConnections(p=True, type="decomposeMatrix")
        if dm:
            at = dm[0]
            dm_node = at.node()
            pm.disconnectAttr(at, jnt.t)
            pm.connectAttr(dm_node.outputTranslateX, jnt.tx)
            pm.connectAttr(dm_node.outputTranslateY, jnt.ty)
            pm.connectAttr(dm_node.outputTranslateZ, jnt.tz)

        # dm = jnt.s.listConnections(p=True, type="decomposeMatrix")
        # if dm:
        #     at = dm[0]
        #     dm_node = at.node()
        #     pm.disconnectAttr(at, jnt.s)
        #     pm.connectAttr(dm_node.outputScaleX, jnt.sx)
        #     pm.connectAttr(dm_node.outputScaleY, jnt.sy)
        #     pm.connectAttr(dm_node.outputScaleZ, jnt.sz)

        return jnt
def MakeSplineStretchy(**kwargs):
    thicknessPlace = kwargs.setdefault('thicknessPlace', 'mid')
    stretchSwitch = kwargs.setdefault('stretchSwitch', True)
    volume = kwargs.setdefault('volume', True)
    ikCrv = kwargs.setdefault('ikCrv')

    if ikCrv == None:
        ikCrv = pm.ls(sl=True)[-1]
    else:
        ikCrv = pm.ls(ikCrv)[-1]

    if not ikCrv.getShape().type() == 'nurbsCurve':
        pm.error('ehm_tools...MakeSplineStretchy: Select an IK Spline Curve!')

    # the value used for keyging ss
    ssv = 0
    if volume == True:
        ssv = 1

    #===============================================================================
    # create curveInfo node

    curveShape = ikCrv.getShape()

    crvLenNode = pm.createNode("curveInfo", n=(ikCrv.name() + "_Info"))

    pm.addAttr(ikCrv, keyable=True, ln="scalePower", at="double")

    ikH = pm.listConnections(curveShape, type="ikHandle")

    jntsToSS = pm.ikHandle(ikH[0], q=True, jointList=True)

    #================================================================================
    # key the curve

    if thicknessPlace == "mid":

        pm.setKeyframe((ikCrv + ".scalePower"), t=1, v=0)
        pm.setKeyframe((ikCrv + ".scalePower"), t=len(jntsToSS) / 2, v=ssv)
        pm.setKeyframe((ikCrv + ".scalePower"), t=len(jntsToSS), v=0)

    elif thicknessPlace == "start":

        pm.setKeyframe((ikCrv + ".scalePower"), t=1, v=ssv)
        pm.setKeyframe((ikCrv + ".scalePower"), t=len(jntsToSS), v=0)

    elif thicknessPlace == "end":

        pm.setKeyframe((ikCrv + ".scalePower"), t=1, v=0)
        pm.setKeyframe((ikCrv + ".scalePower"), t=len(jntsToSS), v=ssv)
    else:
        print "ThinknessPlace not defined. Select one of these : 'start' , 'mid' , 'end' "

    curveShape.worldSpace[0] >> crvLenNode.inputCurve
    pm.addAttr(crvLenNode, ln="normalizedScale", at="double")

    normScl = pm.createNode("multiplyDivide", n=(ikCrv + "_normalizedScale"))
    pm.setAttr((normScl + ".operation"), 2)

    arcLen = pm.getAttr(crvLenNode + ".arcLength")
    pm.setAttr((normScl + ".input2X"), arcLen)
    pm.connectAttr((crvLenNode + ".arcLength"), (normScl + ".input1X"), f=True)
    pm.connectAttr((normScl + ".outputX"), (crvLenNode + ".normalizedScale"),
                   f=True)
    stretchedScale = pm.createNode("multiplyDivide", n=(ikCrv + "_scale_mdn"))
    pm.connectAttr((normScl + ".outputX"), (stretchedScale + ".input1X"),
                   f=True)
    pm.setAttr((stretchedScale + ".operation"), 2)

    lenJnts = len(jntsToSS)

    for k in range(lenJnts):

        pm.addAttr(jntsToSS[k], keyable=True, ln="pow", at="double")
        cacheN = pm.createNode("frameCache", n=(jntsToSS[k] + "_FCnode"))
        pm.connectAttr((cacheN + ".varying"), (jntsToSS[k] + ".pow"))
        pm.connectAttr((ikCrv + ".scalePower"), (cacheN + ".stream"))
        pm.setAttr((cacheN + ".varyTime"), (k + 1))

    #===================================================================================
    # create scale, sqrt and power nodes for keeping the volume using nodes instead of expression

    normScaleSqrt = pm.createNode("multiplyDivide", n="normScaleSqrt")
    pm.connectAttr((stretchedScale + ".outputX"), (normScaleSqrt + ".input1X"))
    pm.setAttr((normScaleSqrt + ".operation"), 3)
    pm.setAttr((normScaleSqrt + ".input2X"), 0.5)

    sqrtMult = pm.createNode("multiplyDivide", n="sqrtMult")
    pm.setAttr((sqrtMult + ".input1X"), 1)

    pm.setAttr((sqrtMult + ".operation"), 2)
    pm.connectAttr((normScaleSqrt + ".outputX"), (sqrtMult + ".input2X"))

    for k in range(lenJnts):
        scaleMult = pm.createNode("multiplyDivide",
                                  n=(jntsToSS[k] + "_scale_mdn"))
        pm.setAttr((scaleMult + ".operation"), 3)

        sqrtMult.outputX >> scaleMult.input1X
        jntsToSS[k].pow >> scaleMult.input2X

        stretchedScale.outputX >> jntsToSS[k].scaleX
        scaleMult.outputX >> jntsToSS[k].scaleY
        scaleMult.outputX >> jntsToSS[k].scaleZ

    #===================================================================================
    # making the spine scalable by connecting the scale of the mian_ctrl to it's network

    if stretchSwitch == True:
        pm.addAttr(ikCrv,
                   ln="stretchSwitch",
                   at="double",
                   keyable=True,
                   min=0,
                   max=1,
                   dv=1)
        back_stretchSwitch_bln = pm.createNode("blendColors",
                                               n="back_stretchSwitch_bln")

        back_stretchSwitch_bln.color1R.set(1)
        normScl.outputX >> back_stretchSwitch_bln.color2R
        ikCrv.stretchSwitch >> back_stretchSwitch_bln.blender

        pm.connectAttr((back_stretchSwitch_bln + ".outputR"),
                       (stretchedScale + ".input2X"),
                       f=True)
Beispiel #35
0
    def doRig(self):
        if pm.objExists(self.name + 'Constrained_grp'):
            pm.delete(self.name + 'Constrained_grp')
        if pm.objExists(self.name + 'tweakSys_grp'):
            pm.delete(self.name + 'tweakSys_grp')

        cnstrGrp = pm.group(n=self.name + 'Constrained_grp', em=True)
        allSliderGrp = pm.group(n=self.name + 'Sliders_grp', em=True)
        tweakCtrlGrp = pm.group(n=self.name + 'tweakCtrls_grp', em=True)

        tweakJntGrp = pm.group(n=self.name + 'tweakSys_grp', em=True)

        pm.parent(tweakCtrlGrp, allSliderGrp, cnstrGrp)
        tweakJntGrp.visibility.set(False)

        basePos = pm.xform(self.guideMoveall, t=True, q=True, ws=True)

        masterSlderGrp = pm.group(em=True, name=self.name + 'global_grp')
        masterSliderCtrl = pm.circle(nr=(0, 0, 1),
                                     r=0.2,
                                     n=self.name + 'global_ctrl')[0]
        pm.parent(masterSliderCtrl, masterSlderGrp)
        pm.parent(masterSlderGrp, allSliderGrp)

        p1 = pm.xform(self.tweak4, q=True, ws=True, t=True)[0]
        p2 = pm.xform(self.tweak3, q=True, ws=True, t=True)[0]

        pm.xform(masterSlderGrp,
                 t=(p1 + (p1 - p2), basePos[1] + 1, basePos[2] + 1),
                 ws=True)

        displaySetup = self.tweakCtrlSetup.copy()
        tweakGuides = [self.tweak1, self.tweak2, self.tweak3, self.tweak4]
        slidersNames = ['In', 'MidIn', 'MidOut', 'Out']

        sliderList = []
        sideMove = True
        for i in range(4):
            guide = tweakGuides[i]
            guideXpos = pm.xform(guide, q=True, ws=True, t=True)[0]
            slider = createSlider(self.name + slidersNames[i],
                                  size=0.1,
                                  sideMove=sideMove)
            sliderList.append(slider)
            pm.xform(slider.getParent(),
                     t=(guideXpos, basePos[1] + 1, basePos[2] + 1),
                     ws=True)
            pm.parent(slider.getParent(), allSliderGrp)

            addNode = pm.createNode('addDoubleLinear')
            clampConn = pm.listConnections(slider.translateY, p=True, d=True)
            for conn in clampConn:
                addNode.output >> conn
            masterSliderCtrl.translateY >> addNode.input1
            slider.translateY >> addNode.input2

            pm.parent(slider.getParent(), masterSliderCtrl)

            cntrlName = displaySetup['nameTempl'] + str(i)
            jntName = self.jntSetup['nameTempl'] + str(i)
            jnt = jointTools.makeJoint(name=jntName,
                                       obj=guide,
                                       jntSulfix='_jxt',
                                       hasZero=True,
                                       connectToLast=False)
            ctrl = controlTools.cntrlCrv(name=cntrlName,
                                         obj=jnt,
                                         connType='connection',
                                         offsets=1,
                                         **displaySetup)
            pm.parent(jnt.getParent(), tweakJntGrp)
            pm.parent(ctrl.getParent(2), tweakCtrlGrp)

            sideMove = False

        self.guideMoveall.visibility.set(0)
Beispiel #36
0
    def addOperators(self):
        """Create operators and set the relations for the component rig

        Apply operators, constraints, expressions to the hierarchy.
        In order to keep the code clean and easier to debug,
        we shouldn't create any new object in this method.

        """

        # mouth center rotation
        pm.connectAttr(self.jaw_ctl + ".rotateZ",
                       self.mouthCenter + ".rotateZ")

        # Node Creation ########

        # Mut Div nodes
        md_node_1 = pm.createNode("multiplyDivide")
        md_node_2 = pm.createNode("multiplyDivide")
        md_node_3 = pm.createNode("multiplyDivide")
        md_node_4 = pm.createNode("multiplyDivide")
        md_node_5 = pm.createNode("multiplyDivide")
        md_node_6 = pm.createNode("multiplyDivide")
        md_node_7 = pm.createNode("multiplyDivide")
        md_node_8 = pm.createNode("multiplyDivide")

        # Clamp o_node
        clamp_node = pm.createNode("clamp")

        # Condition nodes
        cond_node_1 = pm.createNode("condition")
        cond_node_2 = pm.createNode("condition")
        cond_node_3 = pm.createNode("condition")

        # Blend nodes
        blend_node_1 = pm.createNode("blendColors")
        blend_node_2 = pm.createNode("blendColors")

        # Node Conexions ########

        # md_node_1
        pm.connectAttr(self.jaw_ctl + ".translateY", md_node_1 + ".input1X")
        pm.connectAttr(self.vertRotation_att, md_node_1 + ".input2X")

        # md_node_2
        pm.connectAttr(self.jaw_ctl + ".translateX", md_node_2 + ".input1X")
        pm.connectAttr(self.sideRotation_att, md_node_2 + ".input2X")

        # md_node_3
        pm.connectAttr(self.jaw_ctl + ".translateY", md_node_3 + ".input1X")
        pm.connectAttr(self.lipsAlignSpeed_att, md_node_3 + ".input2X")

        # md_node_4
        pm.connectAttr(self.jaw_ctl + ".translateY", md_node_4 + ".input1X")
        pm.connectAttr(self.verticalTranslation_att, md_node_4 + ".input2X")

        # md_node_5
        pm.connectAttr(self.jaw_ctl + ".translateZ", md_node_5 + ".input1X")
        pm.connectAttr(self.frontalTranslation_att, md_node_5 + ".input2X")

        # md_node_6
        pm.connectAttr(md_node_1 + ".outputX", md_node_6 + ".input1X")
        pm.setAttr(md_node_6 + ".input2X", -1.0)

        # md_node_7
        pm.connectAttr(md_node_5 + ".outputX", md_node_7 + ".input1X")
        pm.connectAttr(clamp_node + ".outputR", md_node_7 + ".input2X")

        # md_node_8
        pm.connectAttr(cond_node_2 + ".outColorR", md_node_8 + ".input1X")
        pm.connectAttr(clamp_node + ".outputR", md_node_8 + ".input2X")

        # clamp_node
        pm.connectAttr(md_node_3 + ".outputX", clamp_node + ".inputR")
        pm.setAttr(clamp_node + ".maxR", 1.0)

        # cond_node_1
        pm.connectAttr(md_node_6 + ".outputX", cond_node_1 + ".colorIfTrueR")
        pm.connectAttr(md_node_6 + ".outputX", cond_node_1 + ".firstTerm")
        pm.setAttr(cond_node_1 + ".operation", 4)
        pm.setAttr(cond_node_1 + ".colorIfFalseR", 0)

        # cond_node_2
        pm.connectAttr(md_node_2 + ".outputX", cond_node_2 + ".colorIfFalseR")
        pm.connectAttr(md_node_6 + ".outputX", cond_node_2 + ".firstTerm")
        pm.setAttr(cond_node_2 + ".operation", 2)

        # cond_node_3
        pm.connectAttr(md_node_4 + ".outputX", cond_node_3 + ".colorIfTrueR")
        pm.connectAttr(md_node_4 + ".outputX", cond_node_3 + ".firstTerm")
        pm.setAttr(cond_node_3 + ".operation", 4)
        pm.setAttr(cond_node_3 + ".colorIfFalseR", 0)

        # blend_node_1
        pm.connectAttr(self.followLips_att, blend_node_1 + ".blender")
        pm.connectAttr(md_node_6 + ".outputX", blend_node_1 + ".color1R")
        pm.connectAttr(md_node_2 + ".outputX", blend_node_1 + ".color1G")
        pm.connectAttr(cond_node_1 + ".outColorR", blend_node_1 + ".color2R")
        pm.connectAttr(md_node_8 + ".outputX", blend_node_1 + ".color2G")

        # blend_node_2
        pm.connectAttr(self.followLips_att, blend_node_2 + ".blender")
        pm.connectAttr(cond_node_3 + ".outColorR", blend_node_2 + ".color1R")
        pm.connectAttr(md_node_5 + ".outputX", blend_node_2 + ".color1G")
        pm.connectAttr(md_node_7 + ".outputX", blend_node_2 + ".color2G")

        # inputs to transforms

        pm.connectAttr(md_node_6 + ".outputX", self.jawLow_rot + ".rotateX")
        pm.connectAttr(md_node_2 + ".outputX", self.jawLow_rot + ".rotateY")

        pm.connectAttr(blend_node_1 + ".outputR", self.jawUp_rot + ".rotateX")
        pm.connectAttr(blend_node_1 + ".outputG", self.jawUp_rot + ".rotateY")

        pm.connectAttr(cond_node_3 + ".outColorR",
                       self.jawLow_pos + ".translateY")
        pm.connectAttr(md_node_5 + ".outputX",
                       self.jawLow_pos + ".translateZ")

        pm.connectAttr(blend_node_2 + ".outputR",
                       self.jawUp_pos + ".translateY")
        pm.connectAttr(blend_node_2 + ".outputG",
                       self.jawUp_pos + ".translateZ")
Beispiel #37
0
def basicStretchyIk(ikHandle, stretchLimits=None, globalScaleAttr=None):
    """
    stretchLimits - tuple with the min and max values for scaling the joints. if set to None, no limits will be set
    """
    if isinstance(ikHandle, basestring):
        ikHandle = pmc.nodetypes.IkHandle(ikHandle)

    # Turn off snapping to avoid cycle error
    ikHandle.snapEnable.set(False)

    joints = ikHandle.getJointList()
    joints.extend(pmc.listConnections(ikHandle.getEndEffector().translateX))

    # generate locators
    # move onto appropriate positioning
    startLoc = pmc.spaceLocator(
        n='loc_{0}_stretchyStart'.format(ikHandle.shortName()))
    endLoc = pmc.spaceLocator(
        n='loc_{0}_stretchyEnd'.format(ikHandle.shortName()))

    pmc.pointConstraint(joints[0], startLoc, maintainOffset=False)
    pmc.pointConstraint(ikHandle, endLoc, maintainOffset=False)

    # create distance node and connect
    # Using createNode() prevents distNode from showing up in Hypershade's utility tab
    # May or may not be helpful to you, based on how tidy you want to keep the scene
    distNode = pmc.createNode('distanceBetween',
                              n='dst_{0}_length'.format(ikHandle.shortName()))

    # Using locator's shape nodes to connect the worldPosition attribute
    startLoc.getShape().worldPosition[0].connect(distNode.point1)
    endLoc.getShape().worldPosition[0].connect(distNode.point2)

    # Get total distance using python's sum() function
    # Returns sum of all values in a list
    # List created inline using list comprehension
    distance = sum([abs(jnt.translateX.get()) for jnt in joints[1:]])

    # create divide node to divide current length
    normalizeNode = pmc.createNode('multiplyDivide',
                                   n='div_{0}_normalizer'.format(
                                       ikHandle.shortName()))
    distNode.distance.connect(normalizeNode.input1X)
    normalizeNode.operation.set(2)
    normalizeNode.input2X.set(distance)

    outputAttr = normalizeNode.outputX
    if stretchLimits:
        clampNode = makeStretchyClamp(normalizeNode=normalizeNode,
                                      minStretch=stretchLimits[0],
                                      maxStretch=stretchLimits[1],
                                      name=ikHandle.shortName())
        outputAttr = clampNode.outputR

    # If rig has global scale, create additional nodes to preserve length
    if globalScaleAttr:
        globalScaleNode = makeStretchyGlobalScale(globalScaleAttr,
                                                  distance,
                                                  name=ikHandle.shortName())
        globalScaleNode.outputX.connect(normalizeNode.input2X)

    # multiply node to scale each joint's translateX
    # connect multiply nodes to joints
    for jnt in joints[1:]:
        scaleNode = pmc.createNode('multiplyDivide',
                                   n='mul_{0}_stretch'.format(jnt.shortName()))

        outputAttr.connect(scaleNode.input1X)
        scaleNode.input2X.set(jnt.translateX.get())
        scaleNode.outputX.connect(jnt.translateX)

    return [startLoc, endLoc]
Beispiel #38
0
    def setup_swivel_ctrl(self,
                          base_ctrl,
                          ref,
                          pos,
                          ik_handle,
                          constraint=True,
                          mirror_setup=True,
                          **kwargs):
        """
        Create the swivel ctrl for the ik system. Redefined to add the possibility to create a mirror swivel setup
        to prevent flipping problem with pole vector when using ikSpringSolver

        :param base_ctrl: The ctrl used to setup the swivel, create one if needed
        :param ref: Reference object to position the swivel
        :param pos: The computed position of the swivel
        :param ik_handle: The handle to pole vector contraint
        :param constraint: Do we contraint the ik handle to the swivel ctrl
        :param mirror_setup: Is the swivel need a mirror setup (Hack to bypass ikSpringSolver flipping problem
        :param kwargs: Additionnal parameters
        :return: The created ctrl swivel
        """

        # Do not contraint the ik handle now since we could maybe need the flipping setup
        ctrl_swivel = super(LegIkQuad,
                            self).setup_swivel_ctrl(base_ctrl,
                                                    ref,
                                                    pos,
                                                    ik_handle,
                                                    constraint=False,
                                                    **kwargs)
        nomenclature_rig = self.get_nomenclature_rig()

        flip_swivel_ref = None
        if mirror_setup:
            # HACK - In case the ikpringSolver is used, a flip can happen if the foot pos is behind the thigh pos
            # Since we already have a plane, only compare the world Z pos to know if the foot is behind the thigh
            thigh_pos = self.chain_jnt[0].getTranslation(space='world')
            foot_pos = self.chain_jnt[self.iCtrlIndex].getTranslation(
                space='world')
            # TODO - The check is not stable at all. The best we could do is to do real test on the bones
            # if foot_pos.z < thigh_pos.z:
            if foot_pos.z < thigh_pos.z and nomenclature_rig.side != nomenclature_rig.SIDE_R:  # Flip will occur
                log.warning("Using the mirror swivel setup for {0}".format(
                    self.name))
                # The goal is to create a swivel ref that will be at the good position for the poleVectorContraint
                # to not flip and drive it by the pole vector ctrl that is in the real position we really wanted
                flip_swivel_ref = pymel.spaceLocator()
                flip_swivel_ref.rename(
                    nomenclature_rig.resolve('swivelFlipRefBack'))
                flip_pos = pymel.dt.Vector(pos.x, pos.y, -pos.z)
                flip_swivel_ref.setTranslation(flip_pos, space='world')

                # Setup a ref parent that will always look at the foot
                ref_parent_name = nomenclature_rig.resolve(
                    'swivelParentFlipRef')
                ref_parent = pymel.createNode('transform',
                                              name=ref_parent_name,
                                              parent=self.grp_rig)
                ref_parent.setMatrix(self.chain_jnt[0].getMatrix(ws=True),
                                     ws=True)
                pymel.pointConstraint(self.parent, ref_parent, mo=True)
                pymel.aimConstraint(self.ctrl_ik, ref_parent, mo=True)
                ref_parent.setParent(self.grp_rig)
                # Parent the ref flipping swivel on it's parent
                flip_swivel_ref.setParent(ref_parent)

                # Create a ref that will be at the same position than the swivel ctrl
                # and that will control the flipping swivel
                ref_swivel_ctrl = pymel.spaceLocator()
                ref_swivel_ctrl.rename(
                    nomenclature_rig.resolve('swivelCtrlRef'))
                ref_swivel_ctrl.setMatrix(ctrl_swivel.getMatrix(ws=True),
                                          ws=True)
                pymel.pointConstraint(ctrl_swivel, ref_swivel_ctrl)
                ref_swivel_ctrl.setParent(ref_parent)

                # Now, mirror position from the ref swivel ctrl to the flipping swivel ctrl
                inverse_MD = pymel.createNode('multiplyDivide')
                inverse_MD.input2.set(-1.0, -1.0, -1.0)
                ref_swivel_ctrl.translate.connect(inverse_MD.input1)
                inverse_MD.output.connect(flip_swivel_ref.translate)

        if constraint:
            # Pole vector contraint the swivel to the ik handle
            if flip_swivel_ref:  # Use the flipping ref if needed
                pymel.poleVectorConstraint(flip_swivel_ref, ik_handle)
            else:
                pymel.poleVectorConstraint(ctrl_swivel, ik_handle)

        return ctrl_swivel
Beispiel #39
0
def cycleTweak(name,
               edgePair,
               mirrorAxis,
               baseMesh,
               rotMesh,
               transMesh,
               setupParent,
               ctlParent,
               jntOrg=None,
               grp=None,
               iconType="square",
               size=.025,
               color=13,
               ro=datatypes.Vector(1.5708, 0, 1.5708 / 2)):
    """The command to create a cycle tweak.

    A cycle tweak is a tweak that cycles to the parent position but doesn't
    create a cycle of dependency. This type of tweaks
    are very useful to create facial tweakers.

    Args:
        name (string): Name for the cycle tweak
        edgePair (list): List of edge pair to attach the cycle tweak
        mirrorAxis (bool): If true, will mirror the x axis behaviour.
        baseMesh (Mesh): The base mesh for the cycle tweak.
        rotMesh (Mesh): The mesh that will support the rotation transformations
                for the cycle tweak
        transMesh (Mesh): The mesh that will support the translation and scale
                transformations for the cycle tweak
        setupParent (dagNode): The parent for the setup objects
        ctlParent (dagNode): The parent for the control objects
        jntOrg (None or dagNode, optional): The parent for the joints
        grp (None or set, optional): The set to add the controls
        iconType (str, optional): The controls shape
        size (float, optional): The control size
        color (int, optional): The control color
        ro (TYPE, optional): The control shape rotation offset

    Returns:
        multi: the tweak control and the list of related joints.
    """
    # rotation sctructure
    rRivet = rivet.rivet()
    rBase = rRivet.create(baseMesh, edgePair[0], edgePair[1], setupParent,
                          name + "_rRivet_loc")

    pos = rBase.getTranslation(space="world")

    # translation structure
    tRivetParent = pm.createNode("transform",
                                 n=name + "_tRivetBase",
                                 p=ctlParent)
    tRivetParent.setMatrix(datatypes.Matrix(), worldSpace=True)
    tRivet = rivet.rivet()
    tBase = tRivet.create(transMesh, edgePair[0], edgePair[1], tRivetParent,
                          name + "_tRivet_loc")

    # create the control
    tweakBase = pm.createNode("transform", n=name + "_tweakBase", p=ctlParent)
    tweakBase.setMatrix(datatypes.Matrix(), worldSpace=True)
    tweakNpo = pm.createNode("transform", n=name + "_tweakNpo", p=tweakBase)
    tweakBase.setTranslation(pos, space="world")
    tweakCtl = icon.create(tweakNpo,
                           name + "_ctl",
                           tweakNpo.getMatrix(worldSpace=True),
                           color,
                           iconType,
                           w=size,
                           d=size,
                           ro=ro)
    inverseTranslateParent(tweakCtl)
    pm.pointConstraint(tBase, tweakBase)

    # rot
    rotBase = pm.createNode("transform", n=name + "_rotBase", p=setupParent)
    rotBase.setMatrix(datatypes.Matrix(), worldSpace=True)
    rotNPO = pm.createNode("transform", n=name + "_rot_npo", p=rotBase)
    rotJointDriver = pm.createNode("transform",
                                   n=name + "_rotJointDriver",
                                   p=rotNPO)
    rotBase.setTranslation(pos, space="world")

    node.createMulNode(
        [rotNPO.attr("tx"),
         rotNPO.attr("ty"),
         rotNPO.attr("tz")], [-1, -1, -1], [
             rotJointDriver.attr("tx"),
             rotJointDriver.attr("ty"),
             rotJointDriver.attr("tz")
         ])

    pm.pointConstraint(rBase, rotNPO)
    pm.connectAttr(tweakCtl.r, rotNPO.r)
    pm.connectAttr(tweakCtl.s, rotNPO.s)

    # transform
    posNPO = pm.createNode("transform", n=name + "_pos_npo", p=setupParent)
    posJointDriver = pm.createNode("transform",
                                   n=name + "_posJointDriver",
                                   p=posNPO)
    posNPO.setTranslation(pos, space="world")
    pm.connectAttr(tweakCtl.t, posJointDriver.t)

    # mirror behaviour
    if mirrorAxis:
        tweakBase.attr("ry").set(tweakBase.attr("ry").get() + 180)
        rotBase.attr("ry").set(rotBase.attr("ry").get() + 180)
        posNPO.attr("ry").set(posNPO.attr("ry").get() + 180)
        tweakBase.attr("sz").set(-1)
        rotBase.attr("sz").set(-1)
        posNPO.attr("sz").set(-1)

    # create joints
    rJoint = rigbits.addJnt(rotJointDriver, jntOrg, True, grp)
    tJoint = rigbits.addJnt(posJointDriver, jntOrg, True, grp)

    # add to rotation skin
    # TODO: add checker to see if joint is in the skincluster.
    rSK = skin.getSkinCluster(rotMesh)
    pm.skinCluster(rSK, e=True, ai=rJoint, lw=True, wt=0)

    # add to transform skin
    # TODO: add checker to see if joint is in the skincluster.
    tSK = skin.getSkinCluster(transMesh)
    pm.skinCluster(tSK, e=True, ai=tJoint, lw=True, wt=0)

    return tweakCtl, [rJoint, tJoint]
Beispiel #40
0
 def createNode(self, type, **kwargs):
     node = pmc.createNode(type, **kwargs)
     name = '%s_%s' % (self.name(), type)
     node.rename(name)
     return node
def ghostSliderForMouth(ghostControls, intTra, surface, sliderParent):
    """Modify the ghost control behaviour to slide on top of a surface

    Args:
        ghostControls (dagNode): The ghost control
        surface (Surface): The NURBS surface
        sliderParent (dagNode): The parent for the slider.
    """
    if not isinstance(ghostControls, list):
        ghostControls = [ghostControls]

    def conn(ctl, driver, ghost):
        for attr in ["translate", "scale", "rotate"]:
            try:
                pm.connectAttr("{}.{}".format(ctl, attr),
                               "{}.{}".format(driver, attr))
                pm.disconnectAttr("{}.{}".format(ctl, attr),
                                  "{}.{}".format(ghost, attr))
            except RuntimeError:
                pass

    def connCenter(ctl, driver, ghost):
        # mul_node1 = pm.createNode("multMatrix")
        # mul_node2 = pm.createNode("multMatrix")

        down, _, up = ymt_util.findPathAtoB(ctl, driver)
        mult = pm.createNode("multMatrix")

        for i, d in enumerate(down):
            d.attr("matrix") >> mult.attr("matrixIn[{}]".format(i))

        for j, u in enumerate(up[:-1]):
            u.attr("inverseMatrix") >> mult.attr(
                "matrixIn[{}]".format(i + j + 1))

        decomp = pm.createNode("decomposeMatrix")

        dm_node = node.createDecomposeMatrixNode(mult.attr("matrixSum"))

        for attr in ["translate", "scale", "rotate"]:
            pm.connectAttr("{}.output{}".format(dm_node, attr.capitalize()),
                           "{}.{}".format(driver, attr))
            pm.disconnectAttr("{}.{}".format(ctl, attr),
                              "{}.{}".format(ghost, attr))

    surfaceShape = surface.getShape()
    sliders = []

    for i, ctlGhost in enumerate(ghostControls):
        ctl = pm.listConnections(ctlGhost, t="transform")[-1]
        t = ctl.getMatrix(worldSpace=True)

        gDriver = primitive.addTransform(surface.getParent(),
                                         "{}_slideDriver".format(ctl.name()),
                                         t)
        if 0 == i:
            connCenter(ctl, gDriver, ctlGhost)

        else:
            conn(ctl, gDriver, ctlGhost)

        oParent = ctlGhost.getParent()
        npoName = "_".join(ctlGhost.name().split("_")[:-1]) + "_npo"
        oTra = pm.PyNode(
            pm.createNode("transform", n=npoName, p=oParent, ss=True))
        oTra.setTransformation(ctlGhost.getMatrix())
        pm.parent(ctlGhost, oTra)

        slider = primitive.addTransform(sliderParent,
                                        ctl.name() + "_slideDriven", t)
        sliders.append(slider)

        # connexion
        if 0 == i:
            dm_node = node.createDecomposeMatrixNode(gDriver.attr("matrix"))

        else:
            mul_node = pm.createNode("multMatrix")
            i = 0
            parent = ctl
            while parent != sliderParent:
                parent.attr("matrix") >> mul_node.attr(
                    "matrixIn[{}]".format(i))
                parent = parent.getParent()
                i += 1
                if 10 < i:
                    logger.error("maximum recursion")
                    break

            dm_node = node.createDecomposeMatrixNode(
                mul_node.attr("matrixSum"))

        cps_node = pm.createNode("closestPointOnSurface")
        dm_node.attr("outputTranslate") >> cps_node.attr("inPosition")
        surfaceShape.attr("local") >> cps_node.attr("inputSurface")
        cps_node.attr("position") >> slider.attr("translate")

        pm.normalConstraint(surfaceShape,
                            slider,
                            aimVector=[0, 0, 1],
                            upVector=[0, 1, 0],
                            worldUpType="objectrotation",
                            worldUpVector=[0, 1, 0],
                            worldUpObject=gDriver)

        pm.parent(ctlGhost.getParent(), slider)
        ymt_util.setKeyableAttributesDontLockVisibility(slider, [])

    for slider in sliders[1:]:
        _visi_off_lock(slider)
Beispiel #42
0
    def postConnect(self):

        fk_ref_cond = pm.createNode("condition")
        pm.connectAttr(self.fkref_att, "{}.firstTerm".format(fk_ref_cond))
        pm.setAttr("{}.secondTerm".format(fk_ref_cond), 0)
        pm.setAttr("{}.operation".format(fk_ref_cond), 0)
        pm.setAttr("{}.colorIfTrueR".format(fk_ref_cond), 0)
        pm.setAttr("{}.colorIfTrueG".format(fk_ref_cond), 0)
        pm.setAttr("{}.colorIfTrueB".format(fk_ref_cond), 0)
        pm.setAttr("{}.colorIfFalseR".format(fk_ref_cond), 0)
        pm.setAttr("{}.colorIfFalseG".format(fk_ref_cond), 0)
        pm.setAttr("{}.colorIfFalseB".format(fk_ref_cond), 0)

        pm.connectAttr("{}.outColorR".format(fk_ref_cond),
                       "{}.rotateX".format(self.fk0_cns))
        pm.connectAttr("{}.outColorG".format(fk_ref_cond),
                       "{}.rotateY".format(self.fk0_cns))
        pm.connectAttr("{}.outColorB".format(fk_ref_cond),
                       "{}.rotateZ".format(self.fk0_cns))

        if self.settings["fkrefarray"]:

            ref_names = self.settings["fkrefarray"].split(",")
            for i, ref_name in enumerate(ref_names):

                _head_ref_cond = pm.createNode("condition")
                pm.connectAttr("{}.outColorR".format(_head_ref_cond),
                               "{}.colorIfFalseR".format(fk_ref_cond))
                pm.connectAttr("{}.outColorG".format(_head_ref_cond),
                               "{}.colorIfFalseG".format(fk_ref_cond))
                pm.connectAttr("{}.outColorB".format(_head_ref_cond),
                               "{}.colorIfFalseB".format(fk_ref_cond))
                fk_ref_cond = _head_ref_cond

                pm.connectAttr(self.fkref_att,
                               "{}.firstTerm".format(_head_ref_cond))
                pm.setAttr("{}.secondTerm".format(_head_ref_cond), i + 1)
                pm.setAttr("{}.operation".format(_head_ref_cond), 0)

                src = self.rig.findRelative(ref_name)

                down, _, up = findPathAtoB(src, self.root)
                mult = pm.createNode("multMatrix")

                for i, d in enumerate(down):
                    pm.connectAttr("{}.matrix".format(d),
                                   "{}.matrixIn[{}]".format(mult, i))

                for j, u in enumerate(up):
                    pm.connectAttr("{}.inverseMatrix".format(u),
                                   "{}.matrixIn[{}]".format(mult, i + j + 1))

                decomp = pm.createNode("decomposeMatrix")
                pm.connectAttr("{}.matrixSum".format(mult),
                               "{}.inputMatrix".format(decomp))
                pm.connectAttr("{}.outputRotateX".format(decomp),
                               "{}.colorIfTrueR".format(fk_ref_cond))
                pm.connectAttr("{}.outputRotateY".format(decomp),
                               "{}.colorIfTrueG".format(fk_ref_cond))
                pm.connectAttr("{}.outputRotateZ".format(decomp),
                               "{}.colorIfTrueB".format(fk_ref_cond))
Beispiel #43
0
def addBlendedJoint(oSel=None,
                    compScale=True,
                    blend=.5,
                    name=None,
                    select=True,
                    *args):
    """Create and gimmick blended joint

    Create a joint that rotate 50% of the selected joint. This operation is
    done using a pairBlend node.

    Args:
        oSel (None or joint, optional): If None will use the selected joints.
        compScale (bool, optional): Set the compScale option of the blended
            joint. Default is True.
        blend (float, optional): blend rotation value
        name (None, optional): Name for the blended o_node
        *args: Maya's dummy

    Returns:
        list: blended joints list

    """
    if not oSel:
        oSel = pm.selected()
    elif not isinstance(oSel, list):
        oSel = [oSel]
    jnt_list = []
    for x in oSel:
        if isinstance(x, pm.nodetypes.Joint):
            parent = x.getParent()
            if name:
                bname = 'blend_' + name
            else:
                bname = 'blend_' + x.name()

            jnt = pm.createNode('joint', n=bname, p=x)
            jnt_list.append(jnt)
            jnt.attr('radius').set(1.5)
            pm.parent(jnt, parent)
            o_node = pm.createNode("pairBlend")
            o_node.attr("rotInterpolation").set(1)
            pm.setAttr(o_node + ".weight", blend)
            pm.connectAttr(x + ".translate", o_node + ".inTranslate1")
            pm.connectAttr(x + ".translate", o_node + ".inTranslate2")
            pm.connectAttr(x + ".rotate", o_node + ".inRotate1")

            pm.connectAttr(o_node + ".outRotateX", jnt + ".rotateX")
            pm.connectAttr(o_node + ".outRotateY", jnt + ".rotateY")
            pm.connectAttr(o_node + ".outRotateZ", jnt + ".rotateZ")

            pm.connectAttr(o_node + ".outTranslateX", jnt + ".translateX")
            pm.connectAttr(o_node + ".outTranslateY", jnt + ".translateY")
            pm.connectAttr(o_node + ".outTranslateZ", jnt + ".translateZ")

            pm.connectAttr(x + ".scale", jnt + ".scale")

            jnt.attr("overrideEnabled").set(1)
            jnt.attr("overrideColor").set(17)

            jnt.attr("segmentScaleCompensate").set(compScale)

            try:
                defSet = pm.PyNode("rig_deformers_grp")

            except TypeError:
                pm.sets(n="rig_deformers_grp")
                defSet = pm.PyNode("rig_deformers_grp")

            pm.sets(defSet, add=jnt)
        else:
            pm.displayWarning("Blended Joint can't be added to: %s. Because "
                              "is not ot type Joint" % x.name())

    if jnt_list and select:
        pm.select(jnt_list)

    return jnt_list
Beispiel #44
0
test = pm.selected()

#particle geo sphere creation
import pymel.core as pm

curve_selection = pm.selected()
data_position_list = []
curve_root_list = []
yeti_outerRadius = []
for curve in curve_selection:
    cv_root = pm.PyNode(curve.name() + '.cv[0]')
    curve_root_list.append(cv_root)

for root in curve_root_list:
    data_position = root.getPosition(space='world')
    data_position_list.append(data_position)

clean_particle_group = pm.createNode(
    'transform',
    name='Yeti_OutterRadius_grp',
)

for number, position in enumerate(data_position_list):
    particle = pm.particle(p=[0, 0, 0],
                           name=curve_selection[number].name() + '_' +
                           str(number) + '_particle')
    particle[0].translate.set(position)
    particle[1].particleRenderType.set(4)

    pm.parent(particle[0], clean_particle_group)
Beispiel #45
0
	# create zero groups
	ctrlsZerosAndOfss = ZeroGrp( ctrls )
	ctrlsZeros = ctrlsZerosAndOfss[0]
	ctrlsOfss = ctrlsZerosAndOfss[1]
	
	jntsZerosAndOfss = ZeroGrp( jnts )
	jntsZeros = jntsZerosAndOfss[0]
	jntsOfss = jntsZerosAndOfss[1]
	
	
	# connect transforms of ctrls to joints
	for i in range( len( ctrlsZeros ) ):
		ctrls[i].translate		>>		jntsOfss[i].translate
		ctrls[i].rotate			>>		jntsOfss[i].rotate
		ctrls[i].scale			>>		jntsOfss[i].scale
	
	
	# reverse the scale and connect it to next zeroGrp	
	for i in range( len(ctrlsZeros)-1 ):	
		scaleRev = pm.createNode( 'multiplyDivide', name='%s_scaleRev'%ctrlsZeros[i].name() )
		scaleRev.input1.set(1,1,1)
		scaleRev.operation.set(2)
		ctrls[i].scale			>>		scaleRev.input2
		scaleRev.output			>>		ctrlsZeros[i+1].scale
		
	for i in range( len(jntsZeros)-1 ):	
		scaleRev = pm.createNode( 'multiplyDivide', name='%s_scaleRev'%jntsZeros[i].name() )
		scaleRev.input1.set(1,1,1)
		scaleRev.operation.set(2)
		jntsOfss[i].scale		>>		scaleRev.input2
		scaleRev.output			>>		jntsZeros[i+1].scale
def bdCreateReverseFootRoll(ankleLoc, heelLoc, ballLoc, toeLoc):
    blendColorHeelAuto = pm.createNode('blendColors',
                                       name=heelLoc.name().replace(
                                           'loc', 'auto_BC'))
    blendColorBallAuto = pm.createNode('blendColors',
                                       name=ballLoc.name().replace(
                                           'loc', 'auto_BC'))
    blendColorToeAuto = pm.createNode('blendColors',
                                      name=toeLoc.name().replace(
                                          'loc', 'auto_BC'))

    ankleLoc.attr('Enabled').connect(blendColorHeelAuto.blender)
    ankleLoc.attr('Enabled').connect(blendColorBallAuto.blender)
    ankleLoc.attr('Enabled').connect(blendColorToeAuto.blender)

    ankleLoc.attr('HeelRoll').connect(blendColorHeelAuto.color2R)
    ankleLoc.attr('BallRoll').connect(blendColorBallAuto.color2R)
    ankleLoc.attr('TipRoll').connect(blendColorToeAuto.color2R)

    #setup auto part
    clampHeel = pm.createNode('clamp',
                              n=heelLoc.name().replace('loc', 'roll_CL'))
    clampHeel.minR.set(-90)

    setRangeToe = pm.createNode('setRange',
                                n=toeLoc.name().replace('loc', 'linestep_SR'))
    setRangeToe.minX.set(0)
    setRangeToe.maxX.set(1)

    setRangeBall1 = pm.createNode('setRange',
                                  n=ballLoc.name().replace(
                                      'loc', 'linestep_SR'))
    setRangeBall1.minX.set(0)
    setRangeBall1.maxX.set(1)
    setRangeBall1.oldMinX.set(0)

    mdToeRoll = pm.createNode('multiplyDivide',
                              n=toeLoc.name().replace('loc', 'roll_MD'))
    mdBallRoll = pm.createNode('multiplyDivide',
                               n=ballLoc.name().replace('loc', 'roll_MD'))

    mdBallRange2 = pm.createNode('multiplyDivide',
                                 n=ballLoc.name().replace(
                                     'loc', 'roll_range_MD'))

    pmaBallRange = pm.createNode('plusMinusAverage',
                                 n=ballLoc.name().replace('loc', 'range_PMA'))
    pmaBallRange.input1D[0].set(1)
    pmaBallRange.operation.set(2)

    #connect the heel for negative rolls
    ankleLoc.attr('Roll').connect(clampHeel.inputR)
    clampHeel.outputR.connect(blendColorHeelAuto.color1R)
    blendColorHeelAuto.outputR.connect(heelLoc.rotateX)

    #connect the toe
    ankleLoc.attr('Roll').connect(setRangeToe.valueX)
    ankleLoc.attr('BallStraight').connect(setRangeToe.oldMaxX)
    ankleLoc.attr('ToeStart').connect(setRangeToe.oldMinX)

    ankleLoc.attr('Roll').connect(mdToeRoll.input2X)
    setRangeToe.outValueX.connect(mdToeRoll.input1X)

    mdToeRoll.outputX.connect(blendColorToeAuto.color1R)
    blendColorToeAuto.outputR.connect(toeLoc.rotateX)

    #connect the ball
    ankleLoc.attr('Roll').connect(setRangeBall1.valueX)
    ankleLoc.attr('ToeStart').connect(setRangeBall1.oldMaxX)

    setRangeToe.outValueX.connect(pmaBallRange.input1D[1])

    setRangeBall1.outValueX.connect(mdBallRange2.input1X)
    pmaBallRange.output1D.connect(mdBallRange2.input2X)

    ankleLoc.attr('Roll').connect(mdBallRoll.input2X)
    mdBallRange2.outputX.connect(mdBallRoll.input1X)

    mdBallRoll.outputX.connect(blendColorBallAuto.color1R)
    blendColorBallAuto.outputR.connect(ballLoc.rotateX)
def bdRigLegBones(side):
    ikAnimCon = pm.ls(side.upper() + '_Foot_CON', type='transform')[0]
    legBonesNames = ['Thigh', 'Shin', 'Foot', 'Toe']
    legBones = []
    for bone in legBonesNames:
        legBone = pm.ls(side + bone)[0]
        legBones.append(legBone)
        print legBone.name()
    toeEnd = pm.ls(side + 'Toe_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)

    #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

    offset = 90
    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 * offset)

    ikAnimCon.attr('KneeTwist').connect(adlNode.input1)
    adlNode.output.connect(footIk.twist)

    startTwist = mirror * offset
    limit = 0.001
    increment = mirror * 0.01

    while True:
        pm.select(cl=True)
        thighRot = pm.xform(legBones[0], q=True, ro=True, os=True)
        print thighRot[0]
        if ((thighRot[2] > limit)):
            startTwist = startTwist - increment
            adlNode.input2.set(startTwist)

        else:
            break

    #END knee

    pm.parent(ankleLoc, ikAnimCon)
Beispiel #48
0
    def addOperators(self):
        """Create operators and set the relations for the component rig

        Apply operators, constraints, expressions to the hierarchy.
        In order to keep the code clean and easier to debug,
        we shouldn't create any new object in this method.

        """

        # 1 bone chain Upv ref ==============================
        self.ikHandleUpvRef = primitive.addIkHandle(
            self.root, self.getName("ikHandleLegChainUpvRef"),
            self.legChainUpvRef, "ikSCsolver")
        pm.pointConstraint(self.ik_ctl, self.ikHandleUpvRef)
        pm.parentConstraint(self.legChainUpvRef[0],
                            self.ik_ctl,
                            self.upv_cns,
                            mo=True)

        # Visibilities -------------------------------------
        # shape.dispGeometry
        # fk
        fkvis_node = node.createReverseNode(self.blend_att)

        for shp in self.fk0_ctl.getShapes():
            pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility"))
        for shp in self.fk1_ctl.getShapes():
            pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility"))
        for shp in self.fk2_ctl.getShapes():
            pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility"))

        # ik
        for shp in self.upv_ctl.getShapes():
            pm.connectAttr(self.blend_att, shp.attr("visibility"))
        for shp in self.ikcns_ctl.getShapes():
            pm.connectAttr(self.blend_att, shp.attr("visibility"))
        for shp in self.ik_ctl.getShapes():
            pm.connectAttr(self.blend_att, shp.attr("visibility"))
        for shp in self.line_ref.getShapes():
            pm.connectAttr(self.blend_att, shp.attr("visibility"))

        # IK Solver -----------------------------------------
        out = [self.bone0, self.bone1, self.ctrn_loc, self.eff_loc]
        o_node = applyop.gear_ikfk2bone_op(out, self.root_ctl, self.ik_ref,
                                           self.upv_ctl, self.fk_ctl[0],
                                           self.fk_ctl[1], self.fk_ref,
                                           self.length0, self.length1,
                                           self.negate)

        pm.connectAttr(self.blend_att, o_node + ".blend")
        if self.negate:
            mulVal = -1
        else:
            mulVal = 1
        node.createMulNode(self.roll_att, mulVal, o_node + ".roll")
        # pm.connectAttr(self.roll_att, o_node+".roll")
        pm.connectAttr(self.scale_att, o_node + ".scaleA")
        pm.connectAttr(self.scale_att, o_node + ".scaleB")
        pm.connectAttr(self.maxstretch_att, o_node + ".maxstretch")
        pm.connectAttr(self.slide_att, o_node + ".slide")
        pm.connectAttr(self.softness_att, o_node + ".softness")
        pm.connectAttr(self.reverse_att, o_node + ".reverse")

        # Twist references ---------------------------------
        o_node = applyop.gear_mulmatrix_op(
            self.eff_loc.attr("worldMatrix"),
            self.root.attr("worldInverseMatrix"))

        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix")
        pm.connectAttr(dm_node + ".outputTranslate",
                       self.tws2_npo.attr("translate"))

        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix")
        pm.connectAttr(dm_node + ".outputRotate", self.tws2_npo.attr("rotate"))

        # spline IK for  twist jnts
        self.ikhUpLegTwist, self.uplegTwistCrv = applyop.splineIK(
            self.getName("uplegTwist"),
            self.uplegTwistChain,
            parent=self.root,
            cParent=self.bone0)

        self.ikhLowLegTwist, self.lowlegTwistCrv = applyop.splineIK(
            self.getName("lowlegTwist"),
            self.lowlegTwistChain,
            parent=self.root,
            cParent=self.bone1)

        # references
        self.ikhUpLegRef, self.tmpCrv = applyop.splineIK(
            self.getName("uplegRollRef"),
            self.uplegRollRef,
            parent=self.root,
            cParent=self.bone0)

        self.ikhLowLegRef, self.tmpCrv = applyop.splineIK(
            self.getName("lowlegRollRef"),
            self.lowlegRollRef,
            parent=self.root,
            cParent=self.eff_loc)

        self.ikhAuxTwist, self.tmpCrv = applyop.splineIK(
            self.getName("auxTwist"),
            self.auxTwistChain,
            parent=self.root,
            cParent=self.eff_loc)

        # setting connexions for ikhUpLegTwist
        self.ikhUpLegTwist.attr("dTwistControlEnable").set(True)
        self.ikhUpLegTwist.attr("dWorldUpType").set(4)
        self.ikhUpLegTwist.attr("dWorldUpAxis").set(3)
        self.ikhUpLegTwist.attr("dWorldUpVectorZ").set(1.0)
        self.ikhUpLegTwist.attr("dWorldUpVectorY").set(0.0)
        self.ikhUpLegTwist.attr("dWorldUpVectorEndZ").set(1.0)
        self.ikhUpLegTwist.attr("dWorldUpVectorEndY").set(0.0)
        pm.connectAttr(self.uplegRollRef[0].attr("worldMatrix[0]"),
                       self.ikhUpLegTwist.attr("dWorldUpMatrix"))
        pm.connectAttr(self.bone0.attr("worldMatrix[0]"),
                       self.ikhUpLegTwist.attr("dWorldUpMatrixEnd"))

        # setting connexions for ikhAuxTwist
        self.ikhAuxTwist.attr("dTwistControlEnable").set(True)
        self.ikhAuxTwist.attr("dWorldUpType").set(4)
        self.ikhAuxTwist.attr("dWorldUpAxis").set(3)
        self.ikhAuxTwist.attr("dWorldUpVectorZ").set(1.0)
        self.ikhAuxTwist.attr("dWorldUpVectorY").set(0.0)
        self.ikhAuxTwist.attr("dWorldUpVectorEndZ").set(1.0)
        self.ikhAuxTwist.attr("dWorldUpVectorEndY").set(0.0)
        pm.connectAttr(self.lowlegRollRef[0].attr("worldMatrix[0]"),
                       self.ikhAuxTwist.attr("dWorldUpMatrix"))
        pm.connectAttr(self.tws_ref.attr("worldMatrix[0]"),
                       self.ikhAuxTwist.attr("dWorldUpMatrixEnd"))
        pm.connectAttr(self.auxTwistChain[1].attr("rx"),
                       self.ikhLowLegTwist.attr("twist"))

        pm.parentConstraint(self.bone1, self.aux_npo, maintainOffset=True)

        # scale arm length for twist chain (not the squash and stretch)
        arclen_node = pm.arclen(self.uplegTwistCrv, ch=True)
        alAttrUpLeg = arclen_node.attr("arcLength")
        muldiv_nodeArm = pm.createNode("multiplyDivide")
        pm.connectAttr(arclen_node.attr("arcLength"),
                       muldiv_nodeArm.attr("input1X"))
        muldiv_nodeArm.attr("input2X").set(alAttrUpLeg.get())
        muldiv_nodeArm.attr("operation").set(2)
        for jnt in self.uplegTwistChain:
            pm.connectAttr(muldiv_nodeArm.attr("outputX"), jnt.attr("sx"))

        # scale forearm length for twist chain (not the squash and stretch)
        arclen_node = pm.arclen(self.lowlegTwistCrv, ch=True)
        alAttrLowLeg = arclen_node.attr("arcLength")
        muldiv_nodeLowLeg = pm.createNode("multiplyDivide")
        pm.connectAttr(arclen_node.attr("arcLength"),
                       muldiv_nodeLowLeg.attr("input1X"))
        muldiv_nodeLowLeg.attr("input2X").set(alAttrLowLeg.get())
        muldiv_nodeLowLeg.attr("operation").set(2)
        for jnt in self.lowlegTwistChain:
            pm.connectAttr(muldiv_nodeLowLeg.attr("outputX"), jnt.attr("sx"))

        # scale compensation for the first  twist join
        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(self.root.attr("worldMatrix[0]"),
                       dm_node.attr("inputMatrix"))
        pm.connectAttr(dm_node.attr("outputScale"),
                       self.uplegTwistChain[0].attr("inverseScale"))
        pm.connectAttr(dm_node.attr("outputScale"),
                       self.lowlegTwistChain[0].attr("inverseScale"))

        # tangent controls
        muldiv_node = pm.createNode("multiplyDivide")
        muldiv_node.attr("input2X").set(-1)
        pm.connectAttr(self.tws1A_npo.attr("rz"), muldiv_node.attr("input1X"))
        muldiv_nodeBias = pm.createNode("multiplyDivide")
        pm.connectAttr(muldiv_node.attr("outputX"),
                       muldiv_nodeBias.attr("input1X"))
        pm.connectAttr(self.roundness_att, muldiv_nodeBias.attr("input2X"))
        pm.connectAttr(muldiv_nodeBias.attr("outputX"),
                       self.tws1A_loc.attr("rz"))
        if self.negate:
            axis = "xz"
        else:
            axis = "-xz"
        applyop.aimCns(self.tws1A_npo,
                       self.tws0_loc,
                       axis=axis,
                       wupType=2,
                       wupVector=[0, 0, 1],
                       wupObject=self.mid_ctl,
                       maintainOffset=False)

        applyop.aimCns(self.lowlegTangentB_loc,
                       self.lowlegTangentA_npo,
                       axis=axis,
                       wupType=2,
                       wupVector=[0, 0, 1],
                       wupObject=self.mid_ctl,
                       maintainOffset=False)

        pm.pointConstraint(self.eff_loc, self.lowlegTangentB_loc)

        muldiv_node = pm.createNode("multiplyDivide")
        muldiv_node.attr("input2X").set(-1)
        pm.connectAttr(self.tws1B_npo.attr("rz"), muldiv_node.attr("input1X"))
        muldiv_nodeBias = pm.createNode("multiplyDivide")
        pm.connectAttr(muldiv_node.attr("outputX"),
                       muldiv_nodeBias.attr("input1X"))
        pm.connectAttr(self.roundness_att, muldiv_nodeBias.attr("input2X"))
        pm.connectAttr(muldiv_nodeBias.attr("outputX"),
                       self.tws1B_loc.attr("rz"))
        if self.negate:
            axis = "-xz"
        else:
            axis = "xz"
        applyop.aimCns(self.tws1B_npo,
                       self.tws2_loc,
                       axis=axis,
                       wupType=2,
                       wupVector=[0, 0, 1],
                       wupObject=self.mid_ctl,
                       maintainOffset=False)

        applyop.aimCns(self.uplegTangentA_loc,
                       self.uplegTangentB_npo,
                       axis=axis,
                       wupType=2,
                       wupVector=[0, 0, 1],
                       wupObject=self.mid_ctl,
                       maintainOffset=False)

        # Volume -------------------------------------------
        distA_node = node.createDistNode(self.tws0_loc, self.tws1_loc)
        distB_node = node.createDistNode(self.tws1_loc, self.tws2_loc)
        add_node = node.createAddNode(distA_node + ".distance",
                                      distB_node + ".distance")
        div_node = node.createDivNode(add_node + ".output",
                                      self.root_ctl.attr("sx"))

        # comp scaling issue
        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(self.root.attr("worldMatrix"), dm_node + ".inputMatrix")

        div_node2 = node.createDivNode(div_node + ".outputX",
                                       dm_node + ".outputScaleX")

        self.volDriver_att = div_node2 + ".outputX"

        # connecting tangent scaele compensation after volume to
        # avoid duplicate some nodes
        distA_node = node.createDistNode(self.tws0_loc, self.mid_ctl)
        distB_node = node.createDistNode(self.mid_ctl, self.tws2_loc)

        div_nodeUpLeg = node.createDivNode(distA_node + ".distance",
                                           dm_node.attr("outputScaleX"))

        div_node2 = node.createDivNode(div_nodeUpLeg + ".outputX",
                                       distA_node.attr("distance").get())

        pm.connectAttr(div_node2.attr("outputX"), self.tws1A_loc.attr("sx"))

        pm.connectAttr(div_node2.attr("outputX"),
                       self.uplegTangentA_loc.attr("sx"))

        div_nodeLowLeg = node.createDivNode(distB_node + ".distance",
                                            dm_node.attr("outputScaleX"))
        div_node2 = node.createDivNode(div_nodeLowLeg + ".outputX",
                                       distB_node.attr("distance").get())

        pm.connectAttr(div_node2.attr("outputX"), self.tws1B_loc.attr("sx"))
        pm.connectAttr(div_node2.attr("outputX"),
                       self.lowlegTangentB_loc.attr("sx"))

        # conection curve
        cnts = [
            self.uplegTangentA_loc, self.uplegTangentA_ctl,
            self.uplegTangentB_ctl, self.kneeTangent_ctl
        ]
        applyop.gear_curvecns_op(self.uplegTwistCrv, cnts)

        cnts = [
            self.kneeTangent_ctl, self.lowlegTangentA_ctl,
            self.lowlegTangentB_ctl, self.lowlegTangentB_loc
        ]
        applyop.gear_curvecns_op(self.lowlegTwistCrv, cnts)

        # Tangent controls vis
        for shp in self.uplegTangentA_ctl.getShapes():
            pm.connectAttr(self.tangentVis_att, shp.attr("visibility"))
        for shp in self.uplegTangentB_ctl.getShapes():
            pm.connectAttr(self.tangentVis_att, shp.attr("visibility"))
        for shp in self.lowlegTangentA_ctl.getShapes():
            pm.connectAttr(self.tangentVis_att, shp.attr("visibility"))
        for shp in self.lowlegTangentB_ctl.getShapes():
            pm.connectAttr(self.tangentVis_att, shp.attr("visibility"))
        for shp in self.kneeTangent_ctl.getShapes():
            pm.connectAttr(self.tangentVis_att, shp.attr("visibility"))

        # Divisions ----------------------------------------
        # at 0 or 1 the division will follow exactly the rotation of the
        # controler.. and we wont have this nice tangent + roll
        for i, div_cns in enumerate(self.div_cns):
            if i < (self.settings["div0"] + 2):
                mulmat_node = applyop.gear_mulmatrix_op(
                    self.uplegTwistChain[i] + ".worldMatrix",
                    div_cns + ".parentInverseMatrix")
                lastUpLegDiv = div_cns
            else:
                o_node = self.lowlegTwistChain[i - (self.settings["div0"] + 2)]
                mulmat_node = applyop.gear_mulmatrix_op(
                    o_node + ".worldMatrix", div_cns + ".parentInverseMatrix")
                lastLowLegDiv = div_cns
            dm_node = node.createDecomposeMatrixNode(mulmat_node + ".output")
            pm.connectAttr(dm_node + ".outputTranslate", div_cns + ".t")
            pm.connectAttr(dm_node + ".outputRotate", div_cns + ".r")

            # Squash n Stretch
            o_node = applyop.gear_squashstretch2_op(
                div_cns, None, pm.getAttr(self.volDriver_att), "x")
            pm.connectAttr(self.volume_att, o_node + ".blend")
            pm.connectAttr(self.volDriver_att, o_node + ".driver")
            pm.connectAttr(self.st_att[i], o_node + ".stretch")
            pm.connectAttr(self.sq_att[i], o_node + ".squash")

        # force translation for last loc arm and foreamr
        applyop.gear_mulmatrix_op(self.kneeTangent_ctl.worldMatrix,
                                  lastUpLegDiv.parentInverseMatrix,
                                  lastUpLegDiv, "t")
        applyop.gear_mulmatrix_op(self.tws2_loc.worldMatrix,
                                  lastLowLegDiv.parentInverseMatrix,
                                  lastLowLegDiv, "t")

        # NOTE: next line fix the issue on meters.
        # This is special case becasuse the IK solver from mGear use the
        # scale as lenght and we have shear
        # TODO: check for a more clean and elegant solution instead of
        # re-match the world matrix again
        transform.matchWorldTransform(self.fk_ctl[0], self.match_fk0_off)
        transform.matchWorldTransform(self.fk_ctl[1], self.match_fk1_off)
        transform.matchWorldTransform(self.fk_ctl[0], self.match_fk0)
        transform.matchWorldTransform(self.fk_ctl[1], self.match_fk1)

        # match IK/FK ref
        pm.parentConstraint(self.bone0, self.match_fk0_off, mo=True)
        pm.parentConstraint(self.bone1, self.match_fk1_off, mo=True)

        return
Beispiel #49
0
    def addOperators(self):
        """Create operators and set the relations for the component rig

        Apply operators, constraints, expressions to the hierarchy.
        In order to keep the code clean and easier to debug,
        we shouldn't create any new object in this method.

        """
        # 1 bone chain Upv ref ==============================================
        self.ikHandleUpvRef = primitive.addIkHandle(
            self.root, self.getName("ikHandleArmChainUpvRef"),
            self.armChainUpvRef, "ikSCsolver")
        pm.pointConstraint(self.ik_ctl, self.ikHandleUpvRef)
        pm.parentConstraint(self.armChainUpvRef[0], self.upv_cns, mo=True)

        # Visibilities -------------------------------------
        # fk
        fkvis_node = node.createReverseNode(self.blend_att)

        for shp in self.fk0_ctl.getShapes():
            pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility"))
        for shp in self.fk1_ctl.getShapes():
            pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility"))
        for shp in self.fk2_ctl.getShapes():
            pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility"))

        # ik
        for shp in self.upv_ctl.getShapes():
            pm.connectAttr(self.blend_att, shp.attr("visibility"))
        for shp in self.ikcns_ctl.getShapes():
            pm.connectAttr(self.blend_att, shp.attr("visibility"))
        for shp in self.ik_ctl.getShapes():
            pm.connectAttr(self.blend_att, shp.attr("visibility"))
        for shp in self.line_ref.getShapes():
            pm.connectAttr(self.blend_att, shp.attr("visibility"))
        if self.settings["ikTR"]:
            for shp in self.ikRot_ctl.getShapes():
                pm.connectAttr(self.blend_att, shp.attr("visibility"))
        for shp in self.roll_ctl.getShapes():
            pm.connectAttr(self.blend_att, shp.attr("visibility"))

        # Controls ROT order -----------------------------------
        attribute.setRotOrder(self.fk0_ctl, "XZY")
        attribute.setRotOrder(self.fk1_ctl, "XYZ")
        attribute.setRotOrder(self.fk2_ctl, "YZX")
        attribute.setRotOrder(self.ik_ctl, "XYZ")

        # IK Solver -----------------------------------------
        out = [self.bone0, self.bone1, self.ctrn_loc, self.eff_loc]
        o_node = applyop.gear_ikfk2bone_op(out, self.root, self.ik_ref,
                                           self.upv_ctl, self.fk_ctl[0],
                                           self.fk_ctl[1], self.fk_ref,
                                           self.length0, self.length1,
                                           self.negate)

        # NOTE: Ideally we should not change hierarchy or move object after
        # object generation method. But is much easier this way since every
        # part is in the final and correct position
        # after the  ctrn_loc is in the correct position with the ikfk2bone op

        # point constrain tip reference
        pm.pointConstraint(self.ik_ctl, self.tip_ref, mo=False)

        # interpolate transform  mid point locator
        int_matrix = applyop.gear_intmatrix_op(
            self.armChainUpvRef[0].attr("worldMatrix"),
            self.tip_ref.attr("worldMatrix"), .5)
        applyop.gear_mulmatrix_op(
            int_matrix.attr("output"),
            self.interpolate_lvl.attr("parentInverseMatrix[0]"),
            self.interpolate_lvl)

        # match roll ctl npo to ctrn_loc current transform (so correct orient)
        transform.matchWorldTransform(self.ctrn_loc, self.roll_ctl_npo)

        # match roll ctl npo to interpolate transform current position
        pos = self.interpolate_lvl.getTranslation(space="world")
        self.roll_ctl_npo.setTranslation(pos, space="world")

        # parent constraint roll control npo to interpolate trans
        pm.parentConstraint(self.interpolate_lvl, self.roll_ctl_npo, mo=True)

        if self.settings["ikTR"]:
            # connect the control inputs
            outEff_dm = o_node.listConnections(c=True)[-1][1]

            inAttr = self.ikRot_npo.attr("translate")
            outEff_dm.attr("outputTranslate") >> inAttr

            outEff_dm.attr("outputScale") >> self.ikRot_npo.attr("scale")
            dm_node = node.createDecomposeMatrixNode(o_node.attr("outB"))
            dm_node.attr("outputRotate") >> self.ikRot_npo.attr("rotate")

            # rotation
            mulM_node = applyop.gear_mulmatrix_op(
                self.ikRot_ctl.attr("worldMatrix"),
                self.eff_loc.attr("parentInverseMatrix"))
            intM_node = applyop.gear_intmatrix_op(o_node.attr("outEff"),
                                                  mulM_node.attr("output"),
                                                  o_node.attr("blend"))
            dm_node = node.createDecomposeMatrixNode(intM_node.attr("output"))
            dm_node.attr("outputRotate") >> self.eff_loc.attr("rotate")
            transform.matchWorldTransform(self.fk2_ctl, self.ikRot_cns)

        # scale: this fix the scalin popping issue
        intM_node = applyop.gear_intmatrix_op(
            self.fk2_ctl.attr("worldMatrix"),
            self.ik_ctl_ref.attr("worldMatrix"), o_node.attr("blend"))
        mulM_node = applyop.gear_mulmatrix_op(
            intM_node.attr("output"), self.eff_loc.attr("parentInverseMatrix"))
        dm_node = node.createDecomposeMatrixNode(mulM_node.attr("output"))
        dm_node.attr("outputScale") >> self.eff_loc.attr("scale")

        pm.connectAttr(self.blend_att, o_node + ".blend")
        if self.negate:
            mulVal = -1
            rollMulVal = 1
        else:
            mulVal = 1
            rollMulVal = -1
        roll_m_node = node.createMulNode(self.roll_att, mulVal)
        roll_m_node2 = node.createMulNode(self.roll_ctl.attr("rx"), rollMulVal)
        node.createPlusMinusAverage1D(
            [roll_m_node.outputX, roll_m_node2.outputX],
            operation=1,
            output=o_node + ".roll")
        pm.connectAttr(self.scale_att, o_node + ".scaleA")
        pm.connectAttr(self.scale_att, o_node + ".scaleB")
        pm.connectAttr(self.maxstretch_att, o_node + ".maxstretch")
        pm.connectAttr(self.slide_att, o_node + ".slide")
        pm.connectAttr(self.softness_att, o_node + ".softness")
        pm.connectAttr(self.reverse_att, o_node + ".reverse")

        # Twist references ---------------------------------

        pm.pointConstraint(self.mid_ctl_twst_ref,
                           self.tws1_npo,
                           maintainOffset=False)
        pm.connectAttr(self.mid_ctl.scaleX, self.tws1_loc.scaleX)
        pm.orientConstraint(self.mid_ctl_twst_ref,
                            self.tws1_npo,
                            maintainOffset=False)

        o_node = applyop.gear_mulmatrix_op(
            self.eff_loc.attr("worldMatrix"),
            self.root.attr("worldInverseMatrix"))
        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix")
        pm.connectAttr(dm_node + ".outputTranslate",
                       self.tws2_npo.attr("translate"))

        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix")
        pm.connectAttr(dm_node + ".outputRotate", self.tws2_npo.attr("rotate"))

        o_node = applyop.gear_mulmatrix_op(
            self.eff_loc.attr("worldMatrix"),
            self.tws2_rot.attr("parentInverseMatrix"))
        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix")
        attribute.setRotOrder(self.tws2_rot, "XYZ")
        pm.connectAttr(dm_node + ".outputRotate", self.tws2_rot + ".rotate")

        self.tws0_rot.setAttr("sx", .001)
        self.tws2_rot.setAttr("sx", .001)

        add_node = node.createAddNode(self.roundness_att, .001)
        pm.connectAttr(add_node + ".output", self.tws1_rot.attr("sx"))

        pm.connectAttr(self.armpit_roll_att, self.tws0_rot + ".rotateX")

        # Roll Shoulder
        applyop.splineIK(self.getName("rollRef"),
                         self.rollRef,
                         parent=self.root,
                         cParent=self.bone0)

        # Volume -------------------------------------------
        distA_node = node.createDistNode(self.tws0_loc, self.tws1_loc)
        distB_node = node.createDistNode(self.tws1_loc, self.tws2_loc)
        add_node = node.createAddNode(distA_node + ".distance",
                                      distB_node + ".distance")
        div_node = node.createDivNode(add_node + ".output",
                                      self.root.attr("sx"))

        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(self.root.attr("worldMatrix"), dm_node + ".inputMatrix")

        div_node2 = node.createDivNode(div_node + ".outputX",
                                       dm_node + ".outputScaleX")
        self.volDriver_att = div_node2 + ".outputX"

        if self.settings["extraTweak"]:
            for tweak_ctl in self.tweak_ctl:
                for shp in tweak_ctl.getShapes():
                    pm.connectAttr(self.tweakVis_att, shp.attr("visibility"))

        # Divisions ----------------------------------------
        # at 0 or 1 the division will follow exactly the rotation of the
        # controler.. and we wont have this nice tangent + roll
        for i, div_cns in enumerate(self.div_cns):

            if self.settings["supportJoints"]:
                if i < (self.settings["div0"] + 1):
                    perc = i * .5 / (self.settings["div0"] + 1.0)
                elif i < (self.settings["div0"] + 2):
                    perc = .49
                elif i < (self.settings["div0"] + 3):
                    perc = .50
                elif i < (self.settings["div0"] + 4):
                    perc = .51

                else:
                    perc = .5 + \
                        (i - self.settings["div0"] - 3.0) * .5 / \
                        (self.settings["div1"] + 1.0)
            else:
                if i < (self.settings["div0"] + 1):
                    perc = i * .5 / (self.settings["div0"] + 1.0)
                elif i < (self.settings["div0"] + 2):
                    perc = .501
                else:
                    perc = .5 + \
                        (i - self.settings["div0"] - 1.0) * .5 / \
                        (self.settings["div1"] + 1.0)

            perc = max(.001, min(.990, perc))

            # Roll
            if self.negate:
                o_node = applyop.gear_rollsplinekine_op(
                    div_cns, [self.tws2_rot, self.tws1_rot, self.tws0_rot],
                    1.0 - perc, 40)
            else:
                o_node = applyop.gear_rollsplinekine_op(
                    div_cns, [self.tws0_rot, self.tws1_rot, self.tws2_rot],
                    perc, 40)

            pm.connectAttr(self.resample_att, o_node + ".resample")
            pm.connectAttr(self.absolute_att, o_node + ".absolute")

            # Squash n Stretch
            o_node = applyop.gear_squashstretch2_op(
                div_cns, None, pm.getAttr(self.volDriver_att), "x")
            pm.connectAttr(self.volume_att, o_node + ".blend")
            pm.connectAttr(self.volDriver_att, o_node + ".driver")
            pm.connectAttr(self.st_att[i], o_node + ".stretch")
            pm.connectAttr(self.sq_att[i], o_node + ".squash")

        # match IK/FK ref
        pm.parentConstraint(self.bone0, self.match_fk0_off, mo=True)
        pm.parentConstraint(self.bone1, self.match_fk1_off, mo=True)
        if self.settings["ikTR"]:
            transform.matchWorldTransform(self.ikRot_ctl, self.match_ikRot)
            transform.matchWorldTransform(self.fk_ctl[2], self.match_fk2)

        return
Beispiel #50
0
def createPoseReader(target,
                     rotation=None,
                     name=None,
                     outerRadius=90.0,
                     innerRadius=0.0):
    target = pm.ls(target)[0]
    rotation = rotation or (0.0, 0.0, 0.0)
    if not name:
        suf = '_'.join(
            map(lambda p: p[0] + str(int(p[1])).replace('-', 'n'),
                zip(('x', 'y', 'z'), rotation)))
        name = 'poseReader_' + target.nodeName() + '_' + suf

    # Create reader as curve
    reader = pm.curve(name=name, **arrow)
    reader.overrideEnabled.set(1)
    reader.overrideColor.set(3)

    # Position reader on target
    mult = pm.createNode('multMatrix', name=name + '_OFFSET')
    mult.matrixIn[0].set(target.xformMatrix.get())
    # Parent reader if target has parent
    parent = target.getParent()
    if parent:
        pm.connectAttr(parent.worldMatrix, mult.matrixIn[1])
    pm.connectAttr(mult.matrixSum, reader.offsetParentMatrix)

    # Create vectorProduct and angleBetween nodes
    ab = pm.createNode('angleBetween', name=name + '_ANGLE')
    vps = [
        pm.createNode('vectorProduct', name=name + '_VEC{}'.format(i))
        for i in range(2)
    ]
    # Connect vps
    for src, vp in zip((reader, target), vps):
        vp.operation.set(3)
        vp.input1.set(1, 0, 0)
        pm.connectAttr(src.worldMatrix, vp.matrix)
        ab_in = 'vector1' if vp == vps[0] else 'vector2'
        pm.connectAttr(vp.output, ab.attr(ab_in))

    # Create remapValue
    rv = pm.createNode('remapValue', name=name + '_VALUE')
    for i in range(2):
        rv.value[i].value_FloatValue.set(1 - i)

    # Create reader attributes
    pm.addAttr(reader,
               ln='outerRadius',
               at='float',
               maxValue=180.0,
               defaultValue=90.0,
               k=True)
    pm.addAttr(reader, ln='innerRadius', at='float', maxValue=180.0, k=True)
    pm.addAttr(reader, ln='poseWeight', at='float', k=True)

    # Connect angle & reader attributes
    pm.connectAttr(ab.angle, rv.inputValue)
    pm.connectAttr(reader.outerRadius, rv.inputMax)
    pm.connectAttr(reader.innerRadius, rv.inputMin)
    pm.connectAttr(rv.outValue, reader.poseWeight)

    # Rotate & set reader radius
    reader.outerRadius.set(pm.dt.Vector(rotation).length())
    pm.rotate(reader, rotation, r=True)

    pm.select(reader)
Beispiel #51
0
def connectBndToPivot(bnd, pivot, drivePrimary=False):
    '''
    basically the same at face.connectBndToPriCtl
    but can don't drive primary controls
    '''

    # bnd's "local" matrix within pivot
    bnd_wMat = bnd.getMatrix(ws=True)
    pivot_wMat = pivot.getMatrix(ws=True)
    bnd_lMat = bnd_wMat * pivot_wMat.inverse()
    lMatNd = pm.createNode('fourByFourMatrix',
                           n=bnd.replace('_bnd',
                                         '_lMat_in_' + pivot.nodeName()))
    # populate "local" matrix
    for i in range(4):
        for j in range(4):
            lMatNd.attr('in%d%d' % (i, j)).set(bnd_lMat[i][j])
    # bnd's "local-inverse" matrix
    lInvMatNd = pm.createNode('inverseMatrix',
                              n=bnd.replace('_bnd',
                                            '_lInvMat_in_' + pivot.nodeName()))
    lMatNd.output >> lInvMatNd.inputMatrix
    # for bnd to pivot around pivot,
    # the matrix is lMat * pivotMat * lInvMat
    mmNd = pm.createNode('multMatrix', n=bnd.replace('_bnd', '_calc_mm'))
    lMatNd.output >> mmNd.i[0]
    pivot.matrix >> mmNd.i[1]
    lInvMatNd.outputMatrix >> mmNd.i[2]
    # decompose matrix before passing into bw
    dmNd = pm.createNode('decomposeMatrix', n=bnd.replace('_bnd', '_calc_dm'))
    mmNd.o >> dmNd.inputMatrix
    # get bw nodes to connect to
    channels = ['tx', 'ty', 'tz', 'rx', 'ry', 'rz', 'sx', 'sy', 'sz']
    bwNodes = {}
    for eachChannel in channels:
        bwNodes[eachChannel] = bnd.attr(eachChannel + '_bwMsg').get()
    # get index to connect to
    existingInputs = bwNodes['tx'].i.inputs()
    nextIndex = len(existingInputs)
    # actual connections
    dmNd.otx >> bwNodes['tx'].i[nextIndex]
    dmNd.oty >> bwNodes['ty'].i[nextIndex]
    dmNd.otz >> bwNodes['tz'].i[nextIndex]
    dmNd.orx >> bwNodes['rx'].i[nextIndex]
    dmNd.ory >> bwNodes['ry'].i[nextIndex]
    dmNd.orz >> bwNodes['rz'].i[nextIndex]
    dmNd.osx >> bwNodes['sx'].i[nextIndex]
    dmNd.osy >> bwNodes['sy'].i[nextIndex]
    dmNd.osz >> bwNodes['sz'].i[nextIndex]
    # channel box separator
    bnd.addAttr(pivot.nodeName() + '_weights', at='double', k=True, dv=0)
    bnd.setAttr(pivot.nodeName() + '_weights', lock=True)
    # connect weight to be blended to 0
    for eachChannel in ['tx', 'ty', 'tz', 'rx', 'ry', 'rz']:
        bnd.addAttr(pivot.nodeName() + '_weight_' + eachChannel,
                    at='double',
                    k=True,
                    min=-1,
                    max=2,
                    dv=1)
        bnd.attr(pivot.nodeName() + '_weight_' +
                 eachChannel) >> bwNodes[eachChannel].weight[nextIndex]
    # scales need a minus 1, to be normalized to 0 for blending
    for eachChannel in ['sx', 'sy', 'sz']:
        adl = pm.createNode('addDoubleLinear',
                            n=bnd.replace('_bnd', '_%s_adl' % eachChannel))
        adl.input2.set(-1)
        dmNd.attr('o%s' % eachChannel) >> adl.input1
        adl.output >> bwNodes[eachChannel].i[nextIndex]
        bnd.addAttr(pivot.nodeName() + '_weight_' + eachChannel,
                    at='double',
                    k=True,
                    min=-1,
                    max=2,
                    dv=1)
        bnd.attr(pivot.nodeName() + '_weight_' +
                 eachChannel) >> bwNodes[eachChannel].weight[nextIndex]

    if drivePrimary:
        # if this bnd already has it's own attached priCtl
        # we need to drive that too
        if bnd.hasAttr('attached_pri_ctl'):
            attachedCtl = bnd.attr('attached_pri_ctl').get()

            if attachedCtl != pivot:
                print 'Bnd: ' + bnd
                print 'Current Pri Ctl: ' + pivot
                print 'Attached Pri Ctl: ' + attachedCtl
                attachedCtg = attachedCtl.getParent()
                # add zero grp to take in connections
                zeroGrp = pm.PyNode(
                    cgmrigging.groupMeObject(attachedCtg.nodeName(), True,
                                             True))
                for eachChannel in channels:
                    mdl = pm.createNode(
                        'multDoubleLinear',
                        n=bnd.replace('_bnd',
                                      '_%s_%s_mdl' % (eachChannel, pivot)))
                    if eachChannel in ['sx', 'sy', 'sz']:
                        adl = pm.createNode(
                            'addDoubleLinear',
                            n=bnd.replace('_bnd',
                                          '_%s_%s_adl' % (eachChannel, pivot)))
                        dmNd.attr('o' + eachChannel) >> adl.input1
                        adl.input2.set(-1)
                        adl.output >> mdl.input1
                    else:
                        dmNd.attr('o' + eachChannel) >> mdl.input1

                    bnd.attr(pivot.nodeName() + '_weight_' +
                             eachChannel) >> mdl.input2

                    if eachChannel in ['sx', 'sy', 'sz']:
                        adl = pm.createNode(
                            'addDoubleLinear',
                            n=bnd.replace('_bnd',
                                          '_%s_%s_adl' % (eachChannel, pivot)))
                        mdl.output >> adl.input1
                        adl.input2.set(1)
                        adl.output >> zeroGrp.attr(eachChannel)
                    else:
                        mdl.output >> zeroGrp.attr(eachChannel)
Beispiel #52
0
def createRivetTweak(mesh,
                     edgePair,
                     name,
                     parent=None,
                     parentJnt=None,
                     ctlParent=None,
                     color=[0, 0, 0],
                     size=.04,
                     defSet=None,
                     ctlSet=None,
                     side=None,
                     gearMulMatrix=True):
    """Create a tweak joint attached to the mesh using a rivet

    Args:
        mesh (mesh): The object to add the tweak
        edgePair (pari list): The edge pairt to create the rivet
        name (str): The name for the tweak
        parent (None or dagNode, optional): The parent for the tweak
        parentJnt (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)

    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))
    pm.pointConstraint(base, npo, mo=False)

    # create joints
    if not parentJnt:
        parentJnt = 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(parentJnt, 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)
    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
Beispiel #53
0
    def build(self,
              ctrl_ik_orientation=None,
              constraint=True,
              constraint_handle=True,
              setup_softik=True,
              *args,
              **kwargs):
        """
        Build the ik system when needed
        :param ctrl_ik_orientation: The ik ctrl orientation override
        :param constraint: Bool to tell if we constraint the chain_jnt to the system
        :param constraint_handle: Bool to tell if we constraint the ik handle to the ik ctrl
        :param setup_softik: Bool to tell if we setup the soft ik on this system
        :param args: More args passed to the superclass
        :param kwargs: More kwargs passed to the superclass
        :return:
        """
        nomenclature_anm = self.get_nomenclature_anm()
        nomenclature_rig = self.get_nomenclature_rig()

        index_elbow = 1  #The elbow will always be on the second bone
        index_hand = self.iCtrlIndex

        jnt_elbow = self.chain_jnt[index_elbow]
        jnt_hand = self.chain_jnt[index_hand]

        #Compute swivel pos before any operation is done on the bones
        swivel_pos = self.calc_swivel_pos()

        # Create a group for the ik system
        # This group will be parentConstrained to the module parent.
        ikChainGrp_name = nomenclature_rig.resolve('ikChain')
        self._ikChainGrp = pymel.createNode('transform',
                                            name=ikChainGrp_name,
                                            parent=self.grp_rig)
        self._ikChainGrp.setMatrix(self.chain.start.getMatrix(worldSpace=True),
                                   worldSpace=True)

        super(IK, self).build(*args, **kwargs)

        self._ikChainGrp.setParent(self.grp_rig)

        # Duplicate input chain (we don't want to move the hierarchy)
        #self._chain_ik = pymel.duplicate(list(self.chain_jnt), renameChildren=True, parentOnly=True)
        self._chain_ik = self.chain.duplicate()
        i = 1
        for oIk in self._chain_ik:
            oIk.rename(nomenclature_rig.resolve('{0:02}'.format(i)))
            i += 1
        self._chain_ik[0].setParent(
            self.parent)  # Trick the IK system (temporary solution)

        obj_e = self._chain_ik[index_hand]

        # Compute chain length
        self.chain_length = libPymel.PyNodeChain(self.chain[:self.iCtrlIndex +
                                                            1]).length()
        #self.chain_length = self.chain.length()

        # Create ikChain
        self._chain_ik[0].setParent(self._ikChainGrp)
        # Create ikEffector
        ik_solver_name = nomenclature_rig.resolve('ikHandle')
        ik_effector_name = nomenclature_rig.resolve('ikEffector')
        self._ik_handle, _ik_effector = self.create_ik_handle()
        self._ik_handle.rename(ik_solver_name)
        self._ik_handle.setParent(self._ikChainGrp)
        _ik_effector.rename(ik_effector_name)

        # Create CtrlIK
        if not isinstance(self.ctrl_ik, self._CLASS_CTRL_IK):
            self.ctrl_ik = self._CLASS_CTRL_IK()
        ctrl_ik_refs = [jnt_hand] + jnt_hand.getChildren(allDescendents=True)
        self.ctrl_ik.build(
            refs=ctrl_ik_refs,
            geometries=self.rig.get_meshes())  # refs is used by CtrlIkCtrl
        self.ctrl_ik.setParent(self.grp_anm)
        ctrl_ik_name = nomenclature_anm.resolve('ik')
        self.ctrl_ik.rename(ctrl_ik_name)
        self.ctrl_ik.offset.setTranslation(obj_e.getTranslation(space='world'),
                                           space='world')

        # Set ctrl_ik_orientation
        if ctrl_ik_orientation is None:
            ctrl_ik_orientation = obj_e.getRotation(space='world')
        self.ctrl_ik.offset.setRotation(ctrl_ik_orientation, space='world')

        self.ctrl_ik.create_spaceswitch(self,
                                        self.parent,
                                        default_name='World')

        # Create the ik_handle_target that will control the ik_handle
        # This is allow us to override what control the main ik_handle
        # Mainly used for the Leg setup
        self._ik_handle_target = pymel.createNode(
            'transform', name=nomenclature_rig.resolve('ikHandleTarget'))
        self._ik_handle_target.setParent(self.grp_rig)
        pymel.pointConstraint(self.ctrl_ik, self._ik_handle_target)

        #
        # Create softIk node and connect user accessible attributes to it.
        #
        if setup_softik:
            self.setup_softik([self._ik_handle], self._chain_ik)

        # Connect global scale
        pymel.connectAttr(self.grp_rig.globalScale, self._ikChainGrp.sx)
        pymel.connectAttr(self.grp_rig.globalScale, self._ikChainGrp.sy)
        pymel.connectAttr(self.grp_rig.globalScale, self._ikChainGrp.sz)

        #Setup swivel
        self.ctrl_swivel = self.setup_swivel_ctrl(self.ctrl_swivel, jnt_elbow,
                                                  swivel_pos, self._ik_handle)
        self.swivelDistance = self.chain_length  # Used in ik/fk switch
        #pymel.poleVectorConstraint(flip_swivel_ref, self._ik_handle)

        # Connect rig -> anm
        if constraint_handle:
            pymel.pointConstraint(self.ctrl_ik,
                                  self._ik_handle,
                                  maintainOffset=True)
        pymel.orientConstraint(self.ctrl_ik, obj_e, maintainOffset=True)

        if constraint:
            for source, target in zip(self._chain_ik, self.chain):
                pymel.parentConstraint(source, target)
Beispiel #54
0
    def flexiplane(self, prefix=''):
        """
        Build FlexiPlane
        :param index: number of flexiplane in scene (auto managed by maya)
        :return: FlexiPlane group node
        """

        fp_name = '%sflexiPlane' % prefix
        fp_name = nameCheck.nameCheck(fp_name + '*_GRP').replace(
            '_GRP', '', 1)  # flexiPlane_GRP

        fp_surf = self.create_plane('%s_NURBS' % (fp_name))[0]
        fp_surf.overrideEnabled.set(1)
        fp_surf.overrideDisplayType.set(2)

        # Assign Material
        self.create_lambret(fp_surf,
                            color=(0.067, 0.737, 0.749),
                            transparency=(0.75, 0.75, 0.75))

        # Create Follicles
        # flc_name = 'flexiPlane'
        v = 0.1  # 1/width
        flcs = []
        how_many_flc = 5  # width/2
        for i in range(0, how_many_flc):
            ofoll = self.create_follicle(
                fp_surf, '%s_flc_%s_FLC' % (fp_name, letters[i + 26]), v, 0.5)
            flcs.append(ofoll)
            v += 0.2  # (1/width)*2

        # Group Follicles
        flc_grp = pm.group(flcs, name='%s_flcs_GRP' % (fp_name))

        # creates flexiPlane controls curves at each end
        self.ctrl_a = self.ctrl_square(name='%s_ctrl_a_CTRL' % (fp_name),
                                       pos=[-5, 0, 0])
        ctrl_ashape = self.ctrl_a.getShape()
        pm.rename(ctrl_ashape, '%sShape' % self.ctrl_a)

        self.ctrl_b = self.ctrl_square(name='%s_ctrl_b_CTRL' % (fp_name),
                                       pos=[5, 0, 0])
        ctrl_bshape = self.ctrl_b.getShape()
        pm.rename(ctrl_bshape, '%sShape' % self.ctrl_b)

        pm.select(cl=True)

        # creates flexiPlane blendshape     #  blendshape suffix: _bShp_
        fp_bshp = pm.duplicate(fp_surf, n='%s_bshp_NURBS' % (fp_name))[0]
        pm.move(0, 0, -5, fp_bshp)

        fps_bshp_node = pm.blendShape(fp_bshp,
                                      fp_surf,
                                      n='%s_BSHP' % (fp_name))[0]
        pm.setAttr('%s.%s' % (fps_bshp_node, fp_bshp), 1)
        # pm.rename('tweak1', '%sbshp_%stweak_01' % (fp_name, sur))

        # creates curve for wire deformer
        fp_curve = pm.curve(d=2,
                            p=[(-5, 0, -5), (0, 0, -5), (5, 0, -5)],
                            k=[0, 0, 1, 1],
                            n='%s_wire_CV' % (fp_name))
        cl_a, cl_b, cl_mid = self.cluster_curve(fp_curve, fp_name)

        # create and place twist deformer
        pm.select(fp_bshp)
        fp_twist = pm.nonLinear(type='twist', lowBound=-1, highBound=1)
        # displays warning: pymel.core.general : could not create desired mfn. Defaulting MfnDependencyNode.
        # doesn't seem to affect anything though
        pm.rename(fp_twist[0], '%s_twistAttr_surface_NURBS' % (fp_name))
        pm.rename(fp_twist[1], '%s_twist_Handle_DEFORMER' % (fp_name))
        fp_twist[1].rz.set(90)
        # connect start and end angle to their respective control
        connect = self.ctrl_b.rx >> fp_twist[0].startAngle
        connect = self.ctrl_a.rx >> fp_twist[0].endAngle

        # skins wire to blendshape
        fp_wire = pm.wire(
            fp_bshp,
            w=fp_curve,
            gw=False,
            en=1,
            ce=0,
            li=0,  # dds=(0, 20),
            n='%s_wireAttrs_DEFORMER' % (fp_name))
        fp_wire[0].dropoffDistance[0].set(20)
        hist = pm.listHistory(fp_surf)
        tweaks = [t for t in hist if 'tweak' in t.nodeName()]
        pm.rename(tweaks[2], '%s_cl_cluster_tweak' % (fp_name))
        pm.rename(tweaks[0], '%s_wireAttrs_tweak' % (fp_name))
        pm.rename(tweaks[1], '%s_extra_tweak' % (fp_name))

        # group clusters
        cl_grp = pm.group(cl_a[1],
                          cl_b[1],
                          cl_mid[1],
                          n='%s_cls_GRP' % (fp_name))
        util.lock_and_hide_all(cl_grp)

        # creates mid control
        self.ctrl_mid = self.flexiplane_mid_ctrl(name='%s_ctrl_mid_CTRL' %
                                                 (fp_name))
        ctrl_mid_grp = pm.group(self.ctrl_mid,
                                n='%s_grp_midBend_GRP' % (fp_name))
        pm.pointConstraint(self.ctrl_a,
                           self.ctrl_b,
                           ctrl_mid_grp,
                           o=[0, 0, 0],
                           w=1)

        # groups controls together and locks and hides group attributes
        ctrl_grp = pm.group(self.ctrl_a,
                            self.ctrl_b,
                            ctrl_mid_grp,
                            n='%s_ctrl_GRP' % (fp_name))
        util.lock_and_hide_all(ctrl_grp)

        # connecting translate attrs of control curves for to the clusters
        connect = []
        connect.append(self.ctrl_a.t >> cl_a[1].t)
        connect.append(self.ctrl_b.t >> cl_b[1].t)
        connect.append(self.ctrl_mid.t >> cl_mid[1].t)

        # makes mid_ctrl, flexiPlane and blendShape surfaces non renderable
        util.no_render(fp_surf)
        util.no_render(fp_bshp)
        util.no_render(self.ctrl_mid)

        # groups everything under 1 group then locks and hides the transform attrs of that group #flexiPlane_wire_surface0101BaseWire
        self.fp_grp = pm.group(
            fp_surf,
            flc_grp,
            fp_bshp,
            fp_wire,
            # '%s_wire_%s_BaseWire_GRP' % (fp_name, self.surfaceSuffix),
            cl_grp,
            ctrl_grp,
            n='%s_GRP' % (fp_name))
        util.lock_and_hide_all(self.fp_grp)

        # creates global move group and extraNodes
        fp_gm_grp = pm.group(fp_surf,
                             ctrl_grp,
                             n='%s_globalMove_GRP' % (fp_name))
        fp_xnodes_grp = pm.group(flc_grp,
                                 fp_bshp,
                                 fp_wire,
                                 '%s_wire_CVBaseWire' % (fp_name),
                                 cl_grp,
                                 n='%s_extraNodes_GRP' % (fp_name))
        pm.parent(fp_twist, fp_xnodes_grp)
        pm.parent(fp_xnodes_grp, self.fp_grp)
        fp_xnodes_grp.overrideEnabled.set(1)
        fp_xnodes_grp.overrideDisplayType.set(2)

        # scale constrains follicles to global move group
        for follicle in flcs:
            mparent = follicle.getParent()
            pm.scaleConstraint(fp_gm_grp, mparent)

        # creates global move control
        self.fp_gm_ctrl = self.global_ctrl(name=fp_name)

        # moves global control into flexiPlane group then parent global move group to global move control.
        pm.parent(self.fp_gm_ctrl, self.fp_grp)
        pm.parent(fp_gm_grp, self.fp_gm_ctrl)

        # joints placement
        jnts = []
        for i in range(0, len(flcs)):
            posx = round(flcs[i].getParent().translateX.get(), 4)
            jnt = pm.joint(p=(posx, 0, 0),
                           rad=0.5,
                           n='%sbind_%s_JNT' % (fp_name, letters[i + 26]))
            jnts.append(jnt)
            # parent joint under follicle
            pm.parent(jnt, flcs[i].getParent())

        # locks and hides transformNodes flexiPlane surface
        util.lock_and_hide_all(fp_surf)
        # hides blendShape, clusters and twist Deformer
        fp_twist[1].visibility.set(0)
        cl_grp.visibility.set(0)
        fp_bshp.visibility.set(0)
        fp_curve.visibility.set(0)

        # selects the wire deformer and creates a curve info node...
        # ...to get the wire deformers length
        pm.select(fp_curve, r=True)
        length = pm.arclen(ch=1)
        length.rename('%scurveInfo_DEFORMER' % (fp_name))

        # creates a multiplyDivideNode for squashStretch length...
        # ...and sets it operation to divide
        fp_div = pm.createNode('multiplyDivide',
                               n='%sdiv_squashStretch_length' % (fp_name))
        fp_div.operation.set(2)

        # secondary multDivNode for volume, sets input1X to 1
        fp_div_vol = pm.createNode('multiplyDivide',
                                   n='%sdiv_volume' % (fp_name))
        fp_div_vol.operation.set(2)
        fp_div_vol.input1X.set(1)

        # creates a conditionNode for global_ctrl enable attr
        fp_cond = pm.createNode('condition', n='%scond_volume' % (fp_name))
        fp_cond.secondTerm.set(1)

        # connects curve all the nodes
        connect = length.arcLength >> fp_div.input1.input1X
        fp_div.input2.input2X.set(10)
        connect = fp_div.outputX >> fp_div_vol.input2.input2X
        connect = self.fp_gm_ctrl.enable >> fp_cond.firstTerm
        connect = fp_div_vol.outputX >> fp_cond.colorIfTrueR
        fp_ctrl_global = self.fp_gm_ctrl.getShape()

        for i in range(0, len(flcs)):
            connect = fp_cond.outColorR >> jnts[i].sy
            connect = fp_cond.outColorR >> jnts[i].sz
            flcs[i].visibility.set(0)

        # hides blendShape, clusters and twist Deformer
        fp_twist[1].visibility.set(0)
        cl_grp.visibility.set(0)
        fp_bshp.visibility.set(0)
        fp_curve.visibility.set(0)

        pm.select(self.fp_gm_ctrl, r=True)
        return self.fp_gm_ctrl
Beispiel #55
0
def save(filename,
         objs=None,
         forceOverwrite=False,
         forceKeys=False,
         start=None,
         end=None):
    '''
    Given a list of objects, save all the anim curves for t/r/s/v and user defined
    to the given filename.
    
    :param bool forceOverwrite: Allow prompting if the dest file already exists
    :param bool forceKeys: Put keys on the objects
    
    ..  todo::
        * Check if an attribute ISN'T keyed in the source and mark the static
            value somehow.  Specifically, if parent/world stuff isn't present,
            copying animations goes poorly.
        * At some point animation layers need to be addressed properly.
    
    '''
    global TAGGING_ATTR
    # USING CMDS VERSION FOR SPEED
    #listAttr = cmds.listAttr
    #listConnections = cmds.listConnections
    #addAttr = cmds.addAttr
    #setAttr = cmds.setAttr
    #duplicate = cmds.duplicate
    # ---
    sel = selected()
    objs = objs if objs else selected()

    info = createNode('network')
    info.addAttr('start', at='long')
    info.addAttr('end', at='long')
    info.addAttr('staticValues', dt='string')

    if start is None:
        start = playbackOptions(q=True, min=True)
    if end is None:
        end = playbackOptions(q=True, max=True)

    if start >= end:
        end = start + 1

    info.start.set(start)
    info.end.set(end)

    defaultAttrs = [t + a for t in 'trs' for a in 'xyz'] + ['visibility']

    dups = []
    staticValues = {}

    for obj in objs:
        zooHack = ['ikBlend'] if obj.hasAttr('ikBlend') else [
        ]  # Since use uses builtin ik trans, this doesn't get picked up.

        if obj.hasAttr('tx'):
            attrs = chain(listAttr(obj.name(), ud=True, k=True), defaultAttrs,
                          zooHack)
        else:
            attrs = chain(listAttr(obj.name(), ud=True, k=True), zooHack)

        for attr in attrs:
            _processAttr(obj.name() + '.' + attr, dups, forceKeys,
                         staticValues, start, end)

    if not dups:
        warning("Nothing was animated")
        return

    info.staticValues.set(core.text.asciiCompress(json.dumps(staticValues)))

    select(dups, info)
    exportSelected(filename, force=forceOverwrite)
    select(sel)
    delete(dups)
Beispiel #56
0
    def addOperators(self):

        # 1 bone chain Upv ref =====================================================================================
        self.ikHandleUpvRef = pri.addIkHandle(self.root, self.getName("ikHandleLegChainUpvRef"), self.legChainUpvRef, "ikSCsolver")
        pm.pointConstraint(self.ik_ctl, self.ikHandleUpvRef)
        pm.parentConstraint( self.legChainUpvRef[0], self.ik_ctl, self.upv_cns, mo=True)

        # Visibilities -------------------------------------
        #shape.dispGeometry
        # fk
        fkvis_node = nod.createReverseNode(self.blend_att)

        for shp in self.fk0_ctl.getShapes():
            pm.connectAttr(fkvis_node+".outputX", shp.attr("visibility"))
        for shp in self.fk1_ctl.getShapes():
            pm.connectAttr(fkvis_node+".outputX", shp.attr("visibility"))
        for shp in self.fk2_ctl.getShapes():
            pm.connectAttr(fkvis_node+".outputX", shp.attr("visibility"))

        # ik
        for shp in self.upv_ctl.getShapes():
            pm.connectAttr(self.blend_att, shp.attr("visibility"))
        for shp in self.ikcns_ctl.getShapes():
            pm.connectAttr(self.blend_att, shp.attr("visibility"))
        for shp in self.ik_ctl.getShapes():
            pm.connectAttr(self.blend_att, shp.attr("visibility"))

        # IK Solver -----------------------------------------
        out = [self.bone0, self.bone1, self.ctrn_loc, self.eff_loc]
        node = aop.gear_ikfk2bone_op(out, self.root_ctl, self.ik_ref, self.upv_ctl, self.fk_ctl[0], self.fk_ctl[1], self.fk_ref, self.length0, self.length1, self.negate)

        pm.connectAttr(self.blend_att, node+".blend")
        if self.negate:
            mulVal = -1
        else:
            mulVal = 1
        nod.createMulNode(self.roll_att, mulVal, node+".roll")
        # pm.connectAttr(self.roll_att, node+".roll")
        pm.connectAttr(self.scale_att, node+".scaleA")
        pm.connectAttr(self.scale_att, node+".scaleB")
        pm.connectAttr(self.maxstretch_att, node+".maxstretch")
        pm.connectAttr(self.slide_att, node+".slide")
        pm.connectAttr(self.softness_att, node+".softness")
        pm.connectAttr(self.reverse_att, node+".reverse")

        # Twist references ---------------------------------
        self.ikhArmRef, self.tmpCrv = aop.splineIK(self.getName("legRollRef"), self.rollRef, parent=self.root, cParent=self.bone0 )


        pm.pointConstraint(self.mid_ctl, self.tws1_loc, maintainOffset=False)
        pm.scaleConstraint(self.mid_ctl, self.tws1_loc, maintainOffset=False)
        aop.oriCns(self.mid_ctl, self.tws1_rot, maintainOffset=False)

        pm.pointConstraint(self.eff_loc, self.tws2_loc, maintainOffset=False)
        pm.scaleConstraint(self.eff_loc, self.tws2_loc, maintainOffset=False)
        aop.oriCns(self.bone1, self.tws2_loc, maintainOffset=False)

        aop.oriCns(self.tws_ref, self.tws2_rot)

        self.tws0_loc.setAttr("sx", .001)
        self.tws2_loc.setAttr("sx", .001)

        add_node = nod.createAddNode(self.roundness_att, .001)
        pm.connectAttr(add_node+".output", self.tws1_rot.attr("sx"))

        # Volume -------------------------------------------
        distA_node = nod.createDistNode(self.tws0_loc, self.tws1_loc)
        distB_node = nod.createDistNode(self.tws1_loc, self.tws2_loc)
        add_node = nod.createAddNode(distA_node+".distance", distB_node+".distance")
        div_node = nod.createDivNode(add_node+".output", self.root_ctl.attr("sx"))

        #comp scaling issue
        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(self.root.attr("worldMatrix"), dm_node+".inputMatrix")

        div_node2 = nod.createDivNode(div_node+".outputX", dm_node+".outputScaleX")


        self.volDriver_att = div_node2+".outputX"

        # Divisions ----------------------------------------
        # at 0 or 1 the division will follow exactly the rotation of the controler.. and we wont have this nice tangent + roll
        for i, div_cns in enumerate(self.div_cns):
            subdiv = False
            if i == len(self.div_cns)-1 or i == 0:
                subdiv = 45
            else:
                subdiv = 10


            if i < (self.settings["div0"]+1):
                perc = i*.5 / (self.settings["div0"]+1.0)
            elif i < (self.settings["div0"] + 2):
                perc = .49
                subdiv = 45
            elif i < (self.settings["div0"] +  3 ):
                perc = .50
                subdiv = 45
            elif i < (self.settings["div0"] +  4 ):
                perc = .51
                subdiv = 45

            else:
                perc = .5 + (i-self.settings["div0"]-3.0)*.5 / (self.settings["div1"]+1.0)

            perc = max(.001, min(.999, perc))

            # Roll
            if self.negate:
                node = aop.gear_rollsplinekine_op(div_cns, [self.tws2_rot, self.tws1_rot, self.tws0_rot], 1-perc, subdiv)
            else:
                node = aop.gear_rollsplinekine_op(div_cns, [self.tws0_rot, self.tws1_rot, self.tws2_rot], perc, subdiv)

            pm.connectAttr(self.resample_att, node+".resample")
            pm.connectAttr(self.absolute_att, node+".absolute")

            # Squash n Stretch
            node = aop.gear_squashstretch2_op(div_cns, None, pm.getAttr(self.volDriver_att), "x")
            pm.connectAttr(self.volume_att, node+".blend")
            pm.connectAttr(self.volDriver_att, node+".driver")
            pm.connectAttr(self.st_att[i], node+".stretch")
            pm.connectAttr(self.sq_att[i], node+".squash")



        # NOTE: next line fix the issue on meters.
        # This is special case becasuse the IK solver from mGear use the scale as lenght and we have shear
        # TODO: check for a more clean and elegant solution instead of re-match the world matrix again
        # tra.matchWorldTransform(self.fk_ctl[0], self.match_fk0_off)
        # tra.matchWorldTransform(self.fk_ctl[1], self.match_fk1_off)
        # tra.matchWorldTransform(self.fk_ctl[0], self.match_fk0)
        # tra.matchWorldTransform(self.fk_ctl[1], self.match_fk1)

        # match IK/FK ref
        pm.parentConstraint(self.bone0, self.match_fk0_off, mo=True)
        pm.parentConstraint(self.bone1, self.match_fk1_off, mo=True)
        return
Beispiel #57
0
def bs_createTextureBase(assetName, assetGrade, assetType, episode=None):
    """
    @ create Texture Base group in reference model file in rig.
    Args:
        assetName (str): Model Name.
        assetGrade (str): Character Grade (Primary, Secondary, Tertiary).
        assetType (str): Asset Type Character, Prop, Set, Vehicle
        episode (str): asset Name dodo is like (dod).

    Returns:
            top Texture group.
    """
    # raise popup window for current scene will be discarded if maya is not in batch mode.
    if not pm.about(batch=True):
        confirmation = pm.windows.confirmDialog(
            title='Confirm',
            message="Don't Save Current Scene\nAnd Load New Scene?",
            button=['Yes', 'No'],
            defaultButton='Yes')
        if confirmation == 'Yes':
            pm.newFile(f=True)
        else:
            print 'process cancelled',
            return False
    # get environments.
    serverPath = bs_pathGenerator.bs_getEnv()['projectDir']
    # get model directory.
    if bs_pathGenerator.bs_getEnv()['projectType'] == 'series':
        modelFile = bs_pathGenerator.bs_getOnlyFinalFileOfDept(assetType,
                                                               'Model',
                                                               assetName,
                                                               episode=episode)
    else:
        modelFile = bs_pathGenerator.bs_getOnlyFinalFileOfDept(
            assetType, 'Model', assetName)
    # create path using environment variable.
    modelFile = modelFile.replace(serverPath, '$BSW_PROJECT_DIR')
    bs_reference.bs_createReference(modelFile,
                                    prefixStyle='withoutNamespace',
                                    prefixName='')
    # create Texture Group.
    topGrp = pm.createNode('transform', n='Texture_Group', ss=True)
    # add asset uid.
    astTypShortCode = {
        'Character': 'ch',
        'Prop': 'pr',
        'Set': 'bg',
        'Vehicle': 'vh',
        'SetElement': 'se'
    }
    if bs_pathGenerator.bs_getEnv()['projectType'] == 'series':
        uid = 'bsw_' + astTypShortCode[
            assetType] + '_' + assetName + '_tex_' + episode
    else:
        uid = 'bsw_' + astTypShortCode[assetType] + '_' + assetName + '_tex'
    # add attributes.
    pm.addAttr(topGrp, ln='assetBase', dt='string', k=True)
    pm.addAttr(topGrp, ln='assetType', dt='string', k=True)
    pm.addAttr(topGrp, ln='assetName', dt='string', k=True)
    pm.addAttr(topGrp, ln='assetGrade', dt='string', k=True)
    if bs_pathGenerator.bs_getEnv()['projectType'] == 'series':
        pm.addAttr(topGrp, ln='assetEpisode', dt='string', k=True)
    pm.addAttr(topGrp, ln='assetUID', dt='string', k=True)
    # set Values.
    pm.setAttr(topGrp + '.assetBase', 'Asset')
    pm.setAttr(topGrp + '.assetBase', l=True)
    pm.setAttr(topGrp + '.assetType', assetType)
    pm.setAttr(topGrp + '.assetType', l=True)
    pm.setAttr(topGrp + '.assetName', assetName)
    pm.setAttr(topGrp + '.assetName', l=True)
    pm.setAttr(topGrp + '.assetGrade', assetGrade)
    pm.setAttr(topGrp + '.assetGrade', l=True)
    if bs_pathGenerator.bs_getEnv()['projectType'] == 'series':
        pm.setAttr(topGrp + '.assetEpisode', episode)
        pm.setAttr(topGrp + '.assetEpisode', l=True)
    pm.setAttr(topGrp + '.assetUID', uid)
    pm.setAttr(topGrp + '.assetUID', l=True)
    # parent referenced model top group in texture group.
    pm.parent('geo', topGrp)
    if bs_pathGenerator.bs_getEnv()['projectType'] == 'series':
        bs_pathGenerator.bs_createAssetDirectories(assetType,
                                                   assetName,
                                                   episode=episode)
    else:
        bs_pathGenerator.bs_createAssetDirectories(assetType, assetName)
    bs_qui.bs_displayMessage(
        'success', 'asset Created success and created sourceimages directory')
    return topGrp
Beispiel #58
0
def addJnt(obj=False,
           parent=False,
           noReplace=False,
           grp=None,
           jntName=None,
           *args):
    """Create one joint for each selected object.

    Args:
        obj (bool or dagNode, optional): The object to drive the new
            joint. If False will use the current selection.
        parent (bool or dagNode, optional): The parent for the joint.
            If False will try to parent to jnt_org. If jnt_org doesn't
            exist will parent the joint under the obj
        noReplace (bool, optional): If True will add the extension
            "_jnt" to the new joint name
        grp (pyNode or None, optional): The set to add the new joint.
            If none will use "rig_deformers_grp"
        *args: Maya's dummy

    Returns:
        pyNode: The New created joint.

    """
    if not obj:
        oSel = pm.selected()
    else:
        oSel = [obj]

    for obj in oSel:
        if not parent:
            try:
                oParent = pm.PyNode("jnt_org")
            except TypeError:
                oParent = obj
        else:
            oParent = parent
        if not jntName:
            if noReplace:
                jntName = "_".join(obj.name().split("_")) + "_jnt"
            else:
                jntName = "_".join(obj.name().split("_")[:-1]) + "_jnt"
        jnt = pm.createNode("joint", n=jntName)

        if grp:
            grp.add(jnt)
        else:
            try:
                defSet = pm.PyNode("rig_deformers_grp")
                pm.sets(defSet, add=jnt)
            except TypeError:
                pm.sets(n="rig_deformers_grp")
                defSet = pm.PyNode("rig_deformers_grp")
                pm.sets(defSet, add=jnt)

        oParent.addChild(jnt)

        jnt.setAttr("jointOrient", 0, 0, 0)
        try:
            applyop.gear_matrix_cns(obj, jnt)
        except RuntimeError:
            for axis in ["tx", "ty", "tz", "rx", "ry", "rz"]:
                jnt.attr(axis).set(0.0)

    return jnt
Beispiel #59
0
    def addOperators(self):
        """Create operators and set the relations for the component rig

        Apply operators, constraints, expressions to the hierarchy.
        In order to keep the code clean and easier to debug,
        we shouldn't create any new object in this method.

        """

        # Visibilities -------------------------------------
        if self.isFkIk:
            # fk
            fkvis_node = node.createReverseNode(self.blend_att)

            for fk_ctl in self.fk_ctl:
                for shp in fk_ctl.getShapes():
                    pm.connectAttr(fkvis_node + ".outputX",
                                   shp.attr("visibility"))

            # ik
            for shp in self.upv_ctl.getShapes():
                pm.connectAttr(self.blend_att, shp.attr("visibility"))
            for shp in self.ikcns_ctl.getShapes():
                pm.connectAttr(self.blend_att, shp.attr("visibility"))
            for shp in self.ik_ctl.getShapes():
                pm.connectAttr(self.blend_att, shp.attr("visibility"))

        # FK Chain -----------------------------------------
        if self.isFk:
            for off, ref in zip(self.fk_off[1:], self.fk_ref):
                applyop.gear_mulmatrix_op(ref.worldMatrix,
                                          off.parentInverseMatrix, off, "rt")
        # IK Chain -----------------------------------------
        if self.isIk:
            self.ikh = primitive.addIkHandle(self.root, self.getName("ikh"),
                                             self.chain)
            self.ikh.attr("visibility").set(False)

            # Constraint and up vector
            pm.pointConstraint(self.ik_ctl, self.ikh, maintainOffset=False)
            pm.poleVectorConstraint(self.upv_ctl, self.ikh)

            # TwistTest
            o_list = [round(elem, 4) for elem
                      in transform.getTranslation(self.chain[1])] \
                != [round(elem, 4) for elem in self.guide.apos[1]]

            if o_list:
                add_nodeTwist = node.createAddNode(180.0, self.roll_att)
                pm.connectAttr(add_nodeTwist + ".output",
                               self.ikh.attr("twist"))
            else:
                pm.connectAttr(self.roll_att, self.ikh.attr("twist"))

        # Chain of deformers -------------------------------
        for i, loc in enumerate(self.loc):

            if self.settings["mode"] == 0:  # fk only
                pm.parentConstraint(self.fk_ctl[i], loc, maintainOffset=False)
                pm.connectAttr(self.fk_ctl[i] + ".scale", loc + ".scale")

            elif self.settings["mode"] == 1:  # ik only
                pm.parentConstraint(self.chain[i], loc, maintainOffset=False)

            elif self.settings["mode"] == 2:  # fk/ik

                rev_node = node.createReverseNode(self.blend_att)

                # orientation
                cns = pm.parentConstraint(self.fk_ctl[i],
                                          self.chain[i],
                                          loc,
                                          maintainOffset=False)
                cns.interpType.set(0)
                weight_att = pm.parentConstraint(cns,
                                                 query=True,
                                                 weightAliasList=True)
                pm.connectAttr(rev_node + ".outputX", weight_att[0])
                pm.connectAttr(self.blend_att, weight_att[1])

                # scaling
                blend_node = pm.createNode("blendColors")
                pm.connectAttr(self.chain[i].attr("scale"),
                               blend_node + ".color1")
                pm.connectAttr(self.fk_ctl[i].attr("scale"),
                               blend_node + ".color2")
                pm.connectAttr(self.blend_att, blend_node + ".blender")
                pm.connectAttr(blend_node + ".output", loc + ".scale")
Beispiel #60
0
def ghostSlider(ghostControls, surface, sliderParent):
    """Modify the ghost control behaviour to slide on top of a surface

    Args:
        ghostControls (dagNode): The ghost control
        surface (Surface): The NURBS surface
        sliderParent (dagNode): The parent for the slider.
    """
    if not isinstance(ghostControls, list):
        ghostControls = [ghostControls]

    # Seleccionamos los controles Ghost que queremos mover sobre el surface

    surfaceShape = surface.getShape()

    for ctlGhost in ghostControls:
        ctl = pm.listConnections(ctlGhost, t="transform")[-1]
        t = ctl.getMatrix(worldSpace=True)

        gDriver = primitive.addTransform(ctlGhost.getParent(),
                                         ctl.name() + "_slideDriver", t)

        try:
            pm.connectAttr(ctl + ".translate", gDriver + ".translate")
            pm.disconnectAttr(ctl + ".translate", ctlGhost + ".translate")
        except RuntimeError:
            pass

        try:
            pm.connectAttr(ctl + ".scale", gDriver + ".scale")
            pm.disconnectAttr(ctl + ".scale", ctlGhost + ".scale")
        except RuntimeError:
            pass

        try:
            pm.connectAttr(ctl + ".rotate", gDriver + ".rotate")
            pm.disconnectAttr(ctl + ".rotate", ctlGhost + ".rotate")
        except RuntimeError:
            pass

        oParent = ctlGhost.getParent()
        npoName = "_".join(ctlGhost.name().split("_")[:-1]) + "_npo"
        oTra = pm.PyNode(
            pm.createNode("transform", n=npoName, p=oParent, ss=True))
        oTra.setTransformation(ctlGhost.getMatrix())
        pm.parent(ctlGhost, oTra)

        slider = primitive.addTransform(sliderParent,
                                        ctl.name() + "_slideDriven", t)

        # connexion

        dm_node = node.createDecomposeMatrixNode(
            gDriver.attr("worldMatrix[0]"))
        cps_node = pm.createNode("closestPointOnSurface")
        dm_node.attr("outputTranslate") >> cps_node.attr("inPosition")
        surfaceShape.attr("worldSpace[0]") >> cps_node.attr("inputSurface")
        cps_node.attr("position") >> slider.attr("translate")

        pm.normalConstraint(surfaceShape,
                            slider,
                            aimVector=[0, 0, 1],
                            upVector=[0, 1, 0],
                            worldUpType="objectrotation",
                            worldUpVector=[0, 1, 0],
                            worldUpObject=gDriver)

        pm.parent(ctlGhost.getParent(), slider)