Example #1
0
    def bdBuildSplineSolverScale(self,condition):
        
        print 'asdas'
        self.splineCurve = pm.listConnections(self.ikSpline, type = 'nurbsCurve')[0]

        effector = pm.listConnections(self.ikSpline ,source=True, type='ikEffector')[0]
        endJoint = pm.listConnections(effector,source=True, type='joint')[0]
        startJointChild = pm.listRelatives(self.startJoint,c=True, type='joint')[0]
        self.jointChain = []
        self.jointChain.append(self.startJoint)
        self.jointChain.append(startJointChild)
        while startJointChild.name() != endJoint.name():
            startJointChild = pm.listRelatives(startJointChild,c=True, type='joint')[0]
            self.jointChain.append(startJointChild)
        
        self.splineCurveScl = pm.duplicate(self.splineCurve,name = self.splineCurve.name().replace('crv','crv_scl'))
        strArclenSCL = pm.arclen(self.splineCurveScl,ch=True)
        strArclenCRV = pm.arclen(self.splineCurve,ch=True)
        arclenSCL = pm.ls( strArclenSCL ) [0]
        arclenCRV = pm.ls( strArclenCRV ) [0]
        arclenSCL.rename(self.splineCurveScl[0].name() + '_length')
        arclenCRV.rename(self.splineCurve.name() + '_length')
        
        mdScaleFactor = pm.createNode('multiplyDivide', name = self.splineCurve.name().replace('crv','crv_scaleFactor_md'))
        arclenCRV.arcLength.connect(mdScaleFactor.input1X)
        arclenSCL.arcLength.connect(mdScaleFactor.input2X)
        mdScaleFactor.operation.set(2)

        for jnt in self.jointChain:
            mdScaleFactor.outputX.connect(jnt.scaleX) 
Example #2
0
def gear_curveslide2_op(outcrv,
                        incrv,
                        position=0,
                        maxstretch=1,
                        maxsquash=1,
                        softness=0):
    """Apply a sn_curveslide2_op operator

    Arguments:
        outcrv (NurbsCurve): Out Curve.
        incrv (NurbsCurve):  In Curve.
        position (float): Default position value (from 0 to 1).
        maxstretch (float): Default maxstretch value (from 1 to infinite).
        maxsquash (float): Default maxsquash value (from 0 to 1).
        softness (float): Default softness value (from 0 to 1).

    Returns:
        pyNode: The newly created operator.
    """
    pm.select(outcrv)
    node = pm.deformer(type="mgear_slideCurve2")[0]

    pm.connectAttr(incrv + ".local", node + ".master_crv")
    pm.connectAttr(incrv + ".worldMatrix", node + ".master_mat")

    pm.setAttr(node + ".master_length", pm.arclen(incrv))
    pm.setAttr(node + ".slave_length", pm.arclen(incrv))
    pm.setAttr(node + ".position", 0)
    pm.setAttr(node + ".maxstretch", 1)
    pm.setAttr(node + ".maxsquash", 1)
    pm.setAttr(node + ".softness", 0)

    return node
Example #3
0
def bdBuildSplineSolverScale():
    selection = pm.ls(sl=1, type='transform')
    startJoint = ''
    if selection:
        startJoint = selection[0]
    else:
        return

    print startJoint

    ikSpline = pm.listConnections(startJoint, type='ikHandle')[0]
    print ikSpline
    solver = ikSpline.ikSolver.inputs()[0]

    if 'ikSplineSolver' in solver.name():
        sclChain = pm.duplicate(startJoint, name=startJoint.name() + '_SCL')[0]
        sclChainAll = sclChain.listRelatives(f=True, ad=True, type='joint')

        print sclChainAll

        for sclJnt in sclChainAll:
            pm.rename(sclJnt, sclJnt + '_SCL')

        splineCurve = pm.listConnections(ikSpline, type='nurbsCurve')[0]

        effector = pm.listConnections(ikSpline, source=True,
                                      type='ikEffector')[0]
        endJoint = pm.listConnections(effector, source=True, type='joint')[0]
        jointChain = startJoint.listRelatives(f=True, ad=True, type='joint')
        jointChain = jointChain + [startJoint]
        jointChain.reverse()
        print jointChain

        splineCurveScl = pm.duplicate(splineCurve,
                                      name=splineCurve.name().replace(
                                          'crv', 'crv_scl'))
        strArclenSCL = pm.arclen(splineCurveScl, ch=True)
        strArclenCRV = pm.arclen(splineCurve, ch=True)
        arclenSCL = pm.ls(strArclenSCL)[0]
        arclenCRV = pm.ls(strArclenCRV)[0]
        arclenSCL.rename(splineCurveScl[0].name() + '_length')
        arclenCRV.rename(splineCurve.name() + '_length')

        mdScaleFactor = pm.createNode('multiplyDivide',
                                      name=splineCurve.name().replace(
                                          'crv', 'crv_scaleFactor_md'))
        arclenCRV.arcLength.connect(mdScaleFactor.input1X)
        arclenSCL.arcLength.connect(mdScaleFactor.input2X)
        mdScaleFactor.operation.set(2)

        for jnt in jointChain[1:]:
            mdJntTr = pm.createNode('multiplyDivide', name=jnt + '_trX_MD')
            #mdJntTr.operation.set(2)

            sclJnt = pm.ls(jnt + '_SCL')[0]
            mdScaleFactor.outputX.connect(mdJntTr.input2X)
            sclJnt.translateX.connect(mdJntTr.input1X)
            mdJntTr.outputX.connect(jnt.translateX)
Example #4
0
def bdBuildSplineSolverScale():
    selection = pm.ls(sl=1,type='transform')
    startJoint = ''
    if selection:
        startJoint = selection[0]
    else:
        return
    
    print startJoint
    
    ikSpline  = pm.listConnections(startJoint,type='ikHandle')[0]
    print ikSpline  
    solver = ikSpline.ikSolver.inputs()[0]
    
    if 'ikSplineSolver' in solver.name():
        sclChain = pm.duplicate(startJoint,name = startJoint.name() + '_SCL')[0]
        sclChainAll = sclChain.listRelatives(f=True, ad=True,type='joint')
        
        print sclChainAll  
        
        for sclJnt in sclChainAll:
            pm.rename(sclJnt,sclJnt+'_SCL')
        
        splineCurve = pm.listConnections(ikSpline, type = 'nurbsCurve')[0]
    
        effector = pm.listConnections(ikSpline ,source=True, type='ikEffector')[0]
        endJoint = pm.listConnections(effector,source=True, type='joint')[0]
        jointChain = startJoint.listRelatives(f=True, ad=True,type='joint')
        jointChain  = jointChain + [startJoint]
        jointChain.reverse()
        print jointChain
        
        splineCurveScl = pm.duplicate(splineCurve,name = splineCurve.name().replace('crv','crv_scl'))
        strArclenSCL = pm.arclen(splineCurveScl,ch=True)
        strArclenCRV = pm.arclen(splineCurve,ch=True)
        arclenSCL = pm.ls( strArclenSCL ) [0]
        arclenCRV = pm.ls( strArclenCRV ) [0]
        arclenSCL.rename(splineCurveScl[0].name() + '_length')
        arclenCRV.rename(splineCurve.name() + '_length')
        
        mdScaleFactor = pm.createNode('multiplyDivide', name = splineCurve.name().replace('crv','crv_scaleFactor_md'))
        arclenCRV.arcLength.connect(mdScaleFactor.input1X)
        arclenSCL.arcLength.connect(mdScaleFactor.input2X)
        mdScaleFactor.operation.set(2)
    
        for jnt in jointChain[1:]:
            mdJntTr = pm.createNode('multiplyDivide', name = jnt + '_trX_MD')
            #mdJntTr.operation.set(2)
            
            sclJnt = pm.ls(jnt + '_SCL')[0]
            mdScaleFactor.outputX.connect(mdJntTr.input2X)
            sclJnt.translateX.connect(mdJntTr.input1X)
            mdJntTr.outputX.connect(jnt.translateX)
    def _build(self, *args):
        """
        Builds the joints on the curve.
        """
        # naming convention
        asset = self.asset
        side = self.side
        part = self.part
        joints = self.joints
        suffix = self.suffix

        if self.gui:
            asset = self.asset_name.text()
            side = self.side.currentText()
            part = self.part_name.text()
            joints = self.joints_box.value()
            suffix = self.suffix.currentText()
        try:
            curve = pm.ls(sl=True)[0]
            curve_name = NameUtils.get_unique_name(asset, side, part, "crv")
            self.curve = pm.rename(curve, curve_name)
        except IndexError:
            pm.warning("Please select a curve")
            return

        length_of_curve = pm.arclen(self.curve)
        equal_spacing = length_of_curve / float(joints)

        # clear the selection
        pm.select(cl=True)

        # # create the joints
        curve_joints = list()
        for x in xrange(int(joints) + 1):
            name = NameUtils.get_unique_name(asset, side, part, suffix)
            joint = pm.joint(n=name)
            curve_joints.append(joint)

            joint_position = (x * equal_spacing)
            pm.move(0, joint_position, 0)
        
        # rename last joint
        last_joint = curve_joints[-1]
        pm.rename(last_joint, last_joint + "End")

        root_joint = pm.selected()[0].root()
        end_joint = pm.ls(sl=True)[0]
        solver = 'ikSplineSolver'

        # attach joints to curve
        ik_name = NameUtils.get_unique_name(asset, side, part, "ikHandle")
        self.ikHandle = pm.ikHandle(sj=root_joint, ee=end_joint, sol=solver,
                        c=self.curve, pcv=True, roc=True, ccv=False, n=ik_name)
        joint_chain = pm.ls(root_joint, dag=True)

        # delete history
        pm.makeIdentity(root_joint, apply=True)

        # cleanup
        self._cleanup()
Example #6
0
def make_spline_streatch(ikHandle):
    '''
    '''
    joints = pm.ikHandle(ikHandle, q=True, jl=True)
    curve = pm.PyNode(pm.ikHandle(ikHandle, q=True, c=True)).getParent()

    if not curve.hasAttr('global_scale'):
        pm.addAttr(curve, ln='global_scale', dv=1, k=True)

    arcn = pm.arclen(curve, ch=True)
    mult = pm.createNode('multDoubleLinear')
    devi = pm.createNode('multiplyDivide')

    arcn.al >> devi.i1x

    curve.global_scale >> mult.i1
    arcn.al >> mult.i2
    arcn.al // mult.i2

    mult.o >> devi.i2x

    devi.op.set(2)

    for jnt in joints:
        devi.ox >> pm.PyNode('{0}.s{1}'.format(jnt, get_joint_axis(jnt)))

    return True
Example #7
0
def stretchyBack(ikHandleTorso, jntList):
    pymelLogger.debug('Starting: stretchyBack()...')
    #Stretchy process
    # ArcLen to create curveInfo
    curveInfoNodeBack = pm.arclen(ikHandleTorso[2], ch=True)
    # add attr to curveinfo Node (normalizedScale)
    # this will have a value coming from a multiply divide node that will be
    # dividing the current length by the initial length of the curve
    # this will be used later to scale the joints
    pm.addAttr(curveInfoNodeBack,
               longName='normalizedScale',
               attributeType='double')
    # get initial length of the curve
    iniLen = pm.getAttr(curveInfoNodeBack + '.arcLength')

    # create a node multiplydivide, operation set to division
    MDCurveBack = pm.shadingNode('multiplyDivide', asUtility=True)
    pm.setAttr(MDCurveBack + '.operation', 2)  # divide

    # Connect curve arcLength to input1X
    pm.connectAttr(curveInfoNodeBack + '.arcLength',
                   MDCurveBack + '.input1X',
                   force=True)
    # Set input2X to initial length of the curve
    pm.setAttr(MDCurveBack + '.input2X', iniLen)
    # connect outpux x from multiplydivide to normalized scale of the curve info
    pm.connectAttr(MDCurveBack + '.outputX',
                   curveInfoNodeBack + '.normalizedScale',
                   force=True)

    returnList = [curveInfoNodeBack, MDCurveBack]

    pymelLogger.debug('End: stretchyBack()...')
    return returnList
Example #8
0
    def addScale(self):
        self.splineCurveScl = pm.duplicate(self.crv, name=self.crv.replace('crv', 'crv_ori'))[0]
        strArclenSCL = pm.arclen(self.splineCurveScl, ch=True)
        strArclenCRV = pm.arclen(self.crv, ch=True)
        arclenSCL = pm.ls(strArclenSCL)[0]
        arclenCRV = pm.ls(strArclenCRV)[0]
        arclenSCL.rename(self.splineCurveScl[0].name() + '_length')
        arclenCRV.rename(self.crv + '_length')

        mdScaleFactor = pm.createNode('multiplyDivide', name=self.crv + '_scaleFactor_md')
        arclenCRV.arcLength.connect(mdScaleFactor.input1X)
        arclenSCL.arcLength.connect(mdScaleFactor.input2X)
        mdScaleFactor.operation.set(2)

        for jnt in self.ikJntList:
            mdScaleFactor.outputX.connect(jnt.scaleX)
Example #9
0
    def addScale(self):
        self.splineCurveScl = pm.duplicate(self.crv,name = self.crv.replace('crv','crv_ori'))[0]
        strArclenSCL = pm.arclen(self.splineCurveScl,ch=True)
        strArclenCRV = pm.arclen(self.crv,ch=True)
        arclenSCL = pm.ls( strArclenSCL ) [0]
        arclenCRV = pm.ls( strArclenCRV ) [0]
        arclenSCL.rename(self.splineCurveScl[0].name() + '_length')
        arclenCRV.rename(self.crv + '_length')
        
        mdScaleFactor = pm.createNode('multiplyDivide', name = self.crv + '_scaleFactor_md')
        arclenCRV.arcLength.connect(mdScaleFactor.input1X)
        arclenSCL.arcLength.connect(mdScaleFactor.input2X)
        mdScaleFactor.operation.set(2)

        for jnt in self.ikJntList:
            mdScaleFactor.outputX.connect(jnt.scaleX)        
Example #10
0
def stretchyBack( ikHandleTorso, jntList ):
    pymelLogger.debug('Starting: stretchyBack()...')     
    #Stretchy process
    # ArcLen to create curveInfo
    curveInfoNodeBack = pm.arclen( ikHandleTorso[2], ch=True )
    # add attr to curveinfo Node (normalizedScale)
    # this will have a value coming from a multiply divide node that will be 
    # dividing the current length by the initial length of the curve
    # this will be used later to scale the joints
    pm.addAttr(curveInfoNodeBack, longName='normalizedScale', attributeType='double')
    # get initial length of the curve
    iniLen = pm.getAttr( curveInfoNodeBack + '.arcLength' )
    
    # create a node multiplydivide, operation set to division
    MDCurveBack = pm.shadingNode( 'multiplyDivide', asUtility=True )
    pm.setAttr( MDCurveBack+'.operation', 2 ) # divide
    
    # Connect curve arcLength to input1X
    pm.connectAttr( curveInfoNodeBack + '.arcLength', MDCurveBack + '.input1X', force=True )
    # Set input2X to initial length of the curve
    pm.setAttr(MDCurveBack+'.input2X', iniLen)
    # connect outpux x from multiplydivide to normalized scale of the curve info
    pm.connectAttr(MDCurveBack + '.outputX', curveInfoNodeBack + '.normalizedScale', force=True)
    
    returnList = [curveInfoNodeBack,MDCurveBack]
    
    
    pymelLogger.debug('End: stretchyBack()...')   
    return returnList
Example #11
0
    def bdBuildRPSolverScale(self,condition):
        print 'RP Solver'
        
        #self.splineCurve = pm.listConnections(self.ikSpline, type = 'nurbsCurve')[0]
        pm.select(cl=True)
        ikGrp = pm.group(n=self.ikSpline.name() + '_GRP')
        ikParent = self.ikSpline.getParent()
        ikPos = self.ikSpline.getTranslation(space= 'world')
        ikGrp.setTranslation(ikPos)
        pm.parent(ikGrp,ikParent)
        pm.parent(self.ikSpline,ikGrp)
        

        sclJnt = pm.duplicate(self.startJoint, parentOnly = True , name = self.startJoint.name().replace('JNT','SCL'))[0]
        effector = pm.listConnections(self.ikSpline ,source=True, type='ikEffector')[0]
        endJoint = pm.listConnections(effector,source=True, type='joint')[0]
        startJointChild = pm.listRelatives(self.startJoint,c=True, type='joint')[0]
        self.jointChain = []
        self.jointChain.append(self.startJoint)
        self.jointChain.append(startJointChild)
        while startJointChild.name() != endJoint.name():
            startJointChild = pm.listRelatives(startJointChild,c=True, type='joint')[0]
            self.jointChain.append(startJointChild)
        
        jntPos = []
        for jnt in self.jointChain:
            pos = jnt.getTranslation(space= 'world')
            jntPos.append(pos)
        
        self.splineCurveScl = pm.curve(p=jntPos, degree =1, n = self.startJoint.name().replace('01_JNT','CRV_SCL'))
        self.splineCurveScl.setPivots(jntPos[0])
        pm.parent(self.splineCurveScl, sclJnt)
        
        strArclenSCL = pm.arclen(self.splineCurveScl,ch=True)
        arclenSCL = pm.ls( strArclenSCL ) [0]
        arclenSCL.rename(self.splineCurveScl.name() + '_length')
        distanceNode = pm.createNode('distanceBetween',name = self.startJoint.name().replace('_01_JNT','distance'))
        
        sclJnt.rotatePivotTranslate.connect(distanceNode.point1)
        ikGrp.rotatePivotTranslate.connect(distanceNode.point2)
        sclJnt.worldMatrix.connect(distanceNode.inMatrix1)
        ikGrp.worldMatrix.connect(distanceNode.inMatrix2)
     
        mdScaleFactor = pm.createNode('multiplyDivide', name = self.splineCurveScl.name().replace('CRV_SCL','CRV_scaleFactor_MD'))
        distanceNode.distance.connect(mdScaleFactor.input1X)
        arclenSCL.arcLength.connect(mdScaleFactor.input2X)
        mdScaleFactor.operation.set(2)

        cndScaleFactor = pm.createNode('condition', name = self.splineCurveScl.name().replace('CRV_SCL','CRV_scaleFactor_CND'))
        distanceNode.distance.connect(cndScaleFactor.firstTerm)
        arclenSCL.arcLength.connect(cndScaleFactor.secondTerm)
        mdScaleFactor.outputX.connect(cndScaleFactor.colorIfTrueR)
        
        cndScaleFactor.operation.set(2)
        
        
        for jnt in self.jointChain:
            cndScaleFactor.outColorR.connect(jnt.scaleX)                 
Example #12
0
    def add_squash_n_stretch(self, follicles):
        """ 
        Args:
            None
        Returns (None)
        Usage:
        """
        base_name = '%s_flexiPlane' % self.flexiPlaneNameField.getText()
        wire_name =  '%s_wire_CRV' % base_name
        main_crv_name =  '%s_main_CTRL' % base_name
        
        wire = pm.PyNode(wire_name)
        
        arc_len = pm.arclen(wire, ch = True)
        pm.rename( arc_len, wire_name + 'info' )
        arc_len_val = pm.getAttr( wire_name + 'info.arcLength')
        
        multDiv_length = pm.shadingNode( 'multiplyDivide', asUtility = True )
        pm.rename( multDiv_length, base_name  + '_div_squashStretch_length' )
        pm.setAttr( base_name  + '_div_squashStretch_length.operation', 2 )
        
        pm.connectAttr( wire_name + 'info.arcLength', base_name  + '_div_squashStretch_length.input1X' )
        pm.setAttr( base_name  + '_div_squashStretch_length.input2X', arc_len_val )
        
        multDiv_volume = pm.shadingNode( 'multiplyDivide', asUtility = True )
        pm.rename( multDiv_volume, base_name  + '_div_volume' )
        pm.setAttr( base_name  + '_div_volume.operation', 2 )
        pm.setAttr( base_name  + '_div_volume.input1X', 1 )
        
        pm.connectAttr( base_name  + '_div_squashStretch_length.outputX', base_name  + '_div_volume.input2X', f = True )
        
        conditional_volume = pm.shadingNode( 'condition', asUtility = True )
        pm.rename( conditional_volume, base_name  + '_cond_volume' )
        pm.setAttr( base_name  + '_cond_volume.secondTerm', 1 )
        pm.connectAttr( main_crv_name + '.squashN_stretch', base_name  + '_cond_volume.firstTerm' )

        multDiv_globelScale = pm.shadingNode( 'multiplyDivide', asUtility = True )
        pm.rename( multDiv_globelScale, base_name  + '_mult_globalScale' )
        pm.connectAttr( base_name  + '_div_volume.outputX', base_name  + '_mult_globalScale.input1X' )
        pm.connectAttr( main_crv_name  + '.scaleX', base_name  + '_mult_globalScale.input2X' )
        pm.connectAttr( base_name  + '_mult_globalScale.outputX', base_name  + '_cond_volume.colorIfTrueR' )

        for index,follicle in enumerate(follicles):
            jnt_name = self.format_string.format(PREFIX = self.flexiPlaneNameField.getText(),
                                                 INDEX = 'flexiPlane_jnt%03d' % (index+1),
                                                 SUFFIX = 'JNT')
            jnt_offset_name = jnt_name.replace('_JNT','Offset_GRP')
            tweek_crv_name = self.format_string.format(PREFIX = self.flexiPlaneNameField.getText(),
                                                 INDEX = 'flexiPlane_tweak%03d' % (index+1),
                                                 SUFFIX = 'CTRL')
            
            pm.scaleConstraint( tweek_crv_name + 'Con_GRP', jnt_offset_name )
            pm.connectAttr( base_name  + '_cond_volume.outColorR', jnt_name + '.scaleX')
            pm.connectAttr( base_name  + '_cond_volume.outColorR', jnt_name + '.scaleZ')
            
            pm.select( clear = True )
Example #13
0
    def duplicateAlongPath(self, *args):
        '''
        ------------------------------------------

            position along curve

        ------------------------------------------
        '''
        inputX = pm.intField(self.widgets['numberOfDuplicates'],
                             q=True,
                             v=True)
        GOD_object = pm.ls(sl=True)[0]
        curve = pm.textFieldButtonGrp(self.widgets['curvePath'],
                                      q=True,
                                      tx=True)
        pathLength = pm.arclen(curve, ch=False)
        randomON = pm.checkBox(self.widgets['RandomPathDistance'],
                               q=True,
                               v=True)
        n = 0

        pathIncrement = 1.0 / inputX

        for increment in range(inputX):

            object = pm.duplicate(GOD_object, rc=True)
            objGroup = pm.group(object)
            motionPath = pm.pathAnimation(objGroup,
                                          fm=True,
                                          f=True,
                                          fa='x',
                                          ua='y',
                                          wut='scene',
                                          c=curve)
            pm.delete(pm.listConnections(motionPath + '.uValue'))
            value = rand.uniform(n, (n + pathIncrement))
            if randomON == True:
                pm.setAttr(motionPath + '.uValue', value)
                randomRotate = rand.randint(0, 360)

                randomScale = rand.uniform(
                    (pm.floatField(self.widgets['randomizeScaleMINPath'],
                                   q=True,
                                   v=True)),
                    (pm.floatField(self.widgets['randomizeScaleMAXPath'],
                                   q=True,
                                   v=True)))
                print object
                pm.setAttr(object[0] + '.ry', randomRotate)
                pm.setAttr(object[0] + '.sx', randomScale)
                pm.setAttr(object[0] + '.sy', randomScale)
                pm.setAttr(object[0] + '.sz', randomScale)
            else:
                pm.setAttr(motionPath + '.uValue', n)
            n = n + pathIncrement
            pm.parent(objGroup, 'ROOT_enviroment_01')
Example #14
0
def IK_createAveObj(cur, number, s="group"):

    newCur = pm.duplicate(cur, rr=1, n=cur + "_copyCurve1")
    curInfo = pm.arclen(cur, ch=1)
    ns = int(curInfo.arcLength.get())
    pm.delete(curInfo)
    pm.rebuildCurve(newCur,
                    ch=1,
                    rpo=1,
                    rt=0,
                    end=1,
                    kr=0,
                    kcp=0,
                    kep=1,
                    kt=0,
                    s=ns * 100,
                    d=3,
                    tol=0.01)

    allNewInfo = []
    aimObj = []

    p = 1.0 / float((number - 1))
    prF = 0.0

    if s == "position":
        allPoistion = []

    for i in range(number):
        if i == number - 1:
            NewInfo = pm.pointOnCurve(newCur, ch=1, top=1, pr=1)
        else:
            NewInfo = pm.pointOnCurve(newCur, ch=1, top=1, pr=prF)
            prF += p
        allNewInfo.append(NewInfo)

        t = pm.getAttr(NewInfo + ".position")

        if s == "position":
            allPoistion.append(t)

        if s == "group":
            obj = pm.group(em=1, n=cur + "_AimGrp" + str(i + 1))
            aimObj.append(obj)
            pm.setAttr(obj + ".translate", t)
            cmds.select(cl=1)

    pm.delete(allNewInfo, newCur)

    if s == "position":
        return allPoistion

    if s == "group":
        return aimObj
Example #15
0
    def bdBuildSplineSolverScale(self, condition):

        print 'asdas'
        self.splineCurve = pm.listConnections(self.ikSpline,
                                              type='nurbsCurve')[0]

        effector = pm.listConnections(self.ikSpline,
                                      source=True,
                                      type='ikEffector')[0]
        endJoint = pm.listConnections(effector, source=True, type='joint')[0]
        startJointChild = pm.listRelatives(self.startJoint,
                                           c=True,
                                           type='joint')[0]
        self.jointChain = []
        self.jointChain.append(self.startJoint)
        self.jointChain.append(startJointChild)
        while startJointChild.name() != endJoint.name():
            startJointChild = pm.listRelatives(startJointChild,
                                               c=True,
                                               type='joint')[0]
            self.jointChain.append(startJointChild)

        self.splineCurveScl = pm.duplicate(
            self.splineCurve,
            name=self.splineCurve.name().replace('crv', 'crv_scl'))
        strArclenSCL = pm.arclen(self.splineCurveScl, ch=True)
        strArclenCRV = pm.arclen(self.splineCurve, ch=True)
        arclenSCL = pm.ls(strArclenSCL)[0]
        arclenCRV = pm.ls(strArclenCRV)[0]
        arclenSCL.rename(self.splineCurveScl[0].name() + '_length')
        arclenCRV.rename(self.splineCurve.name() + '_length')

        mdScaleFactor = pm.createNode('multiplyDivide',
                                      name=self.splineCurve.name().replace(
                                          'crv', 'crv_scaleFactor_md'))
        arclenCRV.arcLength.connect(mdScaleFactor.input1X)
        arclenSCL.arcLength.connect(mdScaleFactor.input2X)
        mdScaleFactor.operation.set(2)

        for jnt in self.jointChain:
            mdScaleFactor.outputX.connect(jnt.scaleX)
Example #16
0
 def create_ik_spline(self, *args):
     """ Creates an ik spline with ik ctrls from the start and end locators, with the given selection the names will
     be neck,head and else. This uses the crv type, crv color, locator scale for the ctrl crvs. This uses joints from
      the create_jnt_chain, and makes a spline ik handle with advanced twist attributes for every rotation.
     :param args:
     :return: None
     """
     # create ik handle spline solver
     pm.ikHandle(n='{}_iks'.format(self.name),
                 sj=self.jnt_chain[0],
                 ee=self.jnt_chain[int(self.number)],
                 sol='ikSplineSolver',
                 ns=1,
                 ccv=True)
     # get the name for crv
     ik_crv = '{}_ik_crv'.format(self.name)
     # rename the ik spline handle crv
     pm.rename(pm.listConnections('{}_iks'.format(self.name), t='shape'),
               ik_crv)
     # select the ik crv
     pm.select(ik_crv, r=True)
     # create a curve info
     crv_info = pm.arclen(ik_crv, ch=True)
     # rename the curve info
     pm.rename(crv_info, '{}_ik_crv_info'.format(self.name))
     # enable advanced twist controls in ik handle
     pm.setAttr('{}_iks.dTwistControlEnable'.format(self.name), 1)
     # more advanced twist option changes
     pm.setAttr('{}_iks.dWorldUpType'.format(self.name), 4)
     # creating the ik ctrls by using the ik_ctrl_wloc module
     start_loc_name, start_ctrl_name, self.top_start_grp = ik_ctrl_wloc(
         self.name, self.ik_ctrl_s_scale, self.jnt_chain[0], self.crv_type,
         self.color_index)
     end_loc_name, end_ctrl_name, self.top_end_grp = ik_ctrl_wloc(
         self.name_end, self.ik_ctrl_e_scale,
         self.jnt_chain[int(self.number)], self.crv_type, self.color_index)
     pm.connectAttr('{}.worldMatrix[0]'.format(start_loc_name),
                    '{}_iks.dWorldUpMatrix'.format(self.name))
     pm.connectAttr('{}.worldMatrix[0]'.format(end_loc_name),
                    '{}_iks.dWorldUpMatrixEnd'.format(self.name))
     # get the span number form the ik crv spans and degrees
     crv_cv = pm.getAttr(ik_crv + '.spans') + pm.getAttr(ik_crv + '.degree')
     # get the position and create a locator to that position
     for x in range(crv_cv):
         source_node = pm.pointPosition(ik_crv + '.cv[{:d}]'.format(x))
         target_loc = '{}_ik_{:d}_loc'.format(self.name, x)
         loc_grp = create_loc(source_node, target_loc)
         pm.connectAttr(('{}Shape.worldPosition[0]'.format(target_loc)),
                        ('{}Shape.controlPoints[{}]'.format(ik_crv, x)))
         if x < 2:
             loc_grp.setParent(start_ctrl_name)
         else:
             loc_grp.setParent(end_ctrl_name)
Example #17
0
def makeStretchySpline(controller, ik, stretchDefault=1):
    start, chain, jointAxis, switcher = _makeStretchyPrep(
        controller, ik, stretchDefault)

    crv = ik.inCurve.listConnections()[0]
    length = arclen(crv, ch=1).arcLength
    lengthMax = arclen(crv, ch=1).arcLength.get()
    # Spline squashes and stretches
    multiplier = core.math.divide(length, lengthMax)

    jointLenMultiplier = switcher.output

    multiplier >> switcher.input[1]

    for i, j in enumerate(chain[1:], 1):
        #util.recordFloat(j, 'restLength', j.attr('t' + jointAxis).get() )
        saveRestLength(j, jointAxis)
        core.math.multiply(jointLenMultiplier,
                           j.restLength) >> j.attr('t' + jointAxis)

    return controller.attr('stretch'), jointLenMultiplier
Example #18
0
def curveInfo():
    sel = pm.ls(sl = True)[0]
    curve = pm.arclen(sel, ch = True)
    print pm.rename(curve, (sel.name() + "_info"))
    print curve

    pm.addAttr( sel, longName = "part", attributeType = 'double' )
    
    pm.setAttr( (sel + ".part") , keyable = True ) 
    str =(sel + ".part = " + curve + ".arcLength/8 ;")
    print str
    pm.expression(s = str, o = sel, ae = True, uc = "all" , n = (sel + "_part"))
Example #19
0
    def bdBuildMotionPathRbn(self):
        self.mpCrv = pm.ls(sl=1)[0]
        if self.mpType == 'closed':
            startU = self.bdFindStart()
        self.mpLength = pm.arclen(self.mpCrv)
        print self.mpLength

        # oriCrv = self.bdGetOriCrv(self.mpCrv)
        # bdGetUPos(oriCrv)
        allCtrlGrp = pm.group(name=self.mpCrv.name().replace('crv', 'loc_grp'),
                              empty=1)
        allCtrlGrp.setScalePivot(self.mpCrv.boundingBox().center())
        allCtrlGrp.setRotatePivot(self.mpCrv.boundingBox().center())
        for i in range(0, self.numLocs, 1):
            ctrl = pm.circle(
                n=self.mpCrv.name().replace('crv', 'ctrl_' + str(i)))[0]
            ctrl.ry.set(90)
            ctrl.setScale([0.2, 0.2, 0.2])
            ctrl.overrideEnabled.set(1)
            ctrl.overrideColor.set(18)
            pm.makeIdentity(ctrl, a=1)
            ctrlGrp = pm.group(name=ctrl.name() + '_grp')
            if self.mpType == 'closed':
                self.bdFindStart()
            if self.mpType == 'closed':
                uPos = startU + i / (self.numLocs * 1.0)
            else:
                uPos = startU + i / (self.numLocs - 1.0)
            if uPos > 1:
                uPos = uPos - 1
            print uPos
            mp = pm.pathAnimation(ctrlGrp,
                                  c=self.mpCrv.name(),
                                  su=uPos,
                                  follow=1,
                                  followAxis='x',
                                  upAxis='y',
                                  worldUpType="vector")
            uAnimCrv = pm.listConnections('%s.uValue' % mp)
            pm.delete(uAnimCrv)

            pm.select(cl=1)
            jnt = pm.joint(n=ctrl.name().replace('ctrl', 'JNT'))
            pm.select(cl=1)
            pm.parent(jnt, ctrl)
            for axis in ['X', 'Y', 'Z']:
                jnt.attr('translate' + axis).set(0)
            pm.parent(ctrlGrp, allCtrlGrp)
        def bdGetUPos(self,crv):
                crv = pm.ls(crv)[0]
                length = pm.arclen(crv)
                print length
                cvs = crv.getCVs()
                numCvs = crv.numCVs()
                uPos = []
                l=0
                for i in range(numCvs-1):
                        p1 = crv.getCV(i)
                        p2 = crv.getCV(i+1)
                        p3 = p2.distanceTo(p1)
                        l = l + p3
                        print l

                print uPos
                return uPos
Example #21
0
    def bdGetUPos(self, crv):
        crv = pm.ls(crv)[0]
        length = pm.arclen(crv)
        print length
        cvs = crv.getCVs()
        numCvs = crv.numCVs()
        uPos = []
        l = 0
        for i in range(numCvs - 1):
            p1 = crv.getCV(i)
            p2 = crv.getCV(i + 1)
            p3 = p2.distanceTo(p1)
            l = l + p3
            print l

        print uPos
        return uPos
        def bdBuildMotionPathRbn(self):
                self.mpCrv = pm.ls(sl=1)[0]
                if self.mpType == 'closed':
                        startU = self.bdFindStart()
                self.mpLength = pm.arclen(self.mpCrv)
                print self.mpLength

                #oriCrv = self.bdGetOriCrv(self.mpCrv)
                #bdGetUPos(oriCrv)
                allCtrlGrp = pm.group(name = self.mpCrv.name().replace('crv','loc_grp'),empty=1)
                allCtrlGrp.setScalePivot(self.mpCrv.boundingBox().center())
                allCtrlGrp.setRotatePivot(self.mpCrv.boundingBox().center())                
                for i in range(0,self.numLocs,1):
                        ctrl = pm.circle(n=self.mpCrv.name().replace('crv','ctrl_' + str(i)))[0]
                        ctrl.ry.set(90)
                        ctrl.setScale([0.2,0.2,0.2])
                        ctrl.overrideEnabled.set(1)
                        ctrl.overrideColor.set(18)
                        pm.makeIdentity(ctrl,a=1)
                        ctrlGrp = pm.group(name = ctrl.name() + '_grp')
                        if self.mpType == 'closed':
                                self.bdFindStart()
                        if self.mpType == 'closed':
                                uPos = startU + i/(self.numLocs*1.0)
                        else:
                                uPos = startU + i/(self.numLocs-1.0)
                        if uPos > 1:
                                uPos = uPos - 1
                        print uPos
                        mp = pm.pathAnimation(ctrlGrp,c = self.mpCrv.name(),su = uPos,follow = 1,followAxis = 'x', upAxis='y',worldUpType="vector")
                        uAnimCrv = pm.listConnections('%s.uValue'%mp)
                        pm.delete(uAnimCrv)

                        pm.select(cl=1)
                        jnt = pm.joint(n=ctrl.name().replace('ctrl','JNT'))
                        pm.select(cl=1)
                        pm.parent(jnt,ctrl)
                        for axis in ['X','Y','Z']:
                                jnt.attr('translate'+axis).set(0)
                        pm.parent(ctrlGrp,allCtrlGrp)
Example #23
0
    def addStretch(self):
        super(IkSpine, self).addStretch()
        """
        arcMainNode = mc.rename(mc.arclen(IKCrvLenMain, ch=1), self.name + "_" + self.sfx + "_arcLenMain")
        mc.connectAttr(arcMainNode + ".arcLength", stMD + ".input2X")
        """
        arcLen = pm.arclen(self.mainCurve.pynode, constructionHistory=True)
        arcLenMeta = core.MetaRig(arcLen)
        arcLenMeta.part = self.part
        self.transferPropertiesToChild(arcLenMeta, "ArcLen")
        arcLenMeta.resetName()
        self.stretchSystem.setInitialValue(arcLenMeta.pynode.arcLength.get())
        self.stretchSystem.connectTrigger(arcLenMeta.pynode.arcLength)

        # Connect Stretch Joint
        self.connectStretchJoints()

        self.mainCtrls[0].addDivAttr("stretch", "strDiv")
        self.mainCtrls[0].addFloatAttr("Amount", sn="amount")
        amountAttr = self.mainCtrls[0].pynode.amount
        self.stretchSystem.connectAmount(amountAttr)
        amountAttr.set(1)
Example #24
0
    def addStretch(self):
        super(IkSpine, self).addStretch()
        """
        arcMainNode = mc.rename(mc.arclen(IKCrvLenMain, ch=1), self.name + "_" + self.sfx + "_arcLenMain")
        mc.connectAttr(arcMainNode + ".arcLength", stMD + ".input2X")
        """
        arcLen = pm.arclen(self.mainCurve.pynode, constructionHistory=True)
        arcLenMeta = core.MetaRig(arcLen)
        arcLenMeta.part = self.part
        self.transferPropertiesToChild(arcLenMeta, "ArcLen")
        arcLenMeta.resetName()
        self.stretchSystem.setInitialValue(arcLenMeta.pynode.arcLength.get())
        self.stretchSystem.connectTrigger(arcLenMeta.pynode.arcLength)

        # Connect Stretch Joint
        self.connectStretchJoints()

        self.mainCtrls[0].addDivAttr("stretch", "strDiv")
        self.mainCtrls[0].addFloatAttr("Amount", sn="amount")
        amountAttr = self.mainCtrls[0].pynode.amount
        self.stretchSystem.connectAmount(amountAttr)
        amountAttr.set(1)
Example #25
0
def rig_ikChainSpline(name, rootJnt, ctrlSize=1.0, **kwds):
    numIkControls = defaultReturn(5, 'numIkControls', param=kwds)
    numFkControls = defaultReturn(5, 'numFkControls', param=kwds)
    dWorldUpAxis = defaultReturn(6, 'dWorldUpAxis', param=kwds)
    parentRoot = defaultReturn('spineJA_JNT', 'parent', param=kwds)
    lockBase = defaultReturn(1, 'lockBase', param=kwds)
    module = rig_module(name)
    ctrlSizeHalf = [ctrlSize / 2.0, ctrlSize / 2.0, ctrlSize / 2.0]
    ctrlSizeQuarter = [ctrlSize / 4.0, ctrlSize / 4.0, ctrlSize / 4.0]
    ctrlSize = [ctrlSize, ctrlSize, ctrlSize]

    chainList = rig_chain(rootJnt).chain

    numJoints = len(chainList)
    '''
    ctrlPos = []
    for i in range(0, numJoints):
        if i % numFkControls == 0:
            ctrlPos.append(chainList[i])
    '''
    endJnt = defaultReturn(rootJnt.replace('JA_JNT', 'JEnd_JNT'),
                           'endJnt',
                           param=kwds)

    ctrlPos = mm.eval('rig_chainBetweenTwoPoints("' + name + 'Pos", "' +
                      rootJnt + '", "' + endJnt + '",' + str(numIkControls) +
                      ');')

    #for jnt in ctrlPos:
    pm.parent(ctrlPos, w=True)

    for jnt in ctrlPos:
        pm.delete(pm.orientConstraint(rootJnt, jnt))

    # make ik driver controls/joints
    fkControls = []
    ikControls = []
    driverJntList = []
    fkScale = 1.5
    for i in range(0, len(ctrlPos)):
        driverJnt = rig_transform(0,
                                  name=name + 'DriverJ' + ABC[i],
                                  type='joint',
                                  target=ctrlPos[i],
                                  parent=module.parts,
                                  rotateOrder=2).object
        driverJntList.append(driverJnt)

        driverCtrl = rig_control(name=name + 'Driver' + ABC[i],
                                 shape='box',
                                 modify=1,
                                 scale=ctrlSizeHalf,
                                 colour='green',
                                 parentOffset=module.controlsSec,
                                 rotateOrder=2)
        ikControls.append(driverCtrl)
        pm.delete(pm.parentConstraint(driverJnt, driverCtrl.offset))
        pm.parentConstraint(driverCtrl.con, driverJnt, mo=True)

        lockTranslate = []
        ctrlShape = 'circle'
        if i == 0:
            lockTranslate = ['tx', 'ty', 'tz']
            ctrlShape = 'pyramid'
        else:
            lockTranslate = []
        fkCtrl = rig_control(name=name + 'FK' + ABC[i],
                             shape=ctrlShape,
                             modify=2,
                             targetOffset=ctrlPos[i],
                             parentOffset=module.controls,
                             lockHideAttrs=lockTranslate,
                             scale=((ctrlSize[0]) * fkScale,
                                    (ctrlSize[1]) * fkScale,
                                    (ctrlSize[2]) * fkScale))

        if i == 0:
            if pm.objExists(parentRoot):
                pm.parentConstraint(parentRoot, fkCtrl.offset, mo=True)

            if pm.objExists(parentRoot) and pm.objExists('worldSpace_GRP'):
                constrainObject(fkCtrl.modify[0],
                                [fkCtrl.offset, 'worldSpace_GRP'],
                                fkCtrl.ctrl, ['parent', 'world'],
                                type='orientConstraint')

        pm.parentConstraint(fkCtrl.con, driverCtrl.offset, mo=True)

        if i > 0:
            parentOffset = fkControls[i - 1].con
            pm.parent(fkCtrl.offset, parentOffset)

        fkControls.append(fkCtrl)

        fkScale = fkScale - 0.1

    pm.delete(ctrlPos)

    # shape controls
    rootCtrl = fkControls[0]
    pm.addAttr(rootCtrl.ctrl,
               ln='SHAPE',
               at='enum',
               enumName='___________',
               k=True)
    rootCtrl.ctrl.SHAPE.setLocked(True)
    pm.addAttr(rootCtrl.ctrl,
               longName='curl',
               at='float',
               k=True,
               min=-10,
               max=10,
               dv=0)
    pm.addAttr(rootCtrl.ctrl,
               longName='curlSide',
               at='float',
               k=True,
               min=-10,
               max=10,
               dv=0)
    for i in range(1, numIkControls):
        rig_animDrivenKey(rootCtrl.ctrl.curl, (-10, 0, 10),
                          fkControls[i].modify[0] + '.rotateX', (-90, 0, 90))
        rig_animDrivenKey(rootCtrl.ctrl.curlSide, (-10, 0, 10),
                          fkControls[i].modify[0] + '.rotateZ', (-90, 0, 90))

    ik = rig_ik(name,
                rootJnt,
                chainList[-1],
                'ikSplineSolver',
                numSpans=numIkControls)
    pm.parent(ik.handle, ik.curve, module.parts)

    lowerAim = rig_transform(0,
                             name=name + 'LowerAim',
                             type='locator',
                             parent=module.parts,
                             target=ikControls[1].con).object
    upperAim = rig_transform(0,
                             name=name + 'UpperAim',
                             type='locator',
                             parent=module.parts,
                             target=ikControls[-2].con).object

    pm.rotate(lowerAim, 0, 0, -90, r=True, os=True)
    pm.rotate(upperAim, 0, 0, -90, r=True, os=True)

    pm.parentConstraint(ikControls[1].con, lowerAim, mo=True)
    pm.parentConstraint(ikControls[-2].con, upperAim, mo=True)

    aimTop = mm.eval('rig_makePiston("' + lowerAim + '", "' + upperAim +
                     '", "' + name + 'Aim");')

    pm.move(upperAim + 'Up', 0, 30 * ctrlSize[0], 0, r=True, os=True)
    pm.move(lowerAim + 'Up', 0, 20 * ctrlSize[0], 0, r=True, os=True)

    # advanced twist
    pm.setAttr(ik.handle + '.dTwistControlEnable', 1)
    pm.setAttr(ik.handle + '.dWorldUpType', 2)  # object up start and end
    pm.setAttr(ik.handle + '.dForwardAxis', 2)  # positive y
    pm.setAttr(ik.handle + '.dWorldUpAxis', dWorldUpAxis)  # positive x

    pm.connectAttr(upperAim + 'Up.worldMatrix[0]',
                   ik.handle.dWorldUpMatrixEnd,
                   f=True)
    pm.connectAttr(lowerAim + 'Up.worldMatrix[0]',
                   ik.handle.dWorldUpMatrix,
                   f=True)

    pm.parent(aimTop, module.parts)

    pm.select(ik.curve)
    curveShape = pm.pickWalk(direction='down')
    curveInfoNode = pm.arclen(curveShape[0], ch=True)
    curveInfo = pm.rename(curveInfoNode, name + '_splineIk_curveInfo')
    globalCurve = pm.duplicate(ik.curve)
    globalCurve = pm.rename(globalCurve, name + 'global_splineIk_curve')
    pm.select(globalCurve)
    globalCurveShape = pm.pickWalk(direction='down')
    globalCurveInfoNode = pm.arclen(globalCurveShape[0], ch=True)
    globalCurveInfo = pm.rename(globalCurveInfoNode,
                                name + 'global_splineIk_curveInfo')
    pm.parent(globalCurve, module.parts)
    pm.setAttr(globalCurve + '.inheritsTransform', 1)

    distanceToStretch_PM = plusMinusNode(name + '_distanceToStretch',
                                         'subtract', curveInfo, 'arcLength',
                                         globalCurveInfo, 'arcLength')

    correctAdd_Minus_MD = multiplyDivideNode(
        name + '_correctAdd_Minus',
        'multiply',
        input1=[-1, 0, 0],
        input2=[distanceToStretch_PM + '.output1D', 0, 0],
        output=[])

    toggleStretch_ctrl_MD = multiplyDivideNode(
        name + '_toggleStretch_ctrl',
        'multiply',
        input1=[0, 0, 0],
        input2=[correctAdd_Minus_MD + '.outputX', 0, 0],
        output=[])

    distanceStretchCurve_PM = plusMinusNode(name + '_distanceStretchCurve',
                                            'sum', curveInfo, 'arcLength',
                                            toggleStretch_ctrl_MD, 'outputX')

    globalCurveStretchyFix_MD = multiplyDivideNode(
        name + '_globalCurveStretchyFix',
        'divide',
        input1=[distanceStretchCurve_PM + '.output1D', 0, 0],
        input2=[globalCurveInfo + '.arcLength', 1, 1],
        output=[])

    pm.addAttr(fkControls[0].ctrl,
               longName='stretch',
               shortName='ts',
               attributeType="double",
               min=0,
               max=1,
               defaultValue=0,
               keyable=True)

    connectReverse(input=(fkControls[0].ctrl + '.stretch', 0, 0),
                   output=(toggleStretch_ctrl_MD + '.input1X', 0, 0))

    for i in range(0, len(chainList) - 1):
        pm.connectAttr(globalCurveStretchyFix_MD + '.outputX',
                       chainList[i] + '.scaleY',
                       f=True)

    pm.skinCluster(driverJntList, ik.curve, tsb=True)

    return module
Example #26
0
def rope(DEF_nb=10, ropeName="rope",  keepRatio=False, lvlType="transform", oSel=None):
    """
    Create rope rig based in 2 parallel curves.

    Args:
        DEF_nb (int): Number of deformer joints.
        ropeName (str): Name for the rope rig.
        keepRatio (bool): If True, the deformers will keep the length position when the curve is stretched. 
    """
    if oSel and len(oSel) == 2 and isinstance(oSel, list):
        oCrv = oSel[0]
        if isinstance(oCrv, str):
            oCrv = pm.PyNode(oCrv)
        oCrvUpV = oSel[1]
        if isinstance(oCrvUpV, str):
            oCrvUpV = pm.PyNode(oCrvUpV)
    else:
        if len( pm.selected()) !=2:
            print "You need to select 2 nurbsCurve"
            return
        oCrv = pm.selected()[0]
        oCrvUpV = pm.selected()[1]
    if oCrv.getShape().type() != "nurbsCurve" or  oCrvUpV.getShape().type() != "nurbsCurve":
        print "One of the selected objects is not of type: 'nurbsCurve'"
        print oCrv.getShape().type()
        print  oCrvUpV.getShape().type()
        return
    if keepRatio:
        arclen_node = pm.arclen(oCrv, ch=True)
        alAttr = pm.getAttr(arclen_node + ".arcLength")
        muldiv_node =  pm.createNode("multiplyDivide")
        pm.connectAttr(arclen_node+".arcLength", muldiv_node+".input1X")
        pm.setAttr(muldiv_node+".input2X", alAttr)
        pm.setAttr(muldiv_node+".operation", 2)
        pm.addAttr(oCrv, ln="length_ratio", k=True, w=True)
        pm.connectAttr(muldiv_node+".outputX", oCrv+".length_ratio")

    root =   pm.PyNode(pm.createNode(lvlType, n= ropeName + "_root", ss=True))
    step = 1.000/(DEF_nb -1)
    i = 0.000
    shds = []
    for x in range(DEF_nb):

        oTransUpV = pm.PyNode(pm.createNode(lvlType, n= ropeName + str(x).zfill(3) + "_upv", p=root, ss=True))
        oTrans = pm.PyNode(pm.createNode(lvlType, n= ropeName + str(x).zfill(3) + "_lvl", p=root, ss=True))

        cnsUpv = aop.pathCns(oTransUpV, oCrvUpV, cnsType=False, u=i, tangent=False)
        cns = aop.pathCns(oTrans, oCrv, cnsType=False, u=i, tangent=False)

        if keepRatio:
            muldiv_node2 =  pm.createNode("multiplyDivide")
            condition_node =  pm.createNode("condition")
            pm.setAttr(muldiv_node2+".operation", 2)
            pm.setAttr(muldiv_node2+".input1X", i)
            pm.connectAttr(oCrv+".length_ratio", muldiv_node2+".input2X")
            pm.connectAttr(muldiv_node2+".outputX", condition_node+".colorIfFalseR")
            pm.connectAttr(muldiv_node2+".outputX", condition_node+".secondTerm")
            pm.connectAttr(muldiv_node2+".input1X", condition_node+".colorIfTrueR")
            pm.connectAttr(muldiv_node2+".input1X", condition_node+".firstTerm")
            pm.setAttr(condition_node+".operation", 4)


            pm.connectAttr(condition_node+".outColorR", cnsUpv+".uValue")
            pm.connectAttr(condition_node+".outColorR", cns+".uValue")

        cns.setAttr("worldUpType", 1)
        cns.setAttr("frontAxis", 0)
        cns.setAttr("upAxis", 1)

        pm.connectAttr(oTransUpV.attr("worldMatrix[0]"),cns.attr("worldUpMatrix"))
        shd = rt.addJnt(oTrans)
        shds.append(shd[0])
        i += step
    return shds
Example #27
0
    def _build(self, *args):
        """
        Builds the joints on the curve.
        """
        # naming convention
        asset = self.asset
        side = self.side
        part = self.part
        joints = self.joints
        suffix = self.suffix

        if self.gui:
            asset = self.asset_name.text()
            side = self.side.currentText()
            part = self.part_name.text()
            joints = self.joints_box.value()
            suffix = self.suffix.currentText()
        try:
            curve = pm.ls(sl=True)[0]
            curve_name = NameUtils.get_unique_name(asset, side, part, "crv")
            self.curve = pm.rename(curve, curve_name)
        except IndexError:
            pm.warning("Please select a curve")
            return

        length_of_curve = pm.arclen(self.curve)
        equal_spacing = length_of_curve / float(joints)

        # clear the selection
        pm.select(cl=True)

        # # create the joints
        curve_joints = list()
        for x in xrange(int(joints) + 1):
            name = NameUtils.get_unique_name(asset, side, part, suffix)
            joint = pm.joint(n=name)
            curve_joints.append(joint)

            joint_position = (x * equal_spacing)
            pm.move(0, joint_position, 0)

        # rename last joint
        last_joint = curve_joints[-1]
        pm.rename(last_joint, last_joint + "End")

        root_joint = pm.selected()[0].root()
        end_joint = pm.ls(sl=True)[0]
        solver = 'ikSplineSolver'

        # attach joints to curve
        ik_name = NameUtils.get_unique_name(asset, side, part, "ikHandle")
        self.ikHandle = pm.ikHandle(sj=root_joint,
                                    ee=end_joint,
                                    sol=solver,
                                    c=self.curve,
                                    pcv=True,
                                    roc=True,
                                    ccv=False,
                                    n=ik_name)
        joint_chain = pm.ls(root_joint, dag=True)

        # delete history
        pm.makeIdentity(root_joint, apply=True)

        # cleanup
        self._cleanup()
Example #28
0
def createStretchSpline(curveObj, volume, worldScale, worldScaleObj, worldScaleAttr, disable=0, disableObj='', disableAttr=''):
    """
    Script:     js_createStretchSpline.mel
    Author:     Jason Schleifer


    Descr:      Given the selected curve, it will tell the joints to stretch.  It's easiest to use with the
                js_createStretchSplineUI.mel script

    Inputs:     $curveObj           =>  The nurbs curve that will be stretched
                $maintainVolume     =>  Whether or not to maintain volume on the joints
                                        if this is on, then it will be made with
                                        an expression, if not then we'll use nodes.

                $worldScale         =>  Whether or not to take worldScale into account

                $worldScaleObj      =>  The object that will be used for world scale

                $worldScaleAttr     =>  The attribute to be used for world scale

                $disable            =>  Option to control and disable stretch with control

                $disableObj      =>  The object that will be used for disable

                $disableAttr     =>  The attribute to be used for disable 

    Req:        getStretchAxis
                createCurveControl
    """

    node = pm.arclen(curveObj, n= '%s_curveInfo'%curveObj, ch=1)
    # based on the given curve, tell the joints to stretch
    # create a curveInfo node
    # get the ikhandle
    shape = pm.listRelatives(curveObj, s=1, f=1)
    con = pm.listConnections((shape[0] + ".worldSpace[0]"),  type='ikHandle')
    ikHandle = con[0]
    # find out what joints are in the list
    joints = pm.ikHandle(ikHandle, q=1, jl=1)
    # we need to figure out which direction the curve should be scaling.
    # do to that, we'll look at the translate values of the second joint.  Whichever translate has the
    # highest value, that'll be the first one and the other two axis will be the shrinking one
    stretchAxis = getStretchAxis(joints[1])
    # create a normalizedScale attr on the curveInfo node
    pm.addAttr(node, ln="normalizedScale", at="double")
    length = pm.getAttr(str(node) + ".arcLength")

    # create blend node for on/off
    blendStretch = pm.shadingNode('blendColors', asUtility=1, name='%s_stretchBlend'%curveObj)
    pm.setAttr(str(blendStretch) + '.color1R', length)
    pm.connectAttr((str(node) + ".arcLength"), str(blendStretch) + '.color2R')

    #  create a NormalizedScale node to connect to everything.
    multDivide = pm.createNode('multiplyDivide')
    multDivide = pm.rename(multDivide,
                           (curveObj + "_normalizedScale"))
    # set the multiplyDivide node to division
    pm.setAttr((str(multDivide) + ".operation"), 2)
    pm.connectAttr("%s.outputR"%blendStretch,  "%s.input1X"%multDivide)
    pm.setAttr((str(multDivide) + ".input2X"),
               length)
    pm.connectAttr((str(multDivide) + ".outputX"), (str(node) + ".normalizedScale"))
    
    if disable:
        pm.connectAttr('%s.%s'%(disableObj, disableAttr), '%s.blender'%blendStretch )
    else:
        pm.setAttr('%s.blender'%blendStretch, 1 )

    # if worldscale is off, and volume deformation is off, we can just connect directly to the joints
    if (worldScale == 0) and (volume == 0):
        for joint in joints:
            print "connecting to " + str(joint) + "." + stretchAxis[0] + "\n"
            pm.connectAttr((str(node) + ".normalizedScale"), (str(joint) + "." + stretchAxis[0]),
                           f=1)



    elif (worldScale == 1) and (volume == 0):
        md2 = pm.createNode('multiplyDivide', n=(curveObj + "_worldScale"))
        # if $worldScale is on, but volume is off we can just add another multiply divide node
        # and connect to that
        # create a multiplyDivide node
        pm.setAttr((str(md2) + ".operation"),
                   2)
        pm.connectAttr((str(node) + ".normalizedScale"), (str(md2) + ".input1X"))
        pm.connectAttr((worldScaleObj + "." + worldScaleAttr), (str(md2) + ".input2X"))
        for joint in joints:
            pm.connectAttr((str(md2) + ".outputX"), (str(joint) + "." + stretchAxis[0]),
                           f=1)



    else:
        pm.select(joints)
        # also create an anim curve which we can use to connnect to the joints to help
        # determine the scaling power in X and Z.  This will be attached to the curve itself
        utils.createCurveControl(curveObj, "scalePower", "pow")
        # start creating an expression
        expr = ""
        # for each joint, connect the scaleX to the normalizedScale
        # if worldScale and disable:
        #     expr += ("$scale = " + str(node) + ".normalizedScale *" + worldScaleObj + "." + worldScaleAttr + " * " + disableObj + "." + disableAttr + ";\n")
        if worldScale:
            expr += ("$scale = " + str(node) + ".normalizedScale *" + worldScaleObj + "." + worldScaleAttr + ";\n")
        # elif disable:
        #     expr += ("$scale = " + str(node) + ".normalizedScale *" + disableObj + "." + disableAttr + ";\n")
        else:
            expr += ("$scale = " + str(node) + ".normalizedScale;\n")

        expr += ("$sqrt = 1/sqrt($scale);\n")
        size = len(joints)
        for x in range(0, size):
            item = joints[x]
            # set a powPosition based on the number of joints which will be scaling, from 0 to 1
            expr = (expr + str(item) + "." + stretchAxis[0] + " = $scale;\n")
            expr = (expr + str(item) + "." + stretchAxis[1] + " = pow($sqrt," + str(item) + ".pow);\n")
            expr = (expr + str(item) + "." + stretchAxis[2] + " = pow($sqrt," + str(item) + ".pow);\n")

        pm.expression(s=expr, n=(curveObj + "_expr"))

    pm.select(curveObj)
    return joints
Example #29
0
	def _cerateCurveIkHandle(self , frontBackList = None):
		'''
		@frontBackList : list , This is the frontBackList of is List
		'''
		if frontBackList is None :
			OpenMaya.MGlobal_displayError('@frontBackList : This is the jointList is None : frontBackList = %s'%(frontBackList))
			return
		
		frontBackClusterList = []
		for jointList in frontBackList:
			swapName = jointList[0].name().split('_')[-1]
			name = jointList[0].name().replace('_'+swapName , '_cruve')
			
			jointList1 = [jointList[0] , jointList[-1]]
			
			pointList = [a.getTranslation(space = 'world') for a in jointList1]
			knotList = range(len(jointList1))
			
			curve = pm.curve(n = name , d = 1 , p = pointList , k = knotList )
			#pm.rebuildCurve(curve ,d = 3)
			
			
			ikHandleName = jointList[0].name().replace('_'+swapName , '_ikHandle')
			handle , effector = pm.ikHandle( n = ikHandleName , sj = jointList[0] , ee = jointList[-1] , c = curve , sol="ikSplineSolver" , ccv = 0, pcv = 0 , ns = 3)
			
			jointListGroup = self._objectGroup(jointList[0])
			handleGroup = self._objectGroup(handle)
			curveGroup = self._objectGroup(curve)
			
			curve.getParent().inheritsTransform.set(0)
			
			curveGroup.setParent(handleGroup)
			handleGroup.setParent(jointListGroup)
			jointListGroup.setParent(self.featherIkCurGroup)
			
			jointList[0].getParent().v.set(0)
			handle.getParent().v.set(0)
			
			curveInfo = pm.arclen(curve , ch = 1)
			curveInfoName = curveInfo.rename(curve.name().replace('_cruve' , '_curveInfo'))
			
			MDName1 = pm.shadingNode("multiplyDivide",asUtility=True,n=jointList[0].name().replace('_'+swapName , '_MD1'))
			MDName1.operation.set(1)
			
			MDName2 = pm.shadingNode("multiplyDivide",asUtility=True,n=jointList[0].name().replace('_'+swapName , '_MD2'))
			MDName2.operation.set(2)
			
			
			self.globalScaleMD.input1X.set(1)
			
			MDName1.input1X.set(curveInfoName.arcLength.get())
			
			curveInfoName.arcLength.connect(MDName2.input1X)
			MDName1.outputX.connect(MDName2.input2X)
			self.globalScaleMD.outputX.connect(MDName1.input2X)
			
			
			for x in jointList:
				MDName2.outputX.connect(x.scaleX)
			
			ClusterList = self._createCurveCluster(curve)
			frontBackClusterList.append(ClusterList)
			
		
		OpenMaya.MGlobal_clearSelectionList()
		
		return frontBackClusterList
    def generateFollowPlane(self, *args):
        startTime = pm.playbackOptions(q=1, min=1)
        endTime = pm.playbackOptions(q=1, max=1)

        sel_list = pm.ls(sl=1, ni=1, type="transform")
        if not sel_list:
            pm.confirmDialog(message='请选择物体', button=['确定'])
            return

        for sel in sel_list:
            # snapshot = pm.snapshot(sel,st=startTime,et=endTime)[1]
            snapshot = pm.createNode("snapshot")
            sel.selectHandle.connect(snapshot.localPosition)
            sel.worldMatrix[0].connect(snapshot.inputMatrix)
            snapshot.startTime.set(startTime)
            snapshot.endTime.set(endTime)
            snapshot.increment.set(1)
            anim_curve = pm.curve(n=sel + "_follow_curve",
                                  d=3,
                                  p=snapshot.pts.get())
            pm.delete(snapshot)

            curve_length = pm.arclen(anim_curve, ch=0)
            plane, plane_node = pm.polyPlane(n=sel + "_follow_plane",
                                             sx=20,
                                             sy=3,
                                             w=curve_length,
                                             h=20)
            plane_grp = pm.group(plane, n=plane + "_grp")
            # NOTE 创建运动路径跟随
            motion_path = pm.pathAnimation(
                plane_grp,
                anim_curve,
                fractionMode=1,
                follow=1,
                followAxis="x",
                upAxis="y",
                worldUpType="vector",
                worldUpVector=(0, 1, 0),
                inverseUp=0,
                inverseFront=0,
                bank=0,
                startTimeU=startTime,
                endTimeU=endTime,
            )
            motion_path = pm.PyNode(motion_path)
            flow_node, ffd_node, lattice_node, ffd_base = pm.flow(plane_grp,
                                                                  dv=(100, 2,
                                                                      2))

            # NOTE 设置外部影响
            ffd_node.outsideLattice.set(1)
            ffd_node.local.set(1)
            plane_node.width.set(50)

            lattice_node.v.set(0)
            ffd_base.v.set(0)

            # NOTE 设置 Parametric Length 匹配位置
            motion_path.fractionMode.set(0)
            # NOTE 设置为 normal 朝向确保不会翻转
            motion_path.worldUpType.set(4)

            animCurve = motion_path.listConnections(type="animCurve")[0]
            # NOTE 关键帧设置为线性
            animCurve.setTangentTypes(range(animCurve.numKeys()),
                                      inTangentType="linear",
                                      outTangentType="linear")

            # NOTE 打组
            pm.group(lattice_node,
                     ffd_base,
                     plane_grp,
                     anim_curve,
                     n=sel + "_follow_grp")
            pm.select(plane)
Example #31
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
Example #32
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.

        """

        # Curves -------------------------------------------
        op = applyop.gear_curveslide2_op(
            self.slv_crv, self.mst_crv, 0, 1.5, .5, .5)

        pm.connectAttr(self.position_att, op + ".position")
        pm.connectAttr(self.lenght_att, op + ".maxstretch")

        op = applyop.gear_curveslide2_op(
            self.slv_upv_crv, self.upv_crv, 0, 1.5, .5, .5)

        pm.connectAttr(self.position_att, op + ".position")
        pm.connectAttr(self.lenght_att, op + ".maxstretch")

        for tang in self.tangentsCtl:
            for shp in tang.getShapes():
                pm.connectAttr(self.tangentsVis_att, shp.attr("visibility"))

        for twnpo, fkctl in zip(self.tweak_npo, self.fk_ctl):
            intMatrix = applyop.gear_intmatrix_op(
                fkctl.attr("worldMatrix"),
                fkctl.getParent().attr("worldMatrix"),
                .5)

            applyop.gear_mulmatrix_op(intMatrix.attr("output"),
                                      twnpo.attr("parentInverseMatrix[0]"),
                                      twnpo)

        dm_node_scl = node.createDecomposeMatrixNode(self.root.worldMatrix)
        if self.settings["keepLength"]:
            arclen_node = pm.arclen(self.slv_crv, ch=True)
            alAttr = pm.getAttr(arclen_node + ".arcLength")

            pm.addAttr(self.slv_crv, ln="length_ratio", k=True, w=True)
            node.createDivNode(arclen_node.arcLength,
                               alAttr,
                               self.slv_crv.length_ratio)

            div_node_scl = node.createDivNode(self.slv_crv.length_ratio,
                                              dm_node_scl.outputScaleX)

        step = 1.000 / (self.def_number - 1)
        u = 0.000
        for i in range(self.def_number):
            mult_node = node.createMulNode(u, self.lenght_att)
            cnsUpv = applyop.pathCns(self.upv_cns[i],
                                     self.slv_upv_crv,
                                     cnsType=False,
                                     u=u,
                                     tangent=False)
            pm.connectAttr(mult_node.outputX, cnsUpv.uValue)

            cns = applyop.pathCns(
                self.div_cns[i], self.slv_crv, False, u, True)
            pm.connectAttr(mult_node.outputX, cns.uValue)

            # Connectiong the scale for scaling compensation
            for axis, AX in zip("xyz", "XYZ"):
                pm.connectAttr(dm_node_scl.attr("outputScale{}".format(AX)),
                               self.div_cns[i].attr("s{}".format(axis)))

            if self.settings["keepLength"]:

                div_node2 = node.createDivNode(u, div_node_scl.outputX)

                cond_node = node.createConditionNode(div_node2.input1X,
                                                     div_node2.outputX,
                                                     4,
                                                     div_node2.input1X,
                                                     div_node2.outputX)

                # pm.connectAttr(cond_node + ".outColorR",
                #                cnsUpv + ".uValue")
                # pm.connectAttr(cond_node + ".outColorR",
                #                cns + ".uValue")
                pm.connectAttr(cond_node + ".outColorR",
                               mult_node + ".input1X", f=True)

            # Connect the scaling for self.Extra_tweak_npo
            et_npo = self.Extra_tweak_npo[i]
            pm.connectAttr(self.spin_att, et_npo + ".rz")

            base_node = node.createMulNode(self.baseSize_att, 1.00000 - u, output=None)
            tip_node = node.createMulNode(self.tipSize_att, u, output=None)
            sum_node = node.createPlusMinusAverage1D([base_node.outputX, tip_node.outputX])
            # print et_npo
            pm.connectAttr(sum_node.output1D, et_npo.scaleX, f=True)
            pm.connectAttr(sum_node.output1D, et_npo.scaleY, f=True)
            pm.connectAttr(sum_node.output1D, et_npo.scaleZ, f=True)

            cns.setAttr("worldUpType", 1)
            cns.setAttr("frontAxis", 0)
            cns.setAttr("upAxis", 1)

            pm.connectAttr(self.upv_cns[i].attr("worldMatrix[0]"),
                           cns.attr("worldUpMatrix"))
            u += step

        for et in self.Extra_tweak_ctl:
            for shp in et.getShapes():
                pm.connectAttr(self.tweakVis_att, shp.attr("visibility"))

        if self.settings["keepLength"]:
            # add the safty distance offset
            self.tweakTip_npo.attr("tx").set(self.off_dist)
            # connect vis line ref
            for shp in self.line_ref.getShapes():
                pm.connectAttr(self.ikVis_att, shp.attr("visibility"))

        for ctl in self.tweak_ctl:
            for shp in ctl.getShapes():
                pm.connectAttr(self.ikVis_att, shp.attr("visibility"))
        for ctl in self.fk_ctl:
            for shp in ctl.getShapes():
                pm.connectAttr(self.fkVis_att, shp.attr("visibility"))
Example #33
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.

        """
        # setup out channels. This channels are pass through for stack
        node.createPlusMinusAverage1D(
            [self.mid_wide_att, self.mid_wide_in_att, -1.0], 1,
            self.mid_wide_out_att)
        node.createPlusMinusAverage1D(
            [self.mid_depth_att, self.mid_depth_in_att, -1.0], 1,
            self.mid_depth_out_att)

        node.createPlusMinusAverage1D(
            [self.tip_wide_att, self.tip_wide_in_att, -1.0], 1,
            self.tip_wide_out_att)
        node.createPlusMinusAverage1D(
            [self.tip_depth_att, self.tip_depth_in_att, -1.0], 1,
            self.tip_depth_out_att)

        node.createPlusMinusAverage1D(
            [self.mid_twist_att, self.mid_twist_in_att], 1,
            self.mid_twist_out_att)

        node.createPlusMinusAverage1D(
            [self.tip_twist_att, self.tip_twist_in_att], 1,
            self.tip_twist_out_att)

        if not self.settings["simpleFK"]:
            dm_node_scl = node.createDecomposeMatrixNode(self.root.worldMatrix)
            if self.settings["keepLength"]:
                arclen_node = pm.arclen(self.mst_crv, ch=True)
                alAttr = pm.getAttr(arclen_node + ".arcLength")
                ration_node = node.createMulNode(self.length_ratio_att, alAttr)

                pm.addAttr(self.mst_crv, ln="length_ratio", k=True, w=True)
                node.createDivNode(arclen_node.arcLength, ration_node.outputX,
                                   self.mst_crv.length_ratio)

                div_node_scl = node.createDivNode(self.mst_crv.length_ratio,
                                                  dm_node_scl.outputScaleX)

            step = 1.000 / (self.def_number - 1)
            step_mid = 1.000 / ((self.def_number - 1) / 2.0)
            u = 0.000
            u_mid = 0.000
            pass_mid = False
            for i in range(self.def_number):
                cnsUpv = applyop.pathCns(self.upv_cns[i],
                                         self.upv_crv,
                                         cnsType=False,
                                         u=u,
                                         tangent=False)

                cns = applyop.pathCns(self.div_cns[i], self.mst_crv, False, u,
                                      True)

                # Connecting the scale for scaling compensation
                # for axis, AX in zip("xyz", "XYZ"):
                for axis, AX in zip("x", "X"):
                    pm.connectAttr(
                        dm_node_scl.attr("outputScale{}".format(AX)),
                        self.div_cns[i].attr("s{}".format(axis)))

                if self.settings["keepLength"]:

                    div_node2 = node.createDivNode(u, div_node_scl.outputX)

                    cond_node = node.createConditionNode(
                        div_node2.input1X, div_node2.outputX, 4,
                        div_node2.input1X, div_node2.outputX)

                    pm.connectAttr(cond_node + ".outColorR",
                                   cnsUpv + ".uValue")
                    pm.connectAttr(cond_node + ".outColorR", cns + ".uValue")

                cns.setAttr("worldUpType", 1)
                cns.setAttr("frontAxis", 0)
                cns.setAttr("upAxis", 1)

                pm.connectAttr(self.upv_cns[i].attr("worldMatrix[0]"),
                               cns.attr("worldUpMatrix"))

                # Connect scale Wide and Depth
                # wide and Depth
                mid_mul_node = node.createMulNode(
                    [self.mid_wide_att, self.mid_depth_att],
                    [self.mid_wide_in_att, self.mid_depth_in_att])
                mid_mul_node2 = node.createMulNode(
                    [mid_mul_node.outputX, mid_mul_node.outputY],
                    [u_mid, u_mid])
                mid_mul_node3 = node.createMulNode(
                    [mid_mul_node2.outputX, mid_mul_node2.outputY], [
                        dm_node_scl.attr("outputScaleX"),
                        dm_node_scl.attr("outputScaleY")
                    ])
                tip_mul_node = node.createMulNode(
                    [self.tip_wide_att, self.tip_depth_att],
                    [self.tip_wide_in_att, self.tip_depth_in_att])
                tip_mul_node2 = node.createMulNode(
                    [tip_mul_node.outputX, tip_mul_node.outputY], [u, u])
                node.createPlusMinusAverage1D([
                    mid_mul_node3.outputX, 1.0 - u_mid, tip_mul_node2.outputX,
                    1.0 - u, -1.0
                ], 1, self.div_cns[i].attr("sy"))
                node.createPlusMinusAverage1D([
                    mid_mul_node3.outputY, 1.0 - u_mid, tip_mul_node2.outputY,
                    1.0 - u, -1.0
                ], 1, self.div_cns[i].attr("sz"))

                # Connect Twist "cns.frontTwist"
                twist_mul_node = node.createMulNode(
                    [self.mid_twist_att, self.tip_twist_att], [u_mid, u])
                twist_mul_node2 = node.createMulNode(
                    [self.mid_twist_in_att, self.tip_twist_in_att], [u_mid, u])
                node.createPlusMinusAverage1D([
                    twist_mul_node.outputX,
                    twist_mul_node.outputY,
                    twist_mul_node2.outputX,
                    twist_mul_node2.outputY,
                ], 1, cns.frontTwist)

                # u_mid calc
                if u_mid >= 1.0 or pass_mid:
                    u_mid -= step_mid
                    pass_mid = True
                else:
                    u_mid += step_mid

                if u_mid > 1.0:
                    u_mid = 1.0

                # ensure the tip is never affected byt the mid
                if i == (self.def_number - 1):
                    u_mid = 0.0
                u += step

            if self.settings["keepLength"]:
                # add the safty distance offset
                self.tweakTip_npo.attr("tx").set(self.off_dist)
                # connect vis line ref
                for shp in self.line_ref.getShapes():
                    pm.connectAttr(self.ikVis_att, shp.attr("visibility"))

        # CONNECT STACK
        # master components
        mstr_global = self.settings["masterChainGlobal"]
        mstr_local = self.settings["masterChainLocal"]
        if mstr_global:
            mstr_global = self.rig.components[mstr_global]
        if mstr_local:
            mstr_local = self.rig.components[mstr_local]

        # connect twist and scale
        if mstr_global and mstr_local:
            node.createPlusMinusAverage1D([
                mstr_global.root.mid_twist_out, mstr_local.root.mid_twist_out
            ], 1, self.mid_twist_in_att)
            node.createPlusMinusAverage1D([
                mstr_global.root.tip_twist_out, mstr_local.root.tip_twist_out
            ], 1, self.tip_twist_in_att)
            node.createPlusMinusAverage1D([
                mstr_global.root.mid_wide_out, mstr_local.root.mid_wide_out, -1
            ], 1, self.mid_wide_in_att)
            node.createPlusMinusAverage1D([
                mstr_global.root.tip_wide_out, mstr_local.root.tip_wide_out, -1
            ], 1, self.tip_wide_in_att)
            node.createPlusMinusAverage1D([
                mstr_global.root.mid_depth_out, mstr_local.root.mid_depth_out,
                -1
            ], 1, self.mid_depth_in_att)
            node.createPlusMinusAverage1D([
                mstr_global.root.tip_depth_out, mstr_local.root.tip_depth_out,
                -1
            ], 1, self.tip_depth_in_att)
        elif mstr_local or mstr_global:
            for master_chain in [mstr_local, mstr_global]:
                if master_chain:
                    pm.connectAttr(master_chain.root.mid_twist_out,
                                   self.mid_twist_in_att)
                    pm.connectAttr(master_chain.root.tip_twist_out,
                                   self.tip_twist_in_att)
                    pm.connectAttr(master_chain.root.mid_wide_out,
                                   self.mid_wide_in_att)
                    pm.connectAttr(master_chain.root.tip_wide_out,
                                   self.tip_wide_in_att)
                    pm.connectAttr(master_chain.root.mid_depth_out,
                                   self.mid_depth_in_att)
                    pm.connectAttr(master_chain.root.tip_depth_out,
                                   self.tip_depth_in_att)
        # connect the fk chain ctls
        for e, ctl in enumerate(self.fk_ctl):
            # connect out
            out_loc = self.fk_local_out[e]
            applyop.gear_mulmatrix_op(ctl.attr("worldMatrix"),
                                      out_loc.attr("parentInverseMatrix[0]"),
                                      out_loc)
            out_glob = self.fk_global_out[e]
            out_ref = self.fk_global_ref[e]
            applyop.gear_mulmatrix_op(out_ref.attr("worldMatrix"),
                                      out_glob.attr("parentInverseMatrix[0]"),
                                      out_glob)
            # connect in global
            if mstr_global:
                self.connect_master(mstr_global.fk_global_out,
                                    self.fk_global_in, e,
                                    self.settings["cnxOffset"])

            # connect in local
            if mstr_local:
                self.connect_master(mstr_local.fk_local_out, self.fk_local_in,
                                    e, self.settings["cnxOffset"])

            for shp in ctl.getShapes():
                pm.connectAttr(self.fkVis_att, shp.attr("visibility"))

        for ctl in self.tweak_ctl:
            for shp in ctl.getShapes():
                pm.connectAttr(self.ikVis_att, shp.attr("visibility"))

        if self.settings["extraTweak"]:
            for tweak_ctl in self.extratweak_ctl:
                for shp in tweak_ctl.getShapes():
                    pm.connectAttr(self.tweakVis_att, shp.attr("visibility"))
    def bdBuildRPSolverScale(self, condition):
        print 'RP Solver'

        #self.splineCurve = pm.listConnections(self.ikSpline, type = 'nurbsCurve')[0]
        pm.select(cl=True)
        ikGrp = pm.group(n=self.ikSpline.name() + '_GRP')
        ikParent = self.ikSpline.getParent()
        ikPos = self.ikSpline.getTranslation(space='world')
        ikGrp.setTranslation(ikPos)
        pm.parent(ikGrp, ikParent)
        pm.parent(self.ikSpline, ikGrp)

        sclJnt = pm.duplicate(self.startJoint,
                              parentOnly=True,
                              name=self.startJoint.name().replace(
                                  'JNT', 'SCL'))[0]
        effector = pm.listConnections(self.ikSpline,
                                      source=True,
                                      type='ikEffector')[0]
        endJoint = pm.listConnections(effector, source=True, type='joint')[0]
        startJointChild = pm.listRelatives(self.startJoint,
                                           c=True,
                                           type='joint')[0]
        self.jointChain = []
        self.jointChain.append(self.startJoint)
        self.jointChain.append(startJointChild)
        while startJointChild.name() != endJoint.name():
            startJointChild = pm.listRelatives(startJointChild,
                                               c=True,
                                               type='joint')[0]
            self.jointChain.append(startJointChild)

        jntPos = []
        for jnt in self.jointChain:
            pos = jnt.getTranslation(space='world')
            jntPos.append(pos)

        self.splineCurveScl = pm.curve(p=jntPos,
                                       degree=1,
                                       n=self.startJoint.name().replace(
                                           '01_JNT', 'CRV_SCL'))
        self.splineCurveScl.setPivots(jntPos[0])
        pm.parent(self.splineCurveScl, sclJnt)

        strArclenSCL = pm.arclen(self.splineCurveScl, ch=True)
        arclenSCL = pm.ls(strArclenSCL)[0]
        arclenSCL.rename(self.splineCurveScl.name() + '_length')
        distanceNode = pm.createNode('distanceBetween',
                                     name=self.startJoint.name().replace(
                                         '_01_JNT', 'distance'))

        sclJnt.rotatePivotTranslate.connect(distanceNode.point1)
        ikGrp.rotatePivotTranslate.connect(distanceNode.point2)
        sclJnt.worldMatrix.connect(distanceNode.inMatrix1)
        ikGrp.worldMatrix.connect(distanceNode.inMatrix2)

        mdScaleFactor = pm.createNode('multiplyDivide',
                                      name=self.splineCurveScl.name().replace(
                                          'CRV_SCL', 'CRV_scaleFactor_MD'))
        distanceNode.distance.connect(mdScaleFactor.input1X)
        arclenSCL.arcLength.connect(mdScaleFactor.input2X)
        mdScaleFactor.operation.set(2)

        cndScaleFactor = pm.createNode('condition',
                                       name=self.splineCurveScl.name().replace(
                                           'CRV_SCL', 'CRV_scaleFactor_CND'))
        distanceNode.distance.connect(cndScaleFactor.firstTerm)
        arclenSCL.arcLength.connect(cndScaleFactor.secondTerm)
        mdScaleFactor.outputX.connect(cndScaleFactor.colorIfTrueR)

        cndScaleFactor.operation.set(2)

        for jnt in self.jointChain:
            cndScaleFactor.outColorR.connect(jnt.scaleX)
Example #35
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.

        """
        # Tangent position ---------------------------------
        # common part
        d = vector.getDistance(self.guide.pos["root"], self.guide.pos["neck"])
        dist_node = node.createDistNode(self.root, self.ik_ctl)
        rootWorld_node = node.createDecomposeMatrixNode(
            self.root.attr("worldMatrix"))
        div_node = node.createDivNode(dist_node + ".distance",
                                      rootWorld_node + ".outputScaleX")
        div_node = node.createDivNode(div_node + ".outputX", d)

        # tan0
        mul_node = node.createMulNode(self.tan0_att,
                                      self.tan0_loc.getAttr("ty"))
        res_node = node.createMulNode(mul_node + ".outputX",
                                      div_node + ".outputX")
        pm.connectAttr(res_node + ".outputX", self.tan0_loc + ".ty")

        # tan1
        mul_node = node.createMulNode(self.tan1_att,
                                      self.tan1_loc.getAttr("ty"))
        res_node = node.createMulNode(mul_node + ".outputX",
                                      div_node + ".outputX")
        pm.connectAttr(res_node + ".outputX", self.tan1_loc.attr("ty"))

        # Curves -------------------------------------------
        op = applyop.gear_curveslide2_op(self.slv_crv, self.mst_crv, 0, 1.5,
                                         .5, .5)
        pm.connectAttr(self.maxstretch_att, op + ".maxstretch")
        pm.connectAttr(self.maxsquash_att, op + ".maxsquash")
        pm.connectAttr(self.softness_att, op + ".softness")

        # Volume driver ------------------------------------
        crv_node = node.createCurveInfoNode(self.slv_crv)

        # Division -----------------------------------------
        for i in range(self.settings["division"]):

            # References
            u = i / (self.settings["division"] - 1.0)

            cns = applyop.pathCns(self.div_cns[i], self.slv_crv, False, u,
                                  True)
            cns.setAttr("frontAxis", 1)  # front axis is 'Y'
            cns.setAttr("upAxis", 2)  # front axis is 'Z'

            # Roll
            intMatrix = applyop.gear_intmatrix_op(
                self.intMRef + ".worldMatrix", self.ik_ctl + ".worldMatrix", u)
            dm_node = node.createDecomposeMatrixNode(intMatrix + ".output")
            pm.connectAttr(dm_node + ".outputRotate",
                           self.twister[i].attr("rotate"))

            pm.parentConstraint(self.twister[i],
                                self.ref_twist[i],
                                maintainOffset=True)

            pm.connectAttr(self.ref_twist[i] + ".translate",
                           cns + ".worldUpVector")

            # Squash n Stretch
            op = applyop.gear_squashstretch2_op(self.fk_npo[i], self.root,
                                                pm.arclen(self.slv_crv), "y")

            pm.connectAttr(self.volume_att, op + ".blend")
            pm.connectAttr(crv_node + ".arcLength", op + ".driver")
            pm.connectAttr(self.st_att[i], op + ".stretch")
            pm.connectAttr(self.sq_att[i], op + ".squash")
            op.setAttr("driver_min", .1)

            # scl compas
            if i != 0:
                div_node = node.createDivNode([1, 1, 1], [
                    self.fk_npo[i - 1] + ".sx", self.fk_npo[i - 1] + ".sy",
                    self.fk_npo[i - 1] + ".sz"
                ])

                pm.connectAttr(div_node + ".output",
                               self.scl_npo[i] + ".scale")

            # Controlers
            if i == 0:
                mulmat_node = applyop.gear_mulmatrix_op(
                    self.div_cns[i].attr("worldMatrix"),
                    self.root.attr("worldInverseMatrix"))
            else:
                mulmat_node = applyop.gear_mulmatrix_op(
                    self.div_cns[i].attr("worldMatrix"),
                    self.div_cns[i - 1].attr("worldInverseMatrix"))

            dm_node = node.createDecomposeMatrixNode(mulmat_node + ".output")
            pm.connectAttr(dm_node + ".outputTranslate",
                           self.fk_npo[i].attr("t"))
            pm.connectAttr(dm_node + ".outputRotate", self.fk_npo[i].attr("r"))

            # Orientation Lock
            if i == self.settings["division"] - 1:
                dm_node = node.createDecomposeMatrixNode(self.ik_ctl +
                                                         ".worldMatrix")
                blend_node = node.createBlendNode(
                    [dm_node + ".outputRotate%s" % s for s in "XYZ"],
                    [cns + ".rotate%s" % s for s in "XYZ"], self.lock_ori_att)
                self.div_cns[i].attr("rotate").disconnect()

                pm.connectAttr(blend_node + ".output",
                               self.div_cns[i] + ".rotate")

        # Head ---------------------------------------------
        self.fk_ctl[-1].addChild(self.head_cns)

        # scale compensation
        dm_node = node.createDecomposeMatrixNode(self.scl_npo[0] +
                                                 ".parentInverseMatrix")

        pm.connectAttr(dm_node + ".outputScale", self.scl_npo[0] + ".scale")
Example #36
0
def createStretchSpline( ctrl=None, curve=None, maintainVolume=True, globalScaleAttr=None ):
    # PyNode 캐스팅
    if not curve:
        sel = pm.selected()
        if sel:
            curve = sel[0]
    else:
        curve = pm.PyNode( curve )

    # 컨트롤러 캐스팅
    node = curve
    if ctrl:
        node = pm.PyNode(ctrl)

    # ikhandle 알아옴.
    ikHandle = curve.getShape().worldSpace.outputs( type='ikHandle')
    if not ikHandle:
        pm.mel.error(u'select curve for splineIK')

    ikHandle = ikHandle[0]

    # 연결된 조인트 알아옴
    joints = ikHandle.getJointList()

    # ctrl node
    node.addAttr('globalScale',        keyable=True,  dv=1 )
    node.addAttr('stretch',            keyable=True,  dv=1 )
    node.addAttr('maintainVolumne',    keyable=False, dv=1 )

    node.addAttr('currentCurveLength', keyable=True )
    node.addAttr('initCurveLength',    keyable=True  )
    node.addAttr('aimAxisScale',       nn='Aim Axis Scale', keyable=True )

    node.addAttr('sideAxisScale',      keyable=False )
    node.addAttr('sideAxisScaleShape', keyable=False )

    node.setAttr('currentCurveLength', keyable=False, channelBox=True)
    node.setAttr('initCurveLength',    keyable=True,  channelBox=True)
    #node.setAttr('aimAxisScale',       keyable=False, channelBox=True)

    # curveInfo node 생성
    crvInfo = pm.arclen( curve, ch=True )
    crvInfo.setAttr('arcLength', keyable=True)
    initCurveLength = crvInfo.arcLength.get()
    crvInfo.arcLength >> node.currentCurveLength
    node.initCurveLength.set( initCurveLength )

    # we need to figure out which direction the curve should be scaling.
    # do to that, we'll look at the translate values of the second joint.  Whichever translate has the
    # highest value, that'll be the first one and the other two axis will be the shrinking one
    stretchAxis = getStretchAxisAttr( joints[-1] )

    #
    # 노드 계산
    #
    #
    # aimAxisScale = currentCurveLength / initCurveLength
    md1 = pm.createNode( 'multiplyDivide', n=curve.name()+'_initCurveLength' )
    md1.setAttr('operation', keyable=True)
    md1.operation.set(2) # Divide
    node.currentCurveLength >> md1.input1X
    node.initCurveLength    >> md1.input2X
    md1.outputX             >> node.aimAxisScale

    # aimAxisScale = ( currentCurveLength / initCurveLength ) / globalScale
    md2 = pm.createNode( 'multiplyDivide', n=curve.name()+'_multGlobalScale' )
    md2.setAttr('operation', keyable=True)
    md2.operation.set(2) # Divide
    md1.outputX      >> md2.input1X
    node.globalScale >> md2.input2X
    md2.outputX      >> node.aimAxisScale

    # node.stretch 로 stretch가 되고 안되게~
    # aimAxisScale = pow( [ (currentCurveLength / initCurveLength) / globalScale ], stretch )
    stretchable = pm.createNode( 'multiplyDivide', n=curve.name()+'_stretchable_switchPow' )
    stretchable.operation.set(3) # pow
    stretchable.setAttr('operation', keyable=True)
    md2.outputX         >> stretchable.input1X
    node.stretch        >> stretchable.input2X
    stretchable.outputX >> node.aimAxisScale

    for jnt in joints:
        attr = jnt.attr( stretchAxis[0] )
        print 'connecting to "%s"'%attr
        node.aimAxisScale >> attr

    if globalScaleAttr:
        pm.Attribute( globalScaleAttr ) >> node.globalScale

    # maintain Volume Option이 설정 되어 있으면~~
    if maintainVolume:
        node.setAttr('maintainVolumne',    keyable=True, channelBox=False)
        node.setAttr('sideAxisScale',      keyable=True, channelBox=False)
        node.setAttr('sideAxisScaleShape', keyable=True, channelBox=False)

        #
        # sideAxisScale = 1/sqrt( scale )
        #
        sqrtNode = pm.createNode( 'multiplyDivide', n=curve.name()+'_volumnPreserve_sqrt' )
        sqrtNode.operation.set(3) # pow(sqrt)
        sqrtNode.setAttr('operation', keyable=True)
        node.aimAxisScale >> sqrtNode.input1X
        sqrtNode.input2.set(0.5,0.5,0.5)
        # sqrtNode.outputX  >> --->

        divNode = pm.createNode( 'multiplyDivide', n=curve.name()+'_volumnPreserve_div' )
        divNode.operation.set(2) # division
        divNode.setAttr('operation', keyable=True)
        divNode.input1.set(1,1,1)
        sqrtNode.outputX >> divNode.input2X
        divNode.outputX >> node.sideAxisScale

        # node.maintainVolumne 로 볼륨 유지가 되고 안되게~
        maintainVolumneAble = pm.createNode( 'multiplyDivide', n=curve.name()+'_maintainVolumne_switchPow' )
        maintainVolumneAble.operation.set(3) # pow
        maintainVolumneAble.setAttr('operation', keyable=True)
        divNode.outputX      >> maintainVolumneAble.input1X
        node.maintainVolumne >> maintainVolumneAble.input2X
        maintainVolumneAble.outputX >> node.sideAxisScale

        powAttr = rigCurveShapeControl( ctrl=node, attr='sideAxisScaleShape', sampleParams=range( len(joints) ) )

        for i in range( len(joints) ):
            Jnt = joints[i]
            Pow = powAttr[i]

            # pow( 1/sqrt( Scale ), 2 )
            powNode = pm.createNode( 'multiplyDivide', n=curve.name()+'_volumnPreserve_pow' )
            powNode.operation.set(3) # pow
            powNode.setAttr('operation', keyable=True)

            node.sideAxisScale >> powNode.input1X
            Pow                >> powNode.input2X
            powNode.outputX    >> Jnt.attr( stretchAxis[1] )
            powNode.outputX    >> Jnt.attr( stretchAxis[2] )
Example #37
0
#select ikSpline Handle
import pymel.core as pm

ik = pm.selected()[0]

joints = ik.getJointList()
curve = ik.getCurve()

curveInfo = pm.arclen(curve, ch=True)

md = pm.createNode('multiplyDivide')
md.operation.set(2)

length = curveInfo.arcLength.get()
md.input2X.set(length)
curveInfo.arcLength >> md.input1X

for j in joints:
    md.outputX >> j.sx


import pymel.core as pm
for bind_joint in pm.selected():
    rig_joint = pm.PyNode(bind_joint.name().replace('dst', 'src'))
    
    dMatrix = pm.createNode('decomposeMatrix')
    
    rig_joint.worldMatrix[0] >> dMatrix.inputMatrix
    
    dMatrix.outputRotate >> bind_joint.jointOrient
    dMatrix.outputTranslate >> bind_joint.translate
Example #38
0
    def addFkOperator(self, i, rootWorld_node, crv_node):

        fk_local_npo_xfoms = []
        if i not in [len(self.guide.apos), 0]:
            xform = getTransform(self.fk_local_npo[i])
            fk_local_npo_xfoms.append(xform)

        # break FK hierarchical orient
        if i not in [len(self.guide.apos), 0]:
            s = self.fk_ctl[i - 1]
            s2 = self.fk_npo[i]
            d = self.fk_local_npo[i]

            mulmat_node = applyop.gear_mulmatrix_op(s2.attr("matrix"), s.attr("matrix"))
            mulmat_node2 = applyop.gear_mulmatrix_op(mulmat_node.attr("output"), s2.attr("inverseMatrix"))

            dm_node = node.createDecomposeMatrixNode(mulmat_node2 + ".output")
            pm.connectAttr(dm_node + ".outputTranslate", d.attr("t"))

            check_list = (pm.Attribute, unicode, str)  # noqa
            cond = pm.createNode("condition")
            pm.setAttr(cond + ".operation", 4)  # greater
            attribute.connectSet(self.fk_collapsed_att, cond + ".secondTerm", check_list)
            attribute.connectSet(dm_node + ".outputRotate", cond + ".colorIfTrue", check_list)
            pm.setAttr(cond + ".colorIfFalseR", 0.)
            pm.setAttr(cond + ".colorIfFalseG", 0.)
            pm.setAttr(cond + ".colorIfFalseB", 0.)
            pm.connectAttr(cond + ".outColor", d.attr("r"))

        # References
        if i == 0:  # we add extra 10% to the first position
            u = (1.0 / (len(self.guide.apos) - 1.0)) / 10000
        else:
            u = getCurveUAtPoint(self.slv_crv, self.guide.apos[i])

        tmp_div_npo_transform = getTransform(self.div_cns_npo[i])  # to fix mismatch before/after later
        cns = applyop.pathCns(self.div_cns[i], self.slv_crv, False, u, True)
        cns.setAttr("frontAxis", 1)  # front axis is 'Y'
        cns.setAttr("upAxis", 0)  # front axis is 'X'

        # Roll
        # choose ik_ctls
        for _i, uv in enumerate(self.ik_uv_param):
            if u < uv:

                ik_a = self.ik_ctl[_i - 1]
                ik_b = self.ik_ctl[_i]

                roll_a = self.ik_decompose_rot[_i - 1]
                roll_b = self.ik_decompose_rot[_i]

                ratio = (uv - u) * (self.settings["ikNb"] - 1)
                break

        else:
            ik_a = self.ik_ctl[-2]
            ik_b = self.ik_ctl[-1]

            roll_a = self.ik_decompose_rot[-2]
            roll_b = self.ik_decompose_rot[-1]

            ratio = 1.

        intMatrix = applyop.gear_intmatrix_op(
            ik_a + ".worldMatrix",
            ik_b + ".worldMatrix",
            ratio)

        dm_node = node.createDecomposeMatrixNode(intMatrix + ".output")
        # pm.connectAttr(dm_node + ".outputRotate", self.twister[i].attr("rotate"))
        pm.parentConstraint(self.twister[i], self.ref_twist[i], maintainOffset=True)

        pm.connectAttr(self.ref_twist[i] + ".translate", cns + ".worldUpVector")
        self.div_cns_npo[i].setMatrix(tmp_div_npo_transform, worldSpace=True)

        # rotationdriver
        roll_ratio = (i + 1.00) / len(self.fk_ctl)
        mul1 = pm.createNode("multDoubleLinear")
        pm.connectAttr(roll_a.attr("outRoll"), mul1.attr("input1"))
        pm.setAttr(mul1.attr("input2"), ratio)

        mul2 = pm.createNode("multDoubleLinear")
        pm.connectAttr(roll_b.attr("outRoll"), mul2.attr("input1"))
        pm.setAttr(mul2.attr("input2"), (1. - ratio))

        add = pm.createNode("addDoubleLinear")
        pm.connectAttr(mul1.attr("output"), add.attr("input1"))
        pm.connectAttr(mul2.attr("output"), add.attr("input2"))

        compose_rot = pm.createNode("composeRotate")
        pm.setAttr(compose_rot.attr("axisOrientX"), 90.0)
        pm.setAttr(compose_rot.attr("axisOrientZ"), 90.0)
        pm.connectAttr(add.attr("output"), compose_rot.attr("roll"))
        pm.connectAttr(compose_rot.attr("outRotate"), self.div_roll_npo[i].attr("rotate"))

        # compensate scale reference
        div_node = node.createDivNode(
            [1, 1, 1],
            [rootWorld_node + ".outputScaleX",
             rootWorld_node + ".outputScaleY",
             rootWorld_node + ".outputScaleZ"])

        # Squash n Stretch
        op = applyop.gear_squashstretch2_op(self.scl_transforms[i],
                                            self.root,
                                            pm.arclen(self.slv_crv),
                                            "y",
                                            div_node + ".output")

        pm.connectAttr(self.volume_att, op + ".blend")
        pm.connectAttr(crv_node + ".arcLength", op + ".driver")
        # pm.connectAttr(self.st_att[i], op + ".stretch")
        # pm.connectAttr(self.sq_att[i], op + ".squash")

        # Controlers
        tmp_local_npo_transform = getTransform(self.fk_local_npo[i])  # to fix mismatch before/after later
        if i == 0:
            mulmat_node = applyop.gear_mulmatrix_op(
                self.div_roll_npo[i].attr("worldMatrix"),
                self.root.attr("worldInverseMatrix"))

            dm_node = node.createDecomposeMatrixNode(mulmat_node + ".output")
            pm.connectAttr(dm_node + ".outputTranslate", self.fk_npo[i].attr("t"))

        elif i != len(self.guide.apos) - 1:
            mulmat_node = applyop.gear_mulmatrix_op(
                self.div_roll_npo[i].attr("worldMatrix"),
                self.div_roll_npo[i - 1].attr("worldInverseMatrix"))

            dm_node = node.createDecomposeMatrixNode(mulmat_node + ".output")
            mul_node = node.createMulNode(div_node + ".output", dm_node + ".outputTranslate")
            pm.connectAttr(mul_node + ".output", self.fk_npo[i].attr("t"))

        else:
            pass

        if i == len(self.guide.apos) - 1:
            # pm.connectAttr(dm_node + ".outputRotate", self.fk_local_npo2.attr("r"))
            _ = pm.parentConstraint(self.ik_ctl[-1],
                                    self.fk_local_npo2,
                                    skipTranslate=("x", "y", "z"),
                                    maintainOffset=True)
        else:
            pm.connectAttr(dm_node + ".outputRotate", self.fk_npo[i].attr("r"))
        # self.addOperatorsOrientationLock(i, cns)
        self.fk_local_npo[i].setMatrix(tmp_local_npo_transform, worldSpace=True)

        # References
        if i < (len(self.fk_ctl) - 1):

            if self.negate:
                aim = (0., 1., 0.)
                upv = (0., 0., 1.)
            else:
                aim = (0., -1., 0.)
                upv = (0., 0., -1.)

            pm.aimConstraint(self.div_cns_npo[i + 1],
                             self.div_cns_npo[i],
                             mo=True,
                             worldUpType="object",
                             worldUpObject=self.fk_upvectors[i],
                             worldUpVector=(0., 1., 0.),
                             aimVector=aim,
                             upVector=upv,
                             )
Example #39
0
def createIKspline(IK_chain = None, ikSpineGrp = None):
    """
    maj:
     x-- add pelvis control
     -- add follow on mid ctrl
     
    debug: 
     -- orient ik mid ctrl in the same orientation then other controllers
     
    """
    
    # insert joints
#     global IKjointList, dwCtrl,upCtrl
    
    IKjointList = []
    jointIt = 3
    for jnt in IK_chain:
        IKjointList.append(jnt)
        child = jnt.getChildren()
        if len(child)>0:
            num = jointIt
            rad = pm.joint(jnt, query = True , radius = True)[0]
            dist = pm.joint(child[0], query = True , relative = True, position = True)[0]
            gap = dist/(num)
            for i in range((num-1),0,-1):
                newJnt = pm.insertJoint(jnt)
                pm.joint( newJnt, edit = True,component = True, relative = True, radius = rad, position = ((gap*i),0,0))
                IKjointList.append(newJnt)
    
    # create ikhandle
    IKspine = pm.ikHandle(solver = "ikSplineSolver", name = "IKspine", simplifyCurve = True, startJoint = IK_chain[0], endEffector = IK_chain[(len(IK_chain)-1)], createCurve = True, numSpans = 4)
    IKhandle = IKspine[0]
    IKcurve = IKspine[2]
    
    IKhandle.setParent(ikSpineGrp)
    curveJointList = pm.ikHandle(IKhandle, query = True, jointList = True)
    
    # create clusters on point
    cvsList = (IKcurve.getShape()).getCVs()
    
    clusterGrp = pm.group(name = "cluster_grp", empty = True)
    clusterGrp.setParent(ikSpineGrp)
    
    ctrlGrp = pm.group(name = "IK_ctrls_grp", empty = True)
    ctrlGrp.setParent(ikSpineGrp)
    
    # parent cluster to sphere
    ctrlList = []
    clusterList = []
    for i,cv in enumerate(cvsList):
        cluster = pm.cluster("curve1.cv[%s]" % i)
        cluster[0].setAttr("relative", 1)
        tmpCluster = cluster[1]
        tmpCluster.setParent(clusterGrp)
        clusterList.append(tmpCluster)
        
        oneCtrl = helpers.createNurbsSphere(rad = 0.5)
        ctrlList.append(oneCtrl)
    #     oneCtrl.setParent(ctrlGrp)
        tmpPoint = pm.pointConstraint(tmpCluster, oneCtrl)
        pm.delete(tmpPoint)
        pm.pointConstraint(oneCtrl, tmpCluster)
        
        
    for c in ctrlList:
        c.setParent(ctrlGrp)
    
    ctrlListGrp = helpers.insertGroups(ctrlList)
    
    # create main ctrls
    # orient up and down ctrls as joint selection
    upCtrlGrp, upCtrl = helpers.createOneCircle([1,0,0], sel = sel[0], rad = 4, suf= "_IK_ctrl")
    dwCtrlGrp, dwCtrl = helpers.createOneCircle([1,0,0], sel = sel[len(sel)-1], rad = 4, suf= "_IK_ctrl")
    idMid =  int((pm.datatypes.round(float(len(ctrlListGrp))/2)) - 1)
    midCtrlGrp, midCtrl = helpers.createOneCircle([0,1,0], sel = ctrlList[idMid], rad = 4, suf= "_IK_ctrl")
    
    upCtrlGrp.setParent(ctrlGrp)
    dwCtrlGrp.setParent(ctrlGrp)
    midCtrlGrp.setParent(ctrlGrp)
    
    upLoc = helpers.createOneLoc(parentToWorld = False, s = upCtrl)
    dwLoc = helpers.createOneLoc(parentToWorld = False, s = dwCtrl)
    upLoc.setAttr("tz", 2)
    dwLoc.setAttr("tz", 2)
    
    # parent sphere ctrls to main ctrls
    ctrlListGrp[0].setParent(upCtrl)
    ctrlListGrp[1].setParent(upCtrl)
    ctrlListGrp[idMid - 1].setParent(midCtrl)
    ctrlListGrp[idMid].setParent(midCtrl)
    ctrlListGrp[idMid + 1].setParent(midCtrl)
    ctrlListGrp[(len(ctrlListGrp)-2)].setParent(dwCtrl)
    ctrlListGrp[(len(ctrlListGrp)-1)].setParent(dwCtrl)
    
    # add twist
    IKhandle.setAttr("dTwistControlEnable", 1)
    IKhandle.setAttr("dWorldUpType", 2)
    IKhandle.setAttr("dWorldUpAxis", 3)
    
    pm.connectAttr(upLoc.worldMatrix, IKhandle.dWorldUpMatrix, force = True)
    pm.connectAttr(dwLoc.worldMatrix, IKhandle.dWorldUpMatrixEnd, force = True)
    
    #### add stretch
    # add parameters on upper control
    pm.addAttr(dwCtrl, longName  = "________", attributeType  = "enum", enumName = "CTRLS:")
    pm.setAttr(dwCtrl.________, keyable = True, lock = True)
    
    
    # make stretch editable
    pm.addAttr(dwCtrl, longName  = "stretch", attributeType  = "double", min = 0, max = 1, dv = 0) 
#     pm.addAttr(dwCtrl, longName  = "squash", attributeType  = "double", min = 0, max = 1, dv = 0)
    pm.addAttr(dwCtrl, longName  = "followJoint", attributeType  = "double", min = 0, max = 1, dv = 1)
    pm.addAttr(dwCtrl, longName  = "followCtrl", attributeType  = "double", min = 0, max = 1, dv = 0)
    
    pm.setAttr(dwCtrl.stretch, keyable = True)
#     pm.setAttr(dwCtrl.squash, keyable = True)
    pm.setAttr(dwCtrl.followJoint, keyable = True)
    pm.setAttr(dwCtrl.followCtrl, keyable = True)
    
    subFollowNode = pm.createNode('plusMinusAverage', name = "follow_mode_compense")
    subFollowNode.setAttr("input1D[0]", 1)
    subFollowNode.setAttr('operation', 2)
    pm.connectAttr(dwCtrl.followJoint, subFollowNode.input1D[1], f = True)
    pm.connectAttr(subFollowNode.output1D, dwCtrl.followCtrl, f = True)
    
    newJointsNum = (len(IKjointList))
    
    # add arclenght on curve
    arcLenNode = pm.arclen(IKcurve, ch = True)
    defaultSize = arcLenNode.getAttr("arcLength")
    
    # multiply/divide default size by current size
    mdNode = pm.createNode("multiplyDivide")
    mdNode.setAttr("operation", 2 )
    mdNode.setAttr("input2X", arcLenNode.getAttr("arcLength") )
    pm.connectAttr(arcLenNode.arcLength, mdNode.input1X)
    
    # average to calculate stretch addition : stretch - 1
    addStretchNode = pm.createNode("plusMinusAverage", name = "add_stretch")
    addStretchNode.setAttr("operation", 2)
    pm.connectAttr(mdNode.outputX, addStretchNode.input1D[0])
    addStretchNode.setAttr("input1D[1]", 1)
    
    # multiplydivide to mutiply stretch addition by strecth parameter
    stretchMultiplyNode = pm.createNode("multiplyDivide",  name = "multiply_stretch")
    pm.connectAttr(addStretchNode.output1D, stretchMultiplyNode.input1X)
    pm.connectAttr(dwCtrl.stretch, stretchMultiplyNode.input2X)
    
    # average to addition 1 + stretch addition
    addStretchFinalNode = pm.createNode("plusMinusAverage", name = "add_stretch")
    addStretchFinalNode.setAttr("operation", 1)
    pm.connectAttr(stretchMultiplyNode.outputX, addStretchFinalNode.input1D[0])
    addStretchFinalNode.setAttr("input1D[1]", 1)
    
    for jnt in IKjointList:
        jntNode =  (pm.PyNode(jnt))
        try:
            pm.connectAttr(addStretchFinalNode.output1D, jntNode.scaleX)
        except:
            print(Exception)
            
    ## add parametrable squash
    
    
    
    ## follow control on neck
    lastJoint = IKjointList[-1]
    IKfollowJnt = pm.duplicate(lastJoint, name = (lastJoint.nodeName() + "_follow"))[0]
    IKfollowJnt.setAttr("scaleX", 1)
    IKfollowJnt.setParent(ikSpineGrp)
    
    """
    tmp = IKfollowJnt.getParent()
    if tmp:
        tmp.setAttr("scaleX", 1)
        IKfollowJnt.setParent(world = True)
        pm.delete(tmp)
    """
    
    constrain = pm.parentConstraint(dwCtrl, IK_chain[len(IK_chain)-1], IKfollowJnt)
    
    for attr in pm.listAttr(constrain, visible = True, keyable= True):
                if 'IKW' in attr:
#                     print(attr)
                    pm.connectAttr(dwCtrl.followJoint, '%s.%s' % (constrain,attr))
                    ikFound = True
                elif 'ctrl' in attr:
#                     print(attr)
                    pm.connectAttr(dwCtrl.followCtrl, '%s.%s' % (constrain,attr))
                    
    
    ##### ik pelvis
    # follow control on pelvis
        # duplicate first joint as follow_pelvis_joint
    pelvisIKjoint = pm.duplicate(IKjointList[0], parentOnly = True, name = (IKjointList[0].nodeName() + "_pelvis_follow_joint"))[0]
    pelvisIKjoint.jointOrient.set([0,0,0])
    
        # duplicate down ctrl as pelvis ctrl
    pelvisIKctrlList = pm.duplicate(upCtrl, name = (upCtrl.nodeName() + "_pelvis"))
    pelvisIKctrl = pelvisIKctrlList[0]
    toDel = pm.listRelatives(pelvisIKctrl, children = True, type = "transform")
    pm.delete(toDel)
    

    
    manageCtrl.scaleShape(sel = pelvisIKctrl, scalX = True, scalY = True, scalZ = True, scale = 0.9)
    
        # parent pelvis ctrl under down ctrl
    pm.parent(pelvisIKctrl, upCtrl)
    helpers.createOneHelper(sel = pelvisIKctrl, freezeGrp = False, hierarchyParent = "insert")
    
        # add loc on  IKjointList[0]
    IKpelvisJointLocGrp, IKpelvisJointLoc = helpers.createOneHelper(type = "loc", sel = IKjointList[0], freezeGrp = False, hierarchyParent = "child")
        # add loc on  pelvis ctrl
    IKpelvisCtrlLocGrp, IKpelvisCtrlLoc = helpers.createOneHelper(type = "loc", sel = pelvisIKctrl, freezeGrp = False, hierarchyParent = "child")
        
        # parent constraint follow_pelvis_joint to locs
    IKpelvisConstraint = pm.parentConstraint(IKpelvisJointLoc, IKpelvisCtrlLoc, pelvisIKjoint)
    
        # add attributes on base controller
    pm.addAttr(upCtrl, ln =  "_______" , attributeType  = "enum", enumName = "CTRLS:")
    pm.addAttr(upCtrl, ln =  "followJoint" , at  = 'double', min = 0, max = 1, dv = 0)
    pm.addAttr(upCtrl, ln =  "followCtrl" , at  = 'double', min = 0, max = 1)
    
    pm.setAttr(upCtrl._______ , keyable = True, lock = True)
    pm.setAttr(upCtrl.followJoint, keyable = True)
    pm.setAttr(upCtrl.followCtrl, keyable = True)
    
    pelvisSubFollowNode = pm.createNode('plusMinusAverage', name = "pelvis_follow_mode_compense")
    pelvisSubFollowNode.setAttr("input1D[0]", 1)
    pelvisSubFollowNode.setAttr('operation', 2)
    pm.connectAttr(upCtrl.followJoint, pelvisSubFollowNode.input1D[1], f = True)
    pm.connectAttr(pelvisSubFollowNode.output1D, upCtrl.followCtrl, f = True)
    
        # connect attributes to constraint parent
    contraintList = pm.parentConstraint(IKpelvisConstraint, query = True, targetList = True )
    # pprint(contraintList)
    
    weightAliasList = pm.parentConstraint(IKpelvisConstraint, query = True, weightAliasList  = True )
    # pprint(weightAliasList)
    
    
    # pprint(IKpelvisJointLoc)
    
    for i,c in enumerate(contraintList):
        if c == IKpelvisJointLoc:
            pm.connectAttr(upCtrl.followJoint, weightAliasList[i] )
        elif c == IKpelvisCtrlLoc:
            pm.connectAttr(upCtrl.followCtrl, weightAliasList[i] )
        
        ## constraint deformation system to follow ik
        
    
    # return good array of ik joint to parent on
                    
    return IKfollowJnt, pelvisIKjoint
Example #40
0
    def addOperators(self):

        # Visibilities -------------------------------------
        # 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"))

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

        # IK Solver -----------------------------------------
        out = [self.bone0, self.bone1, self.ctrn_loc, self.eff_loc]
        node = aop.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)

        pm.connectAttr(self.blend_att, node + ".blend")
        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 ---------------------------------

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

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

        #spline IK for  twist jnts
        self.ikhArmTwist, self.armTwistCrv = aop.splineIK(
            self.getName("armTwist"),
            self.armTwistChain,
            parent=self.root,
            cParent=self.bone0)
        self.ikhForearmTwist, self.forearmTwistCrv = aop.splineIK(
            self.getName("forearmTwist"),
            self.forearmTwistChain,
            parent=self.root,
            cParent=self.bone1)

        #references
        self.ikhArmRef, self.tmpCrv = aop.splineIK(self.getName("armRollRef"),
                                                   self.armRollRef,
                                                   parent=self.root,
                                                   cParent=self.bone0)
        self.ikhForearmRef, self.tmpCrv = aop.splineIK(
            self.getName("forearmRollRef"),
            self.forearmRollRef,
            parent=self.root,
            cParent=self.eff_loc)
        self.ikhAuxTwist, self.tmpCrv = aop.splineIK(self.getName("auxTwist"),
                                                     self.auxTwistChain,
                                                     parent=self.root,
                                                     cParent=self.eff_loc)

        #setting connexions for ikhArmTwist
        self.ikhArmTwist.attr("dTwistControlEnable").set(True)
        self.ikhArmTwist.attr("dWorldUpType").set(4)
        self.ikhArmTwist.attr("dWorldUpAxis").set(3)
        self.ikhArmTwist.attr("dWorldUpVectorZ").set(1.0)
        self.ikhArmTwist.attr("dWorldUpVectorY").set(0.0)
        self.ikhArmTwist.attr("dWorldUpVectorEndZ").set(1.0)
        self.ikhArmTwist.attr("dWorldUpVectorEndY").set(0.0)
        pm.connectAttr(self.armRollRef[0].attr("worldMatrix[0]"),
                       self.ikhArmTwist.attr("dWorldUpMatrix"))
        pm.connectAttr(self.bone0.attr("worldMatrix[0]"),
                       self.ikhArmTwist.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.forearmRollRef[0].attr("worldMatrix[0]"),
                       self.ikhAuxTwist.attr("dWorldUpMatrix"))
        pm.connectAttr(self.eff_loc.attr("worldMatrix[0]"),
                       self.ikhAuxTwist.attr("dWorldUpMatrixEnd"))
        pm.connectAttr(self.auxTwistChain[1].attr("rx"),
                       self.ikhForearmTwist.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.armTwistCrv, ch=True)
        alAttrArm = arclen_node.attr("arcLength")
        muldiv_nodeArm = pm.createNode("multiplyDivide")
        pm.connectAttr(arclen_node.attr("arcLength"),
                       muldiv_nodeArm.attr("input1X"))
        muldiv_nodeArm.attr("input2X").set(alAttrArm.get())
        muldiv_nodeArm.attr("operation").set(2)
        for jnt in self.armTwistChain:
            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.forearmTwistCrv, ch=True)
        alAttrForearm = arclen_node.attr("arcLength")
        muldiv_nodeForearm = pm.createNode("multiplyDivide")
        pm.connectAttr(arclen_node.attr("arcLength"),
                       muldiv_nodeForearm.attr("input1X"))
        muldiv_nodeForearm.attr("input2X").set(alAttrForearm.get())
        muldiv_nodeForearm.attr("operation").set(2)
        for jnt in self.forearmTwistChain:
            pm.connectAttr(muldiv_nodeForearm.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.armTwistChain[0].attr("inverseScale"))
        pm.connectAttr(dm_node.attr("outputScale"),
                       self.forearmTwistChain[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"
        aop.aimCns(self.tws1A_npo,
                   self.tws0_loc,
                   axis=axis,
                   wupType=2,
                   wupVector=[0, 0, 1],
                   wupObject=self.mid_ctl,
                   maintainOffset=False)

        aop.aimCns(self.forearmTangentB_loc,
                   self.forearmTangentA_npo,
                   axis=axis,
                   wupType=2,
                   wupVector=[0, 0, 1],
                   wupObject=self.mid_ctl,
                   maintainOffset=False)
        pm.pointConstraint(self.eff_loc, self.forearmTangentB_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"
        aop.aimCns(self.tws1B_npo,
                   self.tws2_loc,
                   axis=axis,
                   wupType=2,
                   wupVector=[0, 0, 1],
                   wupObject=self.mid_ctl,
                   maintainOffset=False)

        aop.aimCns(self.armTangentA_loc,
                   self.armTangentB_npo,
                   axis=axis,
                   wupType=2,
                   wupVector=[0, 0, 1],
                   wupObject=self.mid_ctl,
                   maintainOffset=False)

        # 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.attr("sx"))

        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"

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

        div_nodeArm = nod.createDivNode(distA_node + ".distance",
                                        dm_node.attr("outputScaleX"))
        div_node2 = nod.createDivNode(div_nodeArm + ".outputX",
                                      distA_node.attr("distance").get())
        pm.connectAttr(div_node2.attr("outputX"), self.tws1A_loc.attr("sx"))
        pm.connectAttr(div_node2.attr("outputX"),
                       self.armTangentA_loc.attr("sx"))

        div_nodeForearm = nod.createDivNode(distB_node + ".distance",
                                            dm_node.attr("outputScaleX"))
        div_node2 = nod.createDivNode(div_nodeForearm + ".outputX",
                                      distB_node.attr("distance").get())
        pm.connectAttr(div_node2.attr("outputX"), self.tws1B_loc.attr("sx"))
        pm.connectAttr(div_node2.attr("outputX"),
                       self.forearmTangentB_loc.attr("sx"))

        #conection curve
        aop.gear_curvecns_op(self.armTwistCrv, [
            self.armTangentA_loc, self.armTangentA_ctl, self.armTangentB_ctl,
            self.elbowTangent_ctl
        ])
        aop.gear_curvecns_op(self.forearmTwistCrv, [
            self.elbowTangent_ctl, self.forearmTangentA_ctl,
            self.forearmTangentB_ctl, self.forearmTangentB_loc
        ])

        #Tangent controls vis
        pm.connectAttr(self.tangentVis_att,
                       self.armTangentA_ctl.attr("visibility"))
        pm.connectAttr(self.tangentVis_att,
                       self.armTangentB_ctl.attr("visibility"))
        pm.connectAttr(self.tangentVis_att,
                       self.forearmTangentA_ctl.attr("visibility"))
        pm.connectAttr(self.tangentVis_att,
                       self.forearmTangentB_ctl.attr("visibility"))
        pm.connectAttr(self.tangentVis_att,
                       self.elbowTangent_ctl.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 = aop.gear_mulmatrix_op(
                    self.armTwistChain[i] + ".worldMatrix",
                    div_cns + ".parentInverseMatrix")
            else:
                mulmat_node = aop.gear_mulmatrix_op(
                    self.forearmTwistChain[i - (self.settings["div0"] + 2)] +
                    ".worldMatrix", div_cns + ".parentInverseMatrix")
            dm_node = nod.createDecomposeMatrixNode(mulmat_node + ".output")
            pm.connectAttr(dm_node + ".outputTranslate", div_cns + ".t")
            pm.connectAttr(dm_node + ".outputRotate", div_cns + ".r")

            # 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")

        # return

        # 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)
Example #41
0
def build_joint_chain(name=None, crv=None,
                      order=None, num=None,
                      loc=None, reg_node=None, log=False):
    '''Given a valid curve, build joint chain along curve, num joints long

    Attributes:
        name -- Prefix name for plane. Str
        crv -- Curve to use as build guide. pm.nt.Transform
        order -- ['xyz','xzy','yxz','yzx','zxy','zyx']
        num -- Number of joints. 3 - 50, Int
        loc -- Used to set aim of secondary axis nt.Transform
        reg_node -- Registratioin node. nt.Transform
        log -- Output logging messages. Bool
    '''
    general.check_type(name, 'name', [str])
    general.check_type(crv, 'crv', [pm.nt.Transform])
    general.check_type(order, 'order', [str])
    general.check_type(num, 'num', [int])
    general.check_type(loc, 'loc', [pm.nt.Transform])

    orders = ['xyz', 'xzy', 'yxz', 'yzx', 'zxy', 'zyx']
    if order not in orders:
        raise errors.InputError('order', order, orders)
    if num < 3 or num > 50:
        raise errors.InputError('num', num, 'Range: 3 - 50')

    loc = loc.duplicate()[0]
    chain = []
    loc_v = None
    incr = float(1.0/num)
    if log:
        str_1 = 'Curve Length: ', pm.arclen(crv)
        str_2 = 'Increment: ', incr
        general.logging.debug(str_1)
        general.logging.debug(str_2)
    param = 0
    pm.select(clear=1)
    for i in range(num):
        pos = pm.pointOnCurve(crv, pr=param, p=True, top=True)
        if i == 0:  # Get vector to locator
            pos_v = pm.dt.Vector(pos)
            loc_pos = pm.dt.Vector(pm.xform(loc, q=1, ws=1, rp=1))
            loc_v = loc_pos - pos_v
            if log:
                str_1 = 'Jnt Pos: ', pos_v
                str_2 = 'Loc Pos: ', loc_pos
                str_3 = 'Loc Vec: ', loc_v
                general.logging.debug(str_1)
                general.logging.debug(str_2)
                general.logging.debug(str_3)
        j = pm.joint(p=pos, name='%s_Jnt_%s' % (name, (i+1)))
        chain.append(j)
        if log:
            str_1 = 'Created Joint: ', j
            str_2 = 'Parameter: ', param
            str_3 = 'Pos: ', pos
            str_4 = 'Curve: ', crv
            general.logging.debug(str_1)
            general.logging.debug(str_2)
            general.logging.debug(str_3)
            general.logging.debug(str_4)
        param += incr

    if log:
        str_1 = 'Chain: ', str(chain)
        general.logging.debug(str_1)

    # aim vector
    aim_v = []
    if order[0].lower() == 'x':
        aim_v = [1, 0, 0]
    if order[0].lower() == 'y':
        aim_v = [0, 1, 0]
    if order[0].lower() == 'z':
        aim_v = [0, 0, 1]

    # up vector
    up_v = []
    if order[1].lower() == 'x':
        up_v = [1, 0, 0]
    if order[1].lower() == 'y':
        up_v = [0, 1, 0]
    if order[1].lower() == 'z':
        up_v = [0, 0, 1]

    for jnt in chain[:-1]:
        # Snap/parent locator to jnt
        pm.parent(loc, jnt)
        loc.setTranslation(0)
        loc.setRotation([0, 0, 0])

        # move by loc_v
        pm.move(loc_v[0],
                loc_v[1],
                loc_v[2],
                loc, r=1)
        pm.parent(loc, w=1)

        # Remove joint from hierarchy
        p = jnt.getParent()
        c = jnt.getChildren()
        try:
            pm.parent(jnt, w=1)
        except:
            pass
        pm.parent(c, w=1)

        # Aim to child
        pm.delete(pm.aimConstraint(c,
                                   jnt,
                                   aim=aim_v,
                                   wu=up_v,
                                   wut='object',
                                   wuo=loc,
                                   mo=0))

        # Reinsert to heirarchy
        if c:
            pm.parent(c, jnt)
        if p:
            pm.parent(jnt, p)

    # Oreint last joint to none
    pm.joint(chain[-1], e=1, oj='none', zso=True)

    if not reg_node:
        reg_node = control.create_register_node(name)

    control.register_object(reg_node,
                            '%s_chain_root' % name,
                            chain[0])

    pm.select(clear=1)
    pm.delete(loc)
    return reg_node, chain
Example #42
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
Example #43
0
def create_stretchy_ik(ik_handle, prefix):

    prefix = "%s_stretchy" % prefix

    joints = ik_handle.getJointList()
    joints.extend(joints[-1].getChildren(type="joint"))
    spline_curve = ik_handle.getCurve()

    stretchy_grp = pm.group(name="%s_grp" % prefix, empty=True)
    pm.addAttr(stretchy_grp, k=1, at="double", ln="global_scale", dv=1)
    pm.addAttr(stretchy_grp, k=1, at="double", ln="stretch_toggle", min=0, max=1)
    pm.addAttr(stretchy_grp, k=1, at="double", ln="extend", min=0.10, dv=1)

    md = pm.createNode("multiplyDivide", name="%s_scale_md" % prefix)
    md.operation.set(2)

    # determine if it's a spline ik
    if spline_curve:
        print "spilne ik detected"

        curveInfo = pm.arclen(spline_curve, name="%s_arcLen" % prefix, ch=True)
        curveInfo.arcLength >> md.input1X

        distance = curveInfo.arcLength.get()

    else:
        print "ik detected"

        distance = 0.00
        for joint in joints[1::]:
            distance = distance + joint.tx.get()

        ik_handle.snapEnable.set(0)
        ik_handle.stickiness.set(1)

        distanceBetween = pm.createNode("distanceBetween", name="%s_distanceBetween" % prefix)
        joints[0].worldMatrix[0] >> distanceBetween.inMatrix1
        ik_handle.worldMatrix[0] >> distanceBetween.inMatrix2

        condition = pm.createNode("condition", name="%s_condition" % prefix)
        condition.operation.set(5)  # less or equal

        condition.secondTerm.set(distance)
        condition.colorIfTrueR.set(distance)

        distanceBetween.distance >> condition.firstTerm
        distanceBetween.distance >> condition.colorIfFalseR

        condition.outColorR >> md.input1X

    gMd = pm.createNode("multiplyDivide", name="%s_globalScale_mdl" % prefix)
    gMd.input1X.set(distance)
    stretchy_grp.global_scale >> gMd.input2X
    gMd.outputX >> md.input2X

    bta = pm.createNode("blendTwoAttr", name="%s_toggle_bta" % prefix)
    bta.input[0].set(1)
    md.outputX >> bta.input[1]

    stretchy_grp.stretch_toggle >> bta.attributesBlender

    tMd = pm.createNode("multiplyDivide", name="%s_tweakScale_md" % prefix)
    bta.output >> tMd.input1X
    stretchy_grp.extend >> tMd.input2X

    for joint in joints[1::]:
        mdl = pm.createNode("multiplyDivide", name="%s_stretchy_mdl" % joint)

        mdl.input1X.set(joint.tx.get())
        tMd.outputX >> mdl.input2X
        mdl.outputX >> joint.tx
Example #44
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.

        """

        # Auto bend ----------------------------
        if self.settings["autoBend"]:
            mul_node = node.createMulNode(
                [self.autoBendChain[0].ry, self.autoBendChain[0].rz],
                [self.sideBend_att, self.frontBend_att])

            mul_node.outputX >> self.ik1autoRot_lvl.rz
            mul_node.outputY >> self.ik1autoRot_lvl.rx

            self.ikHandleAutoBend = primitive.addIkHandle(
                self.autoBend_ctl, self.getName("ikHandleAutoBend"),
                self.autoBendChain, "ikSCsolver")

        # Tangent position ---------------------------------
        # common part
        d = vector.getDistance(self.guide.apos[0], self.guide.apos[-1])
        dist_node = node.createDistNode(self.ik0_ctl, self.ik1_ctl)
        rootWorld_node = node.createDecomposeMatrixNode(
            self.root.attr("worldMatrix"))

        div_node = node.createDivNode(dist_node + ".distance",
                                      rootWorld_node + ".outputScaleX")

        div_node = node.createDivNode(div_node + ".outputX", d)

        # tan0
        mul_node = node.createMulNode(self.tan0_att,
                                      self.tan0_npo.getAttr("ty"))

        res_node = node.createMulNode(mul_node + ".outputX",
                                      div_node + ".outputX")

        pm.connectAttr(res_node + ".outputX", self.tan0_npo.attr("ty"))

        # tan1
        mul_node = node.createMulNode(self.tan1_att,
                                      self.tan1_npo.getAttr("ty"))

        res_node = node.createMulNode(mul_node + ".outputX",
                                      div_node + ".outputX")

        pm.connectAttr(res_node + ".outputX", self.tan1_npo.attr("ty"))

        # Tangent Mid --------------------------------------
        if self.settings["centralTangent"]:
            tanIntMat = applyop.gear_intmatrix_op(
                self.tan0_npo.attr("worldMatrix"),
                self.tan1_npo.attr("worldMatrix"), .5)

            applyop.gear_mulmatrix_op(
                tanIntMat.attr("output"),
                self.tan_npo.attr("parentInverseMatrix[0]"), self.tan_npo)

            pm.connectAttr(self.tan_ctl.attr("translate"),
                           self.tan0_off.attr("translate"))

            pm.connectAttr(self.tan_ctl.attr("translate"),
                           self.tan1_off.attr("translate"))

        # Curves -------------------------------------------
        op = applyop.gear_curveslide2_op(self.slv_crv, self.mst_crv, 0, 1.5,
                                         .5, .5)

        pm.connectAttr(self.position_att, op + ".position")
        pm.connectAttr(self.maxstretch_att, op + ".maxstretch")
        pm.connectAttr(self.maxsquash_att, op + ".maxsquash")
        pm.connectAttr(self.softness_att, op + ".softness")

        # Volume driver ------------------------------------
        crv_node = node.createCurveInfoNode(self.slv_crv)

        # Division -----------------------------------------
        for i in range(self.settings["division"]):

            # References
            u = i / (self.settings["division"] - 1.0)
            if i == 0:  # we add extra 10% to the first vertebra
                u = (1.0 / (self.settings["division"] - 1.0)) / 10

            cns = applyop.pathCns(self.div_cns[i], self.slv_crv, False, u,
                                  True)

            cns.setAttr("frontAxis", 1)  # front axis is 'Y'
            cns.setAttr("upAxis", 0)  # front axis is 'X'

            # Roll
            intMatrix = applyop.gear_intmatrix_op(
                self.ik0_ctl + ".worldMatrix", self.ik1_ctl + ".worldMatrix",
                u)

            dm_node = node.createDecomposeMatrixNode(intMatrix + ".output")
            pm.connectAttr(dm_node + ".outputRotate",
                           self.twister[i].attr("rotate"))

            pm.parentConstraint(self.twister[i],
                                self.ref_twist[i],
                                maintainOffset=True)

            pm.connectAttr(self.ref_twist[i] + ".translate",
                           cns + ".worldUpVector")

            # compensate scale reference
            div_node = node.createDivNode([1, 1, 1], [
                rootWorld_node + ".outputScaleX", rootWorld_node +
                ".outputScaleY", rootWorld_node + ".outputScaleZ"
            ])

            # Squash n Stretch
            op = applyop.gear_squashstretch2_op(self.scl_transforms[i],
                                                self.root,
                                                pm.arclen(self.slv_crv), "y",
                                                div_node + ".output")

            pm.connectAttr(self.volume_att, op + ".blend")
            pm.connectAttr(crv_node + ".arcLength", op + ".driver")
            pm.connectAttr(self.st_att[i], op + ".stretch")
            pm.connectAttr(self.sq_att[i], op + ".squash")

            # Controlers
            if i == 0:
                mulmat_node = applyop.gear_mulmatrix_op(
                    self.div_cns[i].attr("worldMatrix"),
                    self.root.attr("worldInverseMatrix"))

                dm_node = node.createDecomposeMatrixNode(mulmat_node +
                                                         ".output")

                pm.connectAttr(dm_node + ".outputTranslate",
                               self.fk_npo[i].attr("t"))

            else:
                mulmat_node = applyop.gear_mulmatrix_op(
                    self.div_cns[i].attr("worldMatrix"),
                    self.div_cns[i - 1].attr("worldInverseMatrix"))

                dm_node = node.createDecomposeMatrixNode(mulmat_node +
                                                         ".output")

                mul_node = node.createMulNode(div_node + ".output",
                                              dm_node + ".outputTranslate")

                pm.connectAttr(mul_node + ".output", self.fk_npo[i].attr("t"))

            pm.connectAttr(dm_node + ".outputRotate", self.fk_npo[i].attr("r"))

            # Orientation Lock
            if i == 0:
                dm_node = node.createDecomposeMatrixNode(self.ik0_ctl +
                                                         ".worldMatrix")

                blend_node = node.createBlendNode(
                    [dm_node + ".outputRotate%s" % s for s in "XYZ"],
                    [cns + ".rotate%s" % s for s in "XYZ"], self.lock_ori0_att)

                self.div_cns[i].attr("rotate").disconnect()

                pm.connectAttr(blend_node + ".output",
                               self.div_cns[i] + ".rotate")

            elif i == self.settings["division"] - 1:
                dm_node = node.createDecomposeMatrixNode(self.ik1_ctl +
                                                         ".worldMatrix")

                blend_node = node.createBlendNode(
                    [dm_node + ".outputRotate%s" % s for s in "XYZ"],
                    [cns + ".rotate%s" % s for s in "XYZ"], self.lock_ori1_att)

                self.div_cns[i].attr("rotate").disconnect()
                pm.connectAttr(blend_node + ".output",
                               self.div_cns[i] + ".rotate")

        # Connections (Hooks) ------------------------------
        pm.parentConstraint(self.hip_lvl, self.cnx0)
        pm.scaleConstraint(self.hip_lvl, self.cnx0)
        pm.parentConstraint(self.scl_transforms[-1], self.cnx1)
        pm.scaleConstraint(self.scl_transforms[-1], self.cnx1)
Example #45
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.

        """
        dm_node_scl = node.createDecomposeMatrixNode(self.root.worldMatrix)
        if self.settings["keepLength"]:
            arclen_node = pm.arclen(self.mst_crv, ch=True)
            alAttr = pm.getAttr(arclen_node + ".arcLength")
            ration_node = node.createMulNode(self.length_ratio_att, alAttr)

            pm.addAttr(self.mst_crv, ln="length_ratio", k=True, w=True)
            node.createDivNode(arclen_node.arcLength, ration_node.outputX,
                               self.mst_crv.length_ratio)

            div_node_scl = node.createDivNode(self.mst_crv.length_ratio,
                                              dm_node_scl.outputScaleX)

        step = 1.000 / (self.def_number - 1)
        u = 0.000
        for i in range(self.def_number):
            cnsUpv = applyop.pathCns(self.upv_cns[i],
                                     self.upv_crv,
                                     cnsType=False,
                                     u=u,
                                     tangent=False)

            cns = applyop.pathCns(self.div_cns[i], self.mst_crv, False, u,
                                  True)

            # Connectiong the scale for scaling compensation
            for axis, AX in zip("xyz", "XYZ"):
                pm.connectAttr(dm_node_scl.attr("outputScale{}".format(AX)),
                               self.div_cns[i].attr("s{}".format(axis)))

            if self.settings["keepLength"]:

                div_node2 = node.createDivNode(u, div_node_scl.outputX)

                cond_node = node.createConditionNode(div_node2.input1X,
                                                     div_node2.outputX, 4,
                                                     div_node2.input1X,
                                                     div_node2.outputX)

                pm.connectAttr(cond_node + ".outColorR", cnsUpv + ".uValue")
                pm.connectAttr(cond_node + ".outColorR", cns + ".uValue")

            cns.setAttr("worldUpType", 1)
            cns.setAttr("frontAxis", 0)
            cns.setAttr("upAxis", 1)

            pm.connectAttr(self.upv_cns[i].attr("worldMatrix[0]"),
                           cns.attr("worldUpMatrix"))
            u += step

        if self.settings["keepLength"]:
            # add the safty distance offset
            self.tweakTip_npo.attr("tx").set(self.off_dist)
            # connect vis line ref
            for shp in self.line_ref.getShapes():
                pm.connectAttr(self.ikVis_att, shp.attr("visibility"))

        for ctl in self.tweak_ctl:
            for shp in ctl.getShapes():
                pm.connectAttr(self.ikVis_att, shp.attr("visibility"))
        for ctl in self.fk_ctl:
            for shp in ctl.getShapes():
                pm.connectAttr(self.fkVis_att, shp.attr("visibility"))

        if self.settings["extraTweak"]:
            for tweak_ctl in self.extratweak_ctl:
                for shp in tweak_ctl.getShapes():
                    pm.connectAttr(self.tweakVis_att, shp.attr("visibility"))
    def addFkOperator(self, i, rootWorld_node, crv_node):

        if i == 0 and self.settings["isSplitHip"]:
            s = self.fk_hip_ctl
            d = self.fk_local_npo[0],
            # maintainOffset, skipRotate, skipTranslate
            _ = pm.parentConstraint(s, d, mo=True, sr=("x", "y", "z"), st=())

            s = self.ik_global_out[0]
            d = self.hip_fk_local_in,
            # maintainOffset, skipRotate, skipTranslate
            pm.parentConstraint(s, d, mo=True)

        # break FK hierarchical orient
        if i not in [len(self.guide.apos), 0]:
            s = self.fk_ctl[i - 1]
            s2 = self.fk_npo[i]
            d = self.fk_local_npo[i]

            mulmat_node = applyop.gear_mulmatrix_op(s2.attr("matrix"), s.attr("matrix"))
            mulmat_node2 = applyop.gear_mulmatrix_op(mulmat_node.attr("output"), s2.attr("inverseMatrix"))

            dm_node = node.createDecomposeMatrixNode(mulmat_node2 + ".output")
            pm.connectAttr(dm_node + ".outputTranslate", d.attr("t"))

            check_list = (pm.Attribute, unicode, str)  # noqa
            cond = pm.createNode("condition")
            pm.setAttr(cond + ".operation", 4)  # greater
            attribute.connectSet(self.fk_collapsed_att, cond + ".secondTerm", check_list)
            attribute.connectSet(dm_node + ".outputRotate", cond + ".colorIfTrue", check_list)
            pm.setAttr(cond + ".colorIfFalseR", 0.)
            pm.setAttr(cond + ".colorIfFalseG", 0.)
            pm.setAttr(cond + ".colorIfFalseB", 0.)
            pm.connectAttr(cond + ".outColor", d.attr("r"))

        # References
        if i == 0:  # we add extra 10% to the first position
            u = (1.0 / (len(self.guide.apos) - 1.0)) / 1000
        else:
            u = getCurveUAtPoint(self.slv_crv, self.guide.apos[i])

        tmp_div_npo_transform = getTransform(self.div_cns_npo[i])  # to fix mismatch before/after later
        cns = applyop.pathCns(self.div_cns[i], self.slv_crv, False, u, True)
        cns.setAttr("frontAxis", 1)  # front axis is 'Y'
        cns.setAttr("upAxis", 0)  # front axis is 'X'

        # Roll
        # choose ik_ctls
        for _i, uv in enumerate(self.ik_uv_param):
            if u < uv:

                ik_a = self.ik_ctl[_i - 1]
                ik_b = self.ik_ctl[_i]

                if self.settings["isSplitHip"] and i == 0:
                    u = (i + 1) / (len(self.guide.apos) - 1.0)
                    ratio = u / uv * .5

                else:
                    ratio = u / uv

                break

        else:
            ik_a = self.ik_ctl[-2]
            ik_b = self.ik_ctl[-1]
            ratio = 1.

        intMatrix = applyop.gear_intmatrix_op(
            ik_a + ".worldMatrix",
            ik_b + ".worldMatrix",
            ratio)

        dm_node = node.createDecomposeMatrixNode(intMatrix + ".output")
        pm.connectAttr(dm_node + ".outputRotate", self.twister[i].attr("rotate"))
        pm.parentConstraint(self.twister[i], self.ref_twist[i], maintainOffset=True)

        pm.connectAttr(self.ref_twist[i] + ".translate", cns + ".worldUpVector")
        self.div_cns_npo[i].setMatrix(tmp_div_npo_transform, worldSpace=True)

        # compensate scale reference
        div_node = node.createDivNode(
            [1, 1, 1],
            [rootWorld_node + ".outputScaleX",
             rootWorld_node + ".outputScaleY",
             rootWorld_node + ".outputScaleZ"])

        # Squash n Stretch
        op = applyop.gear_squashstretch2_op(self.scl_transforms[i],
                                            self.root,
                                            pm.arclen(self.slv_crv),
                                            "y",
                                            div_node + ".output")

        pm.connectAttr(self.volume_att, op + ".blend")
        pm.connectAttr(crv_node + ".arcLength", op + ".driver")
        pm.connectAttr(self.st_att[i], op + ".stretch")
        pm.connectAttr(self.sq_att[i], op + ".squash")

        # Controlers
        tmp_local_npo_transform = getTransform(self.fk_local_npo[i])  # to fix mismatch before/after later
        if i == 0:
            mulmat_node = applyop.gear_mulmatrix_op(
                self.div_cns_npo[i].attr("worldMatrix"),
                self.root.attr("worldInverseMatrix"))

            dm_node = node.createDecomposeMatrixNode(mulmat_node + ".output")
            pm.connectAttr(dm_node + ".outputTranslate", self.fk_npo[i].attr("t"))

        else:
            mulmat_node = applyop.gear_mulmatrix_op(
                self.div_cns_npo[i].attr("worldMatrix"),
                self.div_cns_npo[i - 1].attr("worldInverseMatrix"))

            dm_node = node.createDecomposeMatrixNode(mulmat_node + ".output")
            mul_node = node.createMulNode(div_node + ".output", dm_node + ".outputTranslate")
            pm.connectAttr(mul_node + ".output", self.fk_npo[i].attr("t"))

        pm.connectAttr(dm_node + ".outputRotate", self.fk_npo[i].attr("r"))
        self.addOperatorsOrientationLock(i, cns)
        self.fk_local_npo[i].setMatrix(tmp_local_npo_transform, worldSpace=True)

        # References
        if i < (len(self.fk_ctl) - 1):
            aim = pm.aimConstraint(self.div_cns_npo[i + 1], self.div_cns_npo[i], maintainOffset=False)
            pm.setAttr(aim + ".aimVectorX", 0)
            pm.setAttr(aim + ".aimVectorY", 1)
            pm.setAttr(aim + ".aimVectorZ", 0)
            pm.setAttr(aim + ".upVectorX", 0)
            pm.setAttr(aim + ".upVectorY", 1)
            pm.setAttr(aim + ".upVectorZ", 0)
Example #47
0
def add_stretchy_ik(ik_handle):
    """ create stretchy IK"""
    logger.debug("Running function.. (%s.add_strectchy_ik)" %__name__)    
    
    prefix = "%s_stretchy" %ik_handle.name()
    
    joints = ik_handle.getJointList()
    joints.extend(joints[-1].getChildren(type='joint'))
    spline_curve = ik_handle.getCurve()

    ik_handle.add_separator_attr("stretchy_ik")
    pm.addAttr(ik_handle, k=1, at='double', ln='global_scale', dv=1)
    pm.addAttr(ik_handle, k=1, at='double', ln='stretch_toggle', min=0, max=1)
    pm.addAttr(ik_handle, k=1, at='double', ln='extend', min=0.10, dv=1)

    md = pm.createNode('multiplyDivide', name = "%s_scale_md" %prefix)
    md.operation.set(2)
    
    #determine if it's a spline ik
    if spline_curve:
        logger.debug("spilne ik detected")
        
        curveInfo = pm.arclen(spline_curve, name = "%s_arcLen" %prefix, ch=True)
        curveInfo.arcLength >> md.input1X
        
        distance = curveInfo.arcLength.get()
                    
    else:
        logger.debug("ik detected")
        
        distance = 0.00
        for joint in joints[1::]:
            distance = distance + joint.tx.get()        
        
        ik_handle.snapEnable.set(0)
        ik_handle.stickiness.set(1)
        
        distanceBetween = pm.createNode('distanceBetween', name='%s_distanceBetween'%prefix)
        joints[0].worldMatrix[0] >> distanceBetween.inMatrix1
        ik_handle.worldMatrix[0] >> distanceBetween.inMatrix2

        condition = pm.createNode('condition', name="%s_condition"%prefix)
        condition.operation.set(5) # less or equal
        
        condition.secondTerm.set(distance)
        condition.colorIfTrueR.set(distance)
        
        distanceBetween.distance >> condition.firstTerm
        distanceBetween.distance >> condition.colorIfFalseR
        
        condition.outColorR >> md.input1X
        
    gMd = pm.createNode("multiplyDivide", name = "%s_globalScale_mdl" %prefix)
    gMd.input1X.set(distance)
    ik_handle.global_scale >> gMd.input2X
    gMd.outputX >> md.input2X
    
    bta = pm.createNode('blendTwoAttr', name = "%s_toggle_bta" %prefix)
    bta.input[0].set(1)
    md.outputX >> bta.input[1]
     
    ik_handle.stretch_toggle >> bta.attributesBlender
    
    tMd = pm.createNode("multiplyDivide", name = "%s_tweakScale_md" %prefix)
    bta.output >> tMd.input1X
    ik_handle.extend >> tMd.input2X
    
    for joint in joints[1::]:
        mdl = pm.createNode('multiplyDivide', name = "%s_stretchy_mdl" %joint)

        mdl.input1X.set(joint.tx.get())
        tMd.outputX >> mdl.input2X
        mdl.outputX >> joint.tx