Пример #1
0
def strokePath(node, radius=.1):
    """
    Create a nurbs surface from a curve control
    """
    curveNodes = separateShapes(node)
    for curveNode in curveNodes:
        shape = curveNode.listRelatives(type='nurbsCurve')[0]
        t = pm.pointOnCurve(shape, p=0, nt=1)
        pos = pm.pointOnCurve(shape, p=0)
        cir = pm.circle(r=radius)[0]
        pm.xform(cir, t=pos, ws=1)

        #align the circule along the curve
        l = pm.spaceLocator()
        pm.xform(l, t=[pos[0]+t[0], pos[1]+t[1], pos[2]+t[2]], ws=1)
        pm.delete(pm.aimConstraint(l, cir, aimVector=[0,0,1]))
        pm.delete(l)

        newxf = pm.extrude(cir, curveNode, rn=False, po=0, et=2, ucp=1,
                            fpt=1, upn=1, scale=1, rsp=1, ch=1)[0]
        pm.delete(cir)
        pm.delete(curveNode.listRelatives(type='nurbsCurve'))
        parentShape(curveNode, newxf)
    if len(curveNodes) > 1:
        for i in range(1, len(curveNodes)):
            parentShape(curveNodes[0], curveNodes[i])
    return curveNodes[0]
Пример #2
0
def wiggleJointChain(strPnt, endPnt, side='FL', chainPos='Upper'):
    '''
    create joint chain between two points (strPnt & endPnt). require name string of strPnt & endPnt
    '''
    strPos = pm.xform( strPnt, q=True, ws=True, translation=True )
    endPos = pm.xform( endPnt, q=True, ws=True, translation=True )
    
    if side.endswith('L'):
        sideLabel = 1
    elif side.endswith('R'):
        sideLabel = 2
        
    ikSpCrv = pm.curve( degree=2, editPoint=( strPos, endPos) )
    ikSpCrv.rename( 'wiggle_%s_%s_CRV'%(side, chainPos) )
    ikSpCrvShp = ikSpCrv.listRelatives(shapes=True)[0]
    pm.select(clear=True)
    
    jnt2pos = pm.pointOnCurve( ikSpCrv, pr=0.3333, turnOnPercentage=True)
    jnt3pos = pm.pointOnCurve( ikSpCrv, pr=0.6667, turnOnPercentage=True )
    
    jntPos = ( strPos, jnt2pos, jnt3pos, endPos )
    jntList = []
    for pnt in jntPos:
        jName = 'Wiggle_%s_%s_%02d'%(side, chainPos, jntPos.index(pnt)+1)
        newJoint = pm.joint(name=jName, p=pnt)
        newJoint.side.set(sideLabel)
        newJoint.__getattr__('type').set(18)
        newJoint.otherType.set(jName)
        jntList.append(newJoint)
        
    pm.joint( jntList[0], edit=True, orientJoint='xyz', secondaryAxisOrient='xup', children=True, zeroScaleOrient=True )
    
    ikHandle = pm.ikHandle( name='Wiggle_%s_%s_ikHandle'%(side, chainPos),
                            solver='ikSplineSolver', 
                            createCurve=False, 
                            curve=ikSpCrvShp, 
                            startJoint=jntList[0].name(), 
                            endEffector=jntList[-1].name(), 
                            rootOnCurve=False, 
                            createRootAxis=True, 
                            parentCurve=False )
    
    jntGrp = jntList[0].listRelatives(parent=True)[0]
    jntGrp.rename('Wiggle_%s_%s'%(side, chainPos))
    crvInfo = pm.createNode('curveInfo', name='crvInf_wiggle_%s_%s'%(side, chainPos))
    multDiv1 = pm.createNode('multiplyDivide', name='md_wiggle_%s_%s_01'%(side, chainPos))
    multDiv2 = pm.createNode('multiplyDivide', name='md_wiggle_%s_%s_02'%(side, chainPos))
    ikSpCrvShp.worldSpace >> crvInfo.inputCurve
    arcLgt = crvInfo.arcLength.get()
    multDiv1.input2X.set(arcLgt)
    multDiv1.operation.set(2)
    spacing = jntList[1].tx.get()
    multDiv2.input2X.set(spacing)
    multDiv1.outputX >> multDiv2.input1X
    crvInfo.arcLength >> multDiv1.input1X
    
    for jnt in jntList[1:]:
        multDiv2.outputX >> jnt.tx
    
    return ikSpCrvShp, ikSpCrv, ikHandle[0], jntGrp
Пример #3
0
def createHighlight(mesh, lightType=mayaLights["Spot"], offset=6):
    """ Create Light based on curve drawn on object """
    # Get the currently selected curve
    curveA = getSelection()

    # Get the start and end points of the curve as Vectors
    crv_posA = dt.Vector(pm.pointOnCurve(curveA, pr=0))
    crv_posB = dt.Vector(pm.pointOnCurve(curveA, pr=curveA.maxValue.get()))

    # Calculate the mid point
    midPoint = (crv_posA + crv_posB) / 2

    # Get closest point & normal on mesh
    pointOnMesh_set = mesh.getClosestPointAndNormal(midPoint, space="world")
    pointOnMesh = pointOnMesh_set[0]
    pointOnMesh_normal = pointOnMesh_set[1]

    pm.spaceLocator(p=pointOnMesh)  # For debug/vis

    # Create dummy camera
    cam = pm.camera()
    camera = cam[0]
    camera.setTranslation(pointOnMesh + pointOnMesh_normal * offset)
    pm.viewLookAt(camera, pos=pointOnMesh)

    # Create light
    createLight(lightType, camera.getTranslation(), camera.getRotation())

    # Delete dummy camera
    pm.delete(camera)
Пример #4
0
def getPlaneDirection(crv):
    curvePosition = pm.pointOnCurve(crv, pr=0, p=True)
    curveTangent = pm.pointOnCurve(crv, pr=0, tangent=True)
    curvePosVec = MVector(curvePosition[0],curvePosition[1],curvePosition[2])
    curveTangentVec = MVector(curveTangent[0],curveTangent[1],curveTangent[2]).normal()

    yVec = MVector(0,1,0)
    dirVec = yVec ^ curveTangentVec
    return dirVec
Пример #5
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
Пример #6
0
def IK_objPosition(cur, obj):

    vec = []
    crv = str(pm.ls(cur)[0].listRelatives(s=1)[0])
    u = [
        IK_getUParam(cmds.xform(str(obj[i - 1]), q=1, ws=1, t=1), crv)
        for i in range(1,
                       len(obj) + 1)
    ]

    l = u[-1]
    cv = [
        u[0],
    ]

    for i in range(1, len(u) - 1):
        cv.append(((u[i] - u[i - 1]) * 0.5) + u[i - 1])
        cv.append(((u[i] - u[i - 1]) * 0.9) + u[i - 1])
        cv.append(u[i])
        cv.append(((u[i + 1] - u[i]) * 0.1) + u[i])
    if len(u) > 1:
        cv.append(((u[-1] - u[-2]) * 0.5) + u[-2])
    cv.append(l)

    ii = 1
    for p in cv:
        po = pm.pointOnCurve(cur, ch=1, pr=p)
        info = pm.rename(po, cur + "_curveInfo" + str(i))

        vec.append(info.getAttr("position"))
        pm.delete(info)
        ii += 1
    pm.delete(obj)
    return vec
Пример #7
0
def CurveLoft(crv, geom, size, norDir, nm):
    try:
        crvSh = crv.listRelatives(s=1, type='nurbsCurve')[0]
    except:
        pm.warning('%s is not nurbsCurve')
        return
    tmpOC = pm.createNode('nearestPointOnCurve', n='TmpOC')
    crv.ws >> tmpOC.inputCurve
    copyCrvA = crv.duplicate(n='%sCopyACrv' % crv.name().replace('Crv', ''))[0]
    copyCrvB = crv.duplicate(n='%sCopyBCrv' % crv.name().replace('Crv', ''))[0]
    cvSz = int(crv.spans.get())
    if crv.d.get() == 3: cvSz = cvSz + 3
    upvec = dt.Vector(int(norDir[0]), int(norDir[1]), int(norDir[2]))
    for i in xrange(cvSz):
        tmpOC.inPosition.set(crv.cv[i].getPosition(space='world'))
        tVec = pm.pointOnCurve(crv, pr=tmpOC.parameter.get(), nt=1)
        cVecA = dt.cross(upvec, dt.Vector(tVec))
        cVecB = dt.cross(dt.Vector(tVec), upvec)
        pm.move(copyCrvA.cv[i], cVecA * size, r=1)
        pm.move(copyCrvB.cv[i], cVecB * size, r=1)
    geo = pm.loft(copyCrvB,
                  copyCrvA,
                  ch=1,
                  u=1,
                  c=0,
                  ar=1,
                  d=3,
                  ss=1,
                  rn=0,
                  po=int(geom),
                  rsn=1)
    mel.eval('DeleteHistory %s' % geo[0].name())
    pm.delete(tmpOC, copyCrvA, copyCrvB)
    return geo[0]
Пример #8
0
    def build(self):
        """ Build system"""
        self.all_jnts = []
        self.all_pointOnCurve_nodes = []
        self.Pos = []

        # Creation of all joints
        self.all_jnts = [pm.joint(rad=self._radius) for x in range(self._interval)]
        for joint in self.all_jnts:
            pm.parent(joint, w=True)
            adb.makeroot_func(joint)

        # Creation of Point to Curve Nodes
        self.all_pointOnCurve_nodes = [pm.pointOnCurve(self._curve, ch=True, top=True) for x in range(self._interval)]

        for node, joint in zip(self.all_pointOnCurve_nodes, self.all_jnts):
            pm.PyNode(node).positionX >> (pm.PyNode(joint).getParent()).translateX
            pm.PyNode(node).positionY >> (pm.PyNode(joint).getParent()).translateY
            pm.PyNode(node).positionZ >> (pm.PyNode(joint).getParent()).translateZ

        # Find all position
        Nintervalls = self._interval - 1
        for i in range(0, Nintervalls):
            factor = 1 / float((Nintervalls))
            oPos = factor * i
            self.Pos.append(oPos)
        self.Pos.append(1)

        for oPosition, oNode in zip(self.Pos, self.all_pointOnCurve_nodes):
            pm.PyNode(oNode).parameter.set(oPosition)

        pm.select(None)
Пример #9
0
def curve_getPoint(curve, place, cv=False):
	'''Returns points on a curve
	Args:
		curve (pm.PyNode): curve to be queried
		place (float): tells what percent and or cv to choose from, if cv, use int
		cv (boolean): tells whether to use cv positions or not
	Returns:
		(vector): position of point on curve or None if CV doesn't exist
	Usage:
		curve_getPoint(pm.ls(sl=True)[0], .8) - Query Percentage
		curve_getPoint(pm.ls(sl=True)[0], 5, cv=True)) - Query CV
	'''
	pos=[0,0,0]
	if cv:
		if place in range(len(curve.getShape().getCVs())):
			pos = curve.getShape().getCV(place)
		else:
			return None
	else:
		poc = pm.pointOnCurve(curve, ch=True, top=True)
		poc = pm.PyNode(poc)
		poc.parameter.set(place)
		pos = poc.position.get()
		pm.delete(poc)
	return pos
Пример #10
0
def point_on_curve_position(curve, parameter):
    u"""获取曲线上cv点的位置信息

    :param curve: 曲线的名字
    :param parameter: 曲线上的参数值
    :return: Returns the (x,y,z) position of curve at parameter.
    """
    return pm.pointOnCurve(curve, pr=parameter, p=True)
Пример #11
0
    def get_closest_crv_pair_list(self, driver_tfm, driven_tfm):

        driver_crv_list = list(set(pm.listRelatives(pm.listRelatives(driver_tfm, ad = True, type = 'nurbsCurve'), parent = True)))
        driven_crv_list = list(set(pm.listRelatives(pm.listRelatives(driven_tfm, ad = True, type = 'nurbsCurve'), parent = True)))

        driver_pos_info = []

        for driver in driver_crv_list:
            pos = pm.pointOnCurve(driver, pr = 0)
            driver_pos_info.append([pos, driver])

        print driver_pos_info

        pair_list = []
        for driven in driven_crv_list:
            pos = pm.pointOnCurve(driven, pr = 0)
            proximity_list = []
            for driver_pos in driver_pos_info:
                distance = self.get_distance(pos, driver_pos[0])
                proximity_list.append([distance, driver_pos[1]])
            proximity_list.sort()
            pair_list.append([proximity_list[0][1], driven])

        return pair_list
Пример #12
0
def distributeCrv( transformNodes, curve=None, uniform=True ):
    nodes = [pm.PyNode(node) for node in transformNodes]

    crv = pm.PyNode(curve)
    crvShape = crv.getShape()
    
    nodeNums = len(nodes)    

    contMembers = []    
    if uniform:
        rebCrv, reb = pm.rebuildCurve( crvShape, ch=True, rpo=False, rt=4, end=1, kr=0, kcp=0, kep=1, kt=0, s=4, d=3, tol=0.001 )
        crvShape  = rebCrv.getShapes( type='nurbsCurve' )[0]

        rebCrv.rename( crv+'_rebCrv' )
        reb.rename( crv+'_rebuildCrv' )

        contMembers.append( pm.parentConstraint( crv, rebCrv ) )
        contMembers.append( pm.scaleConstraint(  crv, rebCrv ) )
        contMembers.append( rebCrv )
        contMembers.append( reb )

    unit = None
    if crv.form() == 'periodic':
        unit = (1.0/nodeNums)
    else:
        unit = (1.0/(nodeNums-1))

    for i, node in enumerate( nodes ):
        pointOnCurve = pm.PyNode( pm.pointOnCurve( crvShape, ch=True ) )
        pointOnCurve.rename( node+'_POC' )
        pointOnCurve.turnOnPercentage.set(True)

        pointOnCurve.parameter.set( unit*i  )
        pointOnCurve.p >> node.t

        pointOnCurve.setAttr('parameter', keyable=True)

        contMembers.append( pointOnCurve )

    cont = pm.container( type='dagContainer', addNode=contMembers, n=crv+'_distributeCrv#' )
    cont.v.set(False)

    return cont    
Пример #13
0
def get_points_on_curve(inputcurve, amount=3):
    infoNode = pm.PyNode(pm.pointOnCurve(inputcurve, ch=True, top=True))
    try:
        inc = 1.0 / (amount - 1)
        for i in range(amount):
            infoNode.parameter.set(i * inc)
            pos = infoNode.position.get()
            norm = infoNode.normal.get()
            tang = infoNode.tangent.get()
            crossV = norm.cross(tang)
            pmatrix = pm.dt.Matrix(norm.x, norm.y, norm.z, 0, tang.x, tang.y,
                                   tang.z, 0, crossV.x, crossV.y, crossV.z, 0,
                                   pos.x, pos.y, pos.z, 0)
            yield (pmatrix.translate, pmatrix.rotate)
    except ZeroDivisionError:
        log.error('Amount is too low, current:{}, minimum:{}'.format(
            amount, 2))
        raise
    finally:
        pm.delete(infoNode)
Пример #14
0
def LsyIK_stretch(cur, obj, scaleObj):

    crv = str(pm.ls(cur)[0].listRelatives(s=1)[0])
    u = [
        IK_getUParam(cmds.xform(str(obj[i - 1]), q=1, ws=1, t=1), crv)
        for i in range(1,
                       len(obj) + 1)
    ]
    info = []
    for i in range(len(u)):
        po = pm.pointOnCurve(cur, ch=1, pr=u[i])
        info.append(pm.rename(po, cur + "_curveInfo" + str(i)))

    t = [i for i in range(0, len(info) - 1, 2)]
    for i in range(0, len(info) - 1):

        dis = pm.createNode("distanceBetween", n=obj[i + 1] + "_disBet")
        pm.connectAttr(info[i] + ".position", dis + ".point1")
        pm.connectAttr(info[i + 1] + ".position", dis + ".point2")

        if i in t:
            mul = [
                pm.createNode("multiplyDivide", n=obj[i + 1] + "_mul" + x)
                for x in ["1", "2"]
            ]
            [pm.setAttr(s + ".operation", 2) for s in mul]

            pm.connectAttr(dis + ".distance", mul[0] + ".input1X")
            pm.connectAttr(scaleObj + ".sy", mul[0] + ".input2X")

            pm.connectAttr(mul[0] + ".outputX", mul[1] + ".input1X")
            pm.setAttr(mul[1] + ".input2X", pm.getAttr(mul[1] + ".input1X"))
            pm.connectAttr(mul[1] + ".outputX", obj[i] + ".sx")
        else:
            pm.connectAttr(dis + ".distance", mul[0] + ".input1Z")
            pm.connectAttr(scaleObj + ".sy", mul[0] + ".input2Z")

            pm.connectAttr(mul[0] + ".outputZ", mul[1] + ".input1Z")
            pm.setAttr(mul[1] + ".input2Z", pm.getAttr(mul[1] + ".input1Z"))
            pm.connectAttr(mul[1] + ".outputZ", obj[i] + ".sx")
Пример #15
0
def create_shapes(*args):
    print('This will create shapes')
    num = slider1.getValue()
    print('Number of shapes to be created:', num)

    i = 0
    while i < num:
        value = float(i) / num
        angle = random.randint(0, 359)
        radius = random.uniform(0.5, 2)
        height = random.uniform(0.5, 1)
        x, y, z = pm.pointOnCurve('curve1', pr=value, turnOnPercentage=True)

        x1 = random.uniform(x - 3, x + 3)
        y1 = random.uniform(y - 3, y + 3)
        z1 = random.uniform(z - 3, z + 3)

        shape = options.getValueArray4()
        j = random.randint(0, 3)
        if shape[j] == True:
            if j == 0:
                figure = pm.polyTorus(r=radius, sr=0.25)
                pm.move(x1, y1, z1, figure)
                i += 1
            elif j == 1:
                figure = pm.polyCone(sx=1, sy=1.5, sz=0.5, r=radius, h=height)
                pm.move(x1, y1, z1, figure)
                i += 1
            elif j == 2:
                figure = pm.polySphere(r=radius)
                pm.move(x1, y1, z1, figure)
                i += 1
            elif j == 3:
                figure = pm.polyCylinder(r=radius, h=height)
                pm.move(x1, y1, z1, figure)
                i += 1
            pm.select(figure)
            pm.rotate(angle, 0, 0, r=True)
            pm.select(clear=True)
Пример #16
0
    def positionRig(self):
        #
        # 로케이터 생성
        #
        LOC = None
        if self.locatorShape=='locator':
            LOC = pm.spaceLocator( n='locOnCrv#')
        else:
            LOC = pm.group( n='grpOnCrv#', em=True)

        if self.name:
            LOC.rename( self.name )

        LOC.addAttr( 'parameter',        sn='pr',  dv=self.param,        keyable=True )
        LOC.addAttr( 'turnOnPercentage', sn='top', dv=self.turnOnPercentage, at='bool', keyable=True )
        LOC.it.set(False)

        #
        # pointOnCurve 리깅
        #
        pntOnCrv = pm.PyNode( pm.pointOnCurve( self.curve, parameter=self.param, ch=True ) )
        pntOnCrv.turnOnPercentage.set(True)

        pntOnCrv.setAttr('parameter',        keyable=True)
        pntOnCrv.setAttr('turnOnPercentage', keyable=True)

        pntOnCrv.rename( LOC+'_POC' )

        #
        # Position 리깅
        #
        LOC.parameter        >> pntOnCrv.parameter
        LOC.turnOnPercentage >> pntOnCrv.turnOnPercentage
        pntOnCrv.position    >> LOC.t

        self.locator = LOC
        self.pointOnCurve = pntOnCrv
Пример #17
0
def get_pos(crv, param=0):  # dt.Vector
    return dt.Vector(pm.pointOnCurve(crv, pr=param, p=True))
Пример #18
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
Пример #19
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
Пример #20
0
def crvToJnt( curves=[], div=None, ep=True ):
    '''
    update : 2015-04-29
    '''
    # args
    if curves:
        pm.selec(curves)
    curves  = [pm.PyNode(c) for c in pm.filterExpand(sm=9) ]
    if not curves:
        raise

    node     = curves[-1]
    nodeType = node.nodeType()

    transform = None
    crvShape  = None
    if nodeType == 'nurbsCurve':
        crvShape  = node
        transform = crvShape.getParent()
    elif nodeType == 'transform':
        transform = node
        crvShape  = transform.getShapes( type='nurbsCurve' )[0]

    if div:
        rebCrv, rebuild = pm.rebuildCurve( crvShape, ch=True, rpo=False, rt=4, end=1, kr=0, kcp=0, kep=1, kt=0, s=4, d=3, tol=0.001 ) # curvature type
        transform = rebCrv
        crvShape  = transform.getShapes( type='nurbsCurve' )[0]

    # 위치값 챙김.
    p=[]
    if div:
        if ep:
            for i in range(div+1):
                # 커브를 일정하게 나눈 위치 값을 가져옴
                p.append( pm.pointOnCurve( crvShape, turnOnPercentage=True, parameter=(1.0/div)*i ) )
        else:
            rebuild.rebuildType.set(0) # uniform
            rebuild.spans.set(div+1)
            for i in range( len( rebCrv.getCVs() ) ):
                p.append( crvShape.cv[i].getPosition() )

    else:
        if ep:
            # editPoint의 위치값을 가져옴
            for i in range( crvShape.numEPs() ):
                p.append( pm.xform( crvShape.ep[i], q=True, ws=True, t=True) )
        else:
            # cv의 위치값을 가져옴
            for i in range( len( crvShape.getCVs() ) ):
                p.append( crvShape.cv[i].getPosition() )

    if div:
        pm.delete( transform )

    JNTs = []

    pm.select(cl=True)
    for pos in p:
        JNTs.append( pm.joint( p=pos) )

    # 조인트 오리엔트 디폴트
    pm.joint( JNTs[0], e=True, oj='xyz', secondaryAxisOrient='yup', ch=True, zso=True )
    
    pm.select( JNTs )

    return JNTs
Пример #21
0
    def create(self):
        self.nodes = []

        #------------------------------
        #
        # Create Ctrler
        #
        #------------------------------
        self.root_grp = pm.group( n='TwistHelper_grp', em=True)
        self.constMe_to_parent = pm.group( n='constMe_to_parent', em=True)
        self.constMe_to_start  = pm.group( n='constMe_to_start', em=True)
        self.constMe_to_mid    = pm.group( n='constMe_to_mid', em=True )
        self.constMe_to_end    = pm.group( n='constMe_to_end', em=True)
        self.doNotTouch_grp  = pm.group( n='doNotTouch_grp', em=True)
        pm.parent( self.constMe_to_start, self.constMe_to_mid, self.constMe_to_end, self.constMe_to_parent)
        pm.parent( self.constMe_to_parent, self.doNotTouch_grp, self.root_grp )

        self.start_T_anim = pm.group( n='start_T_anim', em=True)
        self.end_T_anim   = pm.group( n='end_T_anim', em=True)
        pm.parent( self.start_T_anim, self.constMe_to_start )
        pm.parent( self.end_T_anim,   self.constMe_to_end )

        self.mid_T_anim   = pm.group( n='mid_T_anim', em=True )
        self.mid1_T_anim  = pm.group( n='mid1_T_anim', em=True )
        self.mid2_T_anim  = pm.group( n='mid2_T_anim', em=True )
        pm.parent( self.mid1_T_anim, self.mid2_T_anim, self.mid_T_anim )
        pm.parent( self.mid_T_anim, self.constMe_to_mid )

        self.start_R_result = pm.group( n='start_R_result', em=True)
        self.start_up_anim  = pm.group( n='start_up_anim', em=True)
        pm.parent( self.start_R_result, self.start_up_anim, self.start_T_anim )

        self.end_R_result = pm.group( n='end_R_result', em=True)
        self.end_up_anim  = pm.group( n='end_up_anim', em=True)
        pm.parent( self.end_R_result, self.end_up_anim, self.end_T_anim )

        self.doNotTouch_grp.v.set(False)        

        # 어트리뷰트 잠금
        self._lockAndHideAttr([self.start_up_anim, self.end_up_anim],['rx','ry','rz','sx','sy','sz'])
        self._lockAndHideAttr([self.constMe_to_start, self.constMe_to_mid, self.constMe_to_end, self.mid_T_anim, self.constMe_to_parent],['sx','sy','sz','v'])
        self._lockAndHideAttr([self.start_R_result, self.end_R_result],['sx','sy','sz','v'])
        self._lockAndHideAttr([self.start_T_anim, self.end_T_anim, self.mid1_T_anim, self.mid2_T_anim],['rx','ry','rz','sx','sy','sz','v'])
        self._lockAndHideAttr([self.doNotTouch_grp, self.root_grp],['tx','ty','tz','rx','ry','rz','sx','sy','sz'])

        self.nodes.extend([self.root_grp, self.constMe_to_parent, self.constMe_to_start, self.constMe_to_mid, self.constMe_to_end, self.doNotTouch_grp, self.start_T_anim, self.end_T_anim, self.mid_T_anim, self.mid1_T_anim, self.mid2_T_anim, self.start_R_result, self.start_up_anim])
        self.nodes.extend([self.end_R_result, self.end_up_anim])

        #------------------------------
        #
        # config Attribute
        #
        #------------------------------
        ctrl = self.root_grp
        ctrl.addAttr('aimAxis', at='enum', en='PositiveX:NegativeX:', keyable=False) # IK핸들의 Advanced Twist Controls 세팅이 -x축은 고려되어 있지 않음. 의미 없음.
        ctrl.addAttr('aimVector', at='double3')
        ctrl.addAttr('aimVectorX', at='double', p='aimVector', keyable=False)
        ctrl.addAttr('aimVectorY', at='double', p='aimVector', keyable=False)
        ctrl.addAttr('aimVectorZ', at='double', p='aimVector', keyable=False)
        ctrl.addAttr('upAxis', at='enum', en='PositiveY:NegativeY:ClosetY:PositiveZ:NegativeZ:ClosetZ:', keyable=True)
        ctrl.addAttr('upVector', at='double3')
        ctrl.addAttr('upVectorX', at='double', p='upVector', keyable=True)
        ctrl.addAttr('upVectorY', at='double', p='upVector', keyable=True)
        ctrl.addAttr('upVectorZ', at='double', p='upVector', keyable=True)
        ctrl.addAttr('startWorldUpVector', at='double3')
        ctrl.addAttr('startWorldUpVectorX', at='double', p='startWorldUpVector', keyable=True)
        ctrl.addAttr('startWorldUpVectorY', at='double', p='startWorldUpVector', keyable=True)
        ctrl.addAttr('startWorldUpVectorZ', at='double', p='startWorldUpVector', keyable=True)
        ctrl.addAttr('endWorldUpVector', at='double3')
        ctrl.addAttr('endworldUpVectorX', at='double', p='endWorldUpVector', keyable=True)
        ctrl.addAttr('endworldUpVectorY', at='double', p='endWorldUpVector', keyable=True)
        ctrl.addAttr('endworldUpVectorZ', at='double', p='endWorldUpVector', keyable=True)
        ctrl.aimVector.set(self.aimVector)
        ctrl.upVector.set(self.upVector)
        ctrl.startWorldUpVector.set(self.startWorldUpVector)
        ctrl.endWorldUpVector.set(self.endWorldUpVector)

        pm.setDrivenKeyframe( ctrl.aimVectorX, value= 1, currentDriver=ctrl.aimAxis, driverValue=0 ) # positiveX
        pm.setDrivenKeyframe( ctrl.aimVectorY, value= 0, currentDriver=ctrl.aimAxis, driverValue=0 ) # positiveX
        pm.setDrivenKeyframe( ctrl.aimVectorZ, value= 0, currentDriver=ctrl.aimAxis, driverValue=0 ) # positiveX
        pm.setDrivenKeyframe( ctrl.aimVectorX, value=-1, currentDriver=ctrl.aimAxis, driverValue=1 ) # negativeX
        pm.setDrivenKeyframe( ctrl.aimVectorY, value= 0, currentDriver=ctrl.aimAxis, driverValue=1 ) # negativeX
        pm.setDrivenKeyframe( ctrl.aimVectorZ, value= 0, currentDriver=ctrl.aimAxis, driverValue=1 ) # negativeX

        pm.setDrivenKeyframe( ctrl.upVectorX, value= 0, currentDriver=ctrl.upAxis, driverValue=0 ) # positiveY
        pm.setDrivenKeyframe( ctrl.upVectorY, value= 1, currentDriver=ctrl.upAxis, driverValue=0 ) # positiveY
        pm.setDrivenKeyframe( ctrl.upVectorZ, value= 0, currentDriver=ctrl.upAxis, driverValue=0 ) # positiveY
        pm.setDrivenKeyframe( ctrl.upVectorX, value= 0, currentDriver=ctrl.upAxis, driverValue=1 ) # negativeY
        pm.setDrivenKeyframe( ctrl.upVectorY, value=-1, currentDriver=ctrl.upAxis, driverValue=1 ) # negativeY
        pm.setDrivenKeyframe( ctrl.upVectorZ, value= 0, currentDriver=ctrl.upAxis, driverValue=1 ) # negativeY
        pm.setDrivenKeyframe( ctrl.upVectorX, value= 0, currentDriver=ctrl.upAxis, driverValue=3 ) # positiveZ
        pm.setDrivenKeyframe( ctrl.upVectorX, value= 0, currentDriver=ctrl.upAxis, driverValue=2 ) # negativeY
        pm.setDrivenKeyframe( ctrl.upVectorY, value= 1, currentDriver=ctrl.upAxis, driverValue=2 ) # negativeY
        pm.setDrivenKeyframe( ctrl.upVectorZ, value= 0, currentDriver=ctrl.upAxis, driverValue=2 ) # negativeY
        pm.setDrivenKeyframe( ctrl.upVectorX, value= 0, currentDriver=ctrl.upAxis, driverValue=3 ) # positiveZ
        pm.setDrivenKeyframe( ctrl.upVectorY, value= 0, currentDriver=ctrl.upAxis, driverValue=3 ) # positiveZ
        pm.setDrivenKeyframe( ctrl.upVectorZ, value= 1, currentDriver=ctrl.upAxis, driverValue=3 ) # positiveZ
        pm.setDrivenKeyframe( ctrl.upVectorX, value= 0, currentDriver=ctrl.upAxis, driverValue=4 ) # negativeZ
        pm.setDrivenKeyframe( ctrl.upVectorY, value= 0, currentDriver=ctrl.upAxis, driverValue=4 ) # negativeZ
        pm.setDrivenKeyframe( ctrl.upVectorZ, value=-1, currentDriver=ctrl.upAxis, driverValue=4 ) # negativeZ
        pm.setDrivenKeyframe( ctrl.upVectorX, value= 0, currentDriver=ctrl.upAxis, driverValue=5 ) # negativeZ
        pm.setDrivenKeyframe( ctrl.upVectorY, value= 0, currentDriver=ctrl.upAxis, driverValue=5 ) # negativeZ
        pm.setDrivenKeyframe( ctrl.upVectorZ, value= 1, currentDriver=ctrl.upAxis, driverValue=5 ) # negativeZ

        ctrl.setAttr('upVectorX', keyable=False )
        ctrl.setAttr('upVectorY', keyable=False )
        ctrl.setAttr('upVectorZ', keyable=False )

        #
        #
        # base Curve
        #
        #
        crv = pm.curve( n='base_crv', d=3, p=[(0,0,0),(0,0,0),(0,0,0),(0,0,0)], k=[0,0,0,1,1,1] )
        pm.parent( crv, self.doNotTouch_grp )
        crv.it.set(False)
        self.nodes.append(crv)

        # create curve cv clusters
        start_crv_clst = pm.cluster( crv.cv[0], wn=(self.start_T_anim,self.start_T_anim) )[0]
        mid1_crv_clst  = pm.cluster( crv.cv[1], wn=(self.mid1_T_anim, self.mid1_T_anim) )[0]
        mid2_crv_clst  = pm.cluster( crv.cv[2], wn=(self.mid2_T_anim, self.mid2_T_anim) )[0]
        end_crv_clst   = pm.cluster( crv.cv[3], wn=(self.end_T_anim,  self.end_T_anim) )[0]
        self.nodes.extend([start_crv_clst,mid1_crv_clst,mid2_crv_clst,end_crv_clst])

        #
        # 초기위치
        #
        self.start_up_anim.t.set( self.upVector * 10)
        self.end_up_anim  .t.set( self.upVector * 10)
        self.constMe_to_end.t.set( self.aimVector * 10)
        pm.delete( pm.pointConstraint(self.start_T_anim, self.end_T_anim, self.constMe_to_mid)  )
        pm.delete( pm.pointConstraint(self.mid_T_anim, self.start_T_anim, self.mid1_T_anim)  )
        pm.delete( pm.pointConstraint(self.mid_T_anim, self.end_T_anim, self.mid2_T_anim)  )

        #
        #
        # rebuild curve for distribute
        #
        #
        # 커브 리빌드, 익스텐드
        rbdCrv, rbd = pm.rebuildCurve( 
            crv, 
            ch=True, 
            replaceOriginal=False, 
            rebuildType=0, # uniform
            endKnots=1,    # 0 - uniform end knots, 1 - multiple end knots
            keepRange=0,   # 0 - reparameterize the resulting curve from 0 to 1, 1 - keep the original curve parameterization, 2 - reparameterize the result from 0 to number of spans
            keepControlPoints=False, 
            keepEndPoints=True, 
            keepTangents=True, 
            spans=100, 
            degree=3, 
            tol=0.001 
            )

        rdbCrv, extCrv = pm.extendCurve( rbdCrv, cos=0, ch=1, jn=True, rmk=True, rpo=True, 
            distance = 1,
            start=0,         # 0 - end, 1 - start, 2 - both
            extendMethod=0,  # 0 - based on distance, 2 - to a 3D point 
            extensionType=0, # 0 - Linear, 1 - Circular, 2 - Extrapolate  
            )

        rdbCrv.rename('rbdExtnd_crv')
        pm.parent( rdbCrv, self.doNotTouch_grp )
        rdbCrv.it.set(False)

        # extend crv Locator
        crvEnd_loc = pm.spaceLocator(n='extCrvEnd_loc')
        pntOnCrv = pm.PyNode( pm.pointOnCurve( rdbCrv.getShape(), parameter=2.0, ch=True ) )
        pntOnCrv.position >> crvEnd_loc.t
        pm.parent( crvEnd_loc, self.doNotTouch_grp )

        self.nodes.extend([ rbdCrv, rbd,extCrv, crvEnd_loc])

        #
        # Cluster & Constraint
        #
        # constraint Rig
        start_aimConst = pm.aimConstraint( self.end_T_anim, self.start_R_result, aim=self.aimVector, u=self.upVector, wu=self.startWorldUpVector, wut='object', wuo=self.start_up_anim)
        mid_pointConst = pm.pointConstraint( self.start_T_anim, self.end_T_anim, self.constMe_to_mid)
        mid_aimConst   = pm.aimConstraint( self.end_T_anim, self.constMe_to_mid, aim=self.aimVector, u=self.upVector, wu=self.startWorldUpVector, wut='objectrotation', wuo=self.start_R_result)
        end_aimConst   = pm.aimConstraint( crvEnd_loc, self.end_R_result,   aim=self.aimVector, u=self.upVector, wu=self.startWorldUpVector, wut='object', wuo=self.end_up_anim)
        self.nodes.extend([ start_aimConst, mid_pointConst, mid_aimConst, end_aimConst ])

        ctrl.aimVector >> start_aimConst.aimVector
        ctrl.aimVector >> mid_aimConst.aimVector
        ctrl.upVector >> start_aimConst.upVector
        ctrl.upVector >> mid_aimConst.upVector
        ctrl.startWorldUpVector >> start_aimConst.worldUpVector
        ctrl.startWorldUpVector >> mid_aimConst.worldUpVector
        
        #
        #   Locators on Curve
        #
        unit = 1.0 / self.div
        locOnCrvs = []
        for i in range(self.div+1):
            param = unit * i

            #xformOnCrv = pm.group( n='xformOnCrv#', em=True)
            xformOnCrv = pm.spaceLocator( n='xformOnCrv#')

            xformOnCrv.addAttr( 'parameter',        sn='pr',  dv=param, keyable=True )
            xformOnCrv.addAttr( 'turnOnPercentage', sn='top', dv=False, at='bool', keyable=True )
            xformOnCrv.addAttr( 'revRotation',  sn='rot', keyable=True )

            xformOnCrv.it.set(False)
            xformOnCrv.rename( 'xformOnCrv%02d'%i )

            pntOnCrv = pm.PyNode( pm.pointOnCurve( rdbCrv.getShape(), parameter=param, ch=True ) )
            pntOnCrv.turnOnPercentage.set(True)
            pntOnCrv.setAttr('parameter',        keyable=True)
            pntOnCrv.setAttr('turnOnPercentage', keyable=True)
            pntOnCrv.rename( xformOnCrv+'_POC' )

            xformOnCrv.parameter        >> pntOnCrv.parameter
            xformOnCrv.turnOnPercentage >> pntOnCrv.turnOnPercentage
            pntOnCrv.position           >> xformOnCrv.t

            locOnCrvs.append(xformOnCrv)

        pm.parent( locOnCrvs, self.doNotTouch_grp )
        self.nodes.extend( locOnCrvs )

        #
        # distance Rig
        #
        distNodes = []
        for i in range(len(locOnCrvs)-1):
            dist = pm.createNode( 'distanceDimShape' )
            locOnCrvs[i].worldPosition[0]   >> dist.startPoint
            locOnCrvs[i+1].worldPosition[0] >> dist.endPoint
            distNodes.append( dist )

        pm.parent( [dist.getParent() for dist in distNodes], self.doNotTouch_grp )
        self.nodes.extend( [dist.getParent() for dist in distNodes] )

        #
        #
        # Joint
        #
        #
        pm.select(cl=True)
        self.jnts = []
        for i in range(self.div+1):
            self.jnts.append( pm.joint( n='bind%d'%i, p=self.aimVector*i ) )

        if self.stretch:
            # 컨트롤러에 어트리뷰트 추가하고, 리깅까지 마침.
            #ctrl = pm.group( em=True)
            ctrl = self.root_grp
            ctrl.addAttr( 'initialDistance', multi=True, readable=True, indexMatters=False )
            ctrl.addAttr( 'currentDistance', multi=True, readable=True, indexMatters=False )
            ctrl.addAttr( 'scaleOutput',     multi=True, readable=True, indexMatters=False )

            for i in range(len(distNodes)):
                ctrl.initialDistance[i].set( distNodes[i].distance.get() )
                distNodes[i].distance >> ctrl.currentDistance[i]
                
                md = pm.createNode('multiplyDivide')
                md.operation.set(2) # divide    
                ctrl.currentDistance[i] >> md.input1X
                ctrl.initialDistance[i] >> md.input2X
                
                md.outputX >> ctrl.scaleOutput[i]

            for i in range(len( ctrl.scaleOutput.get() )):
                ctrl.scaleOutput[i] >> self.jnts[i].sx

        else:
            for dist, jnt in zip(distNodes, self.jnts[1:]):
                #if ctrl.aimAxis==1: # 아임축이 -일경우.
                md = pm.createNode('multiplyDivide')
                dist.distance   >> md.input1X
                ctrl.aimVectorX >> md.input2X
                md.outputX >> jnt.tx
                
                #else:                
                #    dist.distance >> jnt.tx

        self.nodes.extend(self.jnts)

        #
        #
        # spline IK Handle
        #
        #
        ikHandle, endEff = pm.ikHandle(sol='ikSplineSolver', ccv=False, roc=True, pcv=False, ns=4, sj=self.jnts[0], ee=self.jnts[-1], curve=rdbCrv )
        pm.parent(ikHandle, self.doNotTouch_grp )

        # Enable Twist Controls : start, end Sample OBJ
        sampleObj_start = self.start_R_result
        sampleObj_end   = self.end_R_result

        ikHandle.dTwistControlEnable.set(True)                              # Enable Twist Controls
        ikHandle.dWorldUpType.set(4)                                        # 4:Object Rotation Up (Start/End)
        #sampleObj_start.xformMatrix.connect( foreArm_HDL.dWorldUpMatrix )  # << 요렇게 하면 좆됨
        #sampleObj_end.xformMatrix.connect( foreArm_HDL.dWorldUpMatrixEnd ) # << 요렇게 하면 좆됨
        sampleObj_start.worldMatrix >> ikHandle.dWorldUpMatrix              # << 요렇게 해야함.
        sampleObj_end  .worldMatrix >> ikHandle.dWorldUpMatrixEnd           # << 요렇게 해야함.
        ikHandle.dWorldUpAxis.     set(0)                                   # 0:PositiveY, 1:Positive Z
        ikHandle.dWorldUpVector.   set(self.upVector)
        ikHandle.dWorldUpVectorEnd.set(self.upVector)

        ctrl.aimAxis            >> ikHandle.dWorldUpAxis
        ctrl.startWorldUpVector >> ikHandle.dWorldUpVector
        ctrl.endWorldUpVector   >> ikHandle.dWorldUpVectorEnd

        self.nodes.extend([ikHandle,endEff])
Пример #22
0
def hairJiggle( nodes=[], prefix='jiggle', stretchable=True ):
    '''
    update : 2015-04-27

    #
    # 마야에서 기본으로 같은 기능을 하는 MakeCurvesDynamic 스크립트가 있으나 
    # 리턴 값이 없어 사용이 불가
    # pm.runtime.MakeCurvesDynamic('curve1')
    #
    # makeCurvesDynamic 2 { "0", "1", "0", "1", "0"};
    # $args[0] = surfaceAttach	  If true then connect the hairs to a surface(also selected) basing the uv on the nearest point to the first curve cv 
    # $args[1] = snapToSurface    If true and attaching to a surface then also snap the curve to the surface. 
    # $args[2] = matchPosition	  If true then make the input curve a degree one so resulting output curve exactly matches the position. 
    # $args[3] = createOutCurves  If true then output curves are created 
    # $args[4] = createPfxHair	  If true then hair is created.
    #
    '''    
    if nodes:
        pm.select(nodes)

    # get joints
    joints     = pm.ls(sl=True, type='joint')
    if not joints:
        raise

    # get hairSystem
    hairSystem=None
    hairSystems = pm.ls(sl=True, dag=True, type='hairSystem')    
    if hairSystems:
        hairSystem = hairSystems[-1]
    
    # get nucleus
    nucleus=None
    nucleuss = pm.ls(sl=True, dag=True, type='nucleus')
    if nucleuss:
        nucleus = nucleuss[-1]

    # store current state
    currentToolMode = pm.currentCtx()
    pm.setToolTo( 'selectSuperContext' )
    sel = pm.selected()

    #
    # nucleus
    #
    if not nucleus and not hairSystem:       
        nucleus = pm.createNode( 'nucleus' )
        nucleus.rename( prefix+'_nucleus' )
        pm.PyNode('time1').outTime >> nucleus.currentTime
    
    #
    # hairSystem
    #
    hairSystemTr = None
    if hairSystem:
        hairSystemTr = hairSystem.getParent()

    else:
        hairSystem   = pm.createNode( 'hairSystem' )
        hairSystemTr = hairSystem.getParent()
        hairSystemTr.rename( prefix+'_hairSys' )

        # 새로 생성된 헤어와 뉴클리어스 연결 << connectAttr nextAvailable플래그로 해결해보려했으나.. 복잡.. 멜을 사용하는게 제일 편함.
        #pm.PyNode('time1').outTime >> hairSystem.currentTime
        #hairSystem.currentState  >> nucleus.inputActive[0]
        #hairSystem.startState    >> nucleus.inputActiveStart[0]
        #nucleus.outputObjects[0] >> hairSystem.nextState
        #nucleus.startFrame       >> hairSystem.startFrame

        # 새로 생성된 헤어와 뉴클리어스 연결
        pm.mel.assignNSolver( nucleus )

        # default Value
        hairSystem.active.set( True )

    #
    # follicle 생성
    #
    follicle   = pm.createNode( 'follicle' )
    follicleTr = follicle.getParent()
    follicleTr.rename( prefix+'_follicle' )

    # follicle 위치조정
    pm.delete( pm.pointConstraint( joints[0], follicleTr ) )
    pm.delete( pm.orientConstraint( joints[0], follicleTr, offset=(0, 90, 0) ) )
    
    # follicle이 조인트, parent를 따라가도록설정
    # Start Joint의 Parent가 없으면 현재 Start에 페어런트 검.
    parent = joints[0].getParent()
    const = None
    if parent:
        const = pm.parentConstraint( parent, follicleTr, mo=True)
    else:
        const = pm.parentConstraint( joints[0], follicleTr, mo=True)

    # 기본값
    follicle.restPose.set(1)       # same as start
    follicle.startDirection.set(1) # start Curve base
    follicle.degree.set(2)
    follicle.clumpWidth.set(5)     # 폴리클 디스플레이 크기

    #
    # curve Setting
    #
    # startCurve 생성
    startCurve = jntToCrv( joints, degree=3, ep=True )
    startCurve.setParent( follicleTr )
    startCurve.rename( prefix+'_startCurve' )

    # outputCurve 생성
    outputCurveShape = pm.createNode( 'nurbsCurve' )
    outputCurve      = outputCurveShape.getParent()
    outputCurve.rename( prefix+'_outputCurve' )

    #
    # DG 
    #
    settableNum = 0
    while True:    
        if hairSystem.inputHair[ settableNum ].isSettable():
            break
        settableNum +=1
    startCurve.getShape().worldSpace     >> follicle.startPosition
    follicle.outHair                     >> hairSystem.inputHair[ settableNum ]
    hairSystem.outputHair[ settableNum ] >> follicle.currentPosition    
    pm.connectAttr( follicle+'.outCurve', outputCurveShape+'.create' ) # follicle.outCurve >> outputCurveShape.create    # 이부분에서 다음 경고 발생:  Warning: pymel.core.general : Could not create desired MFn. Defaulting to MFnDagNode. # 

    #
    #
    # ikHandle
    #
    HDL, EFF = pm.ikHandle( solver='ikSplineSolver', startJoint=joints[0], endEffector=joints[-1], createCurve=False, curve=outputCurveShape, parentCurve=False )
    HDL.rename( prefix+'_HDL')
    EFF.rename( prefix+'_EFF')

    #
    #
    # 그루핑
    #
    rigGrp = pm.group(n=prefix+'_jointChainRig_grp#',em=True)
    rigGrp.v.set(False)
    pm.parent(follicleTr, HDL, outputCurve, rigGrp)

    #
    #
    # 스트레치 세팅
    #
    if stretchable:
        #
        # 커브 리빌드, 익스텐드
        #
        rdbCrv, rbd = pm.rebuildCurve( 
            outputCurveShape, 
            ch=True, 
            replaceOriginal=False, 
            rebuildType=0, # uniform
            endKnots=1,    # 0 - uniform end knots, 1 - multiple end knots
            keepRange=0,   # 0 - reparameterize the resulting curve from 0 to 1, 1 - keep the original curve parameterization, 2 - reparameterize the result from 0 to number of spans
            keepControlPoints=False, 
            keepEndPoints=True, 
            keepTangents=True, 
            spans=len(joints), 
            degree=3, 
            tol=0.001 
            )

        #
        #   Locators on Curve
        #
        unit = 1.0 / (len(joints)-1)
        locOnCrvs = []
        for i in range(len(joints)):
            param = unit * i

            xformOnCrv = pm.spaceLocator( n='xformOnCrv#')

            xformOnCrv.addAttr( 'parameter',        sn='pr',  dv=param, keyable=True )
            xformOnCrv.addAttr( 'turnOnPercentage', sn='top', dv=False, at='bool', keyable=True )
            xformOnCrv.addAttr( 'revRotation',  sn='rot', keyable=True )

            xformOnCrv.it.set(False)
            xformOnCrv.rename( 'xformOnCrv%02d'%i )

            pntOnCrv = pm.PyNode( pm.pointOnCurve( rdbCrv.getShape(), parameter=param, ch=True ) )
            pntOnCrv.turnOnPercentage.set(True)
            pntOnCrv.setAttr('parameter',        keyable=True)
            pntOnCrv.setAttr('turnOnPercentage', keyable=True)
            pntOnCrv.rename( xformOnCrv+'_POC' )

            xformOnCrv.parameter        >> pntOnCrv.parameter
            xformOnCrv.turnOnPercentage >> pntOnCrv.turnOnPercentage
            pntOnCrv.position           >> xformOnCrv.t

            locOnCrvs.append(xformOnCrv)

        #
        # distance Rig
        #
        distNodes = []
        for i in range(len(locOnCrvs)-1):
            dist = pm.createNode( 'distanceDimShape' )
            locOnCrvs[i].worldPosition[0]   >> dist.startPoint
            locOnCrvs[i+1].worldPosition[0] >> dist.endPoint
            distNodes.append( dist )

        #
        # ik핸들 커브 변경
        #
        pm.ikHandle( HDL, e=True, curve=rdbCrv )

        #
        # connect To Joint
        #
        for dist, jnt in zip(distNodes, joints[1:]):
            dist.distance >> jnt.tx

        #
        # 그루핑
        #
        pm.parent(rdbCrv, locOnCrvs, [dist.getParent() for dist in distNodes], rigGrp)
        
    #
    #
    # restore state
    #
    pm.setToolTo( currentToolMode )
    if sel:
        pm.select(sel)
    else:
        pm.select(cl=True)
Пример #23
0
def crvToJnt( objs=[], div=None, ep=True ):
    '''
    update : 2015-04-27

    curve, upMesh 순으로 선택하고 실행
    div 를 명시하면 일정간격의 조인트를 얻음.

    import rig.joint as jnt
    jnt.crvToJnt()
    jnt.crvToJnt(ep=False)         # 해당 없음. 커브 cv 위치에 조인트가 생김
    jnt.crvToJnt(div=10)
    jnt.crvToJnt(ep=True)          # 해당 없음. 커브 ep 위치에 조인트가 생김
    jnt.crvToJnt(ep=False)         # 해당 없음. 커브 cv 위치에 조인트가 생김
    jnt.crvToJnt(div=10, ep=True)  # 해당 없음. 커브 cv 위치에 조인트가 생김
    jnt.crvToJnt(div=10, ep=False) # 해당 없음. 커브 cv 위치에 조인트가 생김

    '''
    # args
    if objs:
        pm.selec(objs)
    objs = pm.selected()
    if not objs:
        raise
   
    curves  = [pm.PyNode(c) for c in pm.filterExpand(sm=9) ]
    if not curves:
        raise

    upMeshs = []
    if pm.filterExpand(sm=12):    
        upMeshs = [pm.PyNode(c) for c in pm.filterExpand(sm=12) ] # 업축으로 사용할 메쉬

    node = curves[-1]
    nodeType = node.nodeType()
    #cv = True
    #ep = True

    transform = None
    crvShape  = None
    if nodeType == 'nurbsCurve':
        crvShape  = node
        transform = crvShape.getParent()
    elif nodeType == 'transform':
        transform = node
        crvShape  = transform.getShapes( type='nurbsCurve' )[0]

    if div:
        rebCrv, rebuild = pm.rebuildCurve( crvShape, ch=True, rpo=False, rt=4, end=1, kr=0, kcp=0, kep=1, kt=0, s=4, d=3, tol=0.001 ) # curvature type
        transform = rebCrv
        crvShape  = transform.getShapes( type='nurbsCurve' )[0]

    # 위치값 챙김.
    p=[]
    if div:
        if ep:
            for i in range(div+1):
                # 커브를 일정하게 나눈 위치 값을 가져옴
                p.append( pm.pointOnCurve( crvShape, turnOnPercentage=True, parameter=(1.0/div)*i ) )
        else:
            rebuild.rebuildType.set(0) # uniform
            rebuild.spans.set(div+1)
            for i in range( len( rebCrv.getCVs() ) ):
                p.append( crvShape.cv[i].getPosition() )

    else:
        if ep:
            # editPoint의 위치값을 가져옴
            for i in range( crvShape.numEPs() ):
                p.append( pm.xform( crvShape.ep[i], q=True, ws=True, t=True) )
        else:
            # cv의 위치값을 가져옴
            for i in range( len( crvShape.getCVs() ) ):
                p.append( crvShape.cv[i].getPosition() )

    if div:
        pm.delete( transform )

    JNTs = []
    pm.select(cl=True)
    for pos in p:
        JNTs.append( pm.joint( p=pos) )

    # 조인트 오리엔트 조정: 메쉬의 가장 가까운 점의 노말을 조인트의 up으로 설정
    if upMeshs:
        for jnt in JNTs:
            parentJnt = jnt.getParent()
            if parentJnt:
                # point에서 가장 가까운 Vertex의 Normal을 up으로 설정
                pos   = parentJnt.getTranslation( ws=True)
                vtx   = getClosestVertexOnMesh( upMeshs[0], pos )
                pos   = vtx.getPosition()
                norm  = vtx.getNormal()
                upPos = pos + norm * 1000000 # 노말 위치가 가까우면 방향이 틀어져 버림.. 그래서 큰 수를 곱함.

                upLoc = pm.spaceLocator(n='parentJnt_upLoc#')
                upLoc.t.set( upPos )

                jntOrient( [parentJnt, jnt, upLoc] )
                #pm.joint( parentJnt, edit=True, zso=True, oj='xyz', sao='yup' )
                pm.delete( upLoc )

    else:
        for jnt in JNTs:
            parentJnt = jnt.getParent()
            if parentJnt:
                up = pm.spaceLocator()

                grandParent = parentJnt.getParent()
                if grandParent:
                    pm.delete( pm.parentConstraint( grandParent, up ) )                    
                else:
                    pm.delete( pm.parentConstraint( parentJnt, up ) )

                jntOrient( [parentJnt, jnt, up], worldUpType='objectrotation' )
                pm.refresh()
                pm.select(jnt)
                pm.delete(up)

    # 끝 조인트 오리엔트 조정
    pm.joint( JNTs[-1], edit=True, oj='none' )

    pm.select( JNTs )

    return JNTs
Пример #24
0
def buildSplineNeck(start, end, name='', matchEndOrient=False, endOrient=util.EndOrient.TRUE_ZERO, curve=None, duplicateCurve=True, groupName='', controlSpec={} ):
    '''
    Makes a spline with a middle control point constrained between the endpoints.
    
    ..  todo::
        * Might want to make the end the main control to treat it more consistently
            with other IK, where the main is the end of the chain.
    '''
    if not name:
        name = simpleName(start)
        
    container = group(em=True, p=lib.getNodes.mainGroup(), n=name + "_controls")
    container.inheritsTransform.set(False)
    container.inheritsTransform.lock()
    
    controlChain = util.dupChain(start, end)
    controlChain[0].setParent(container)
    
    # If the chain is mirrored, we need to reorient to point down x so the
    # spline doesn't mess up when the main control rotates
    if controlChain[1].tx.get() < 0:
        # Despite aggresive zeroing of the source, the dup can still end up slightly
        # off zero so force it.
        for jnt in controlChain:
            jnt.r.set(0, 0, 0)
        joint( controlChain[0], e=True, oj='xyz', secondaryAxisOrient='yup', zso=True, ch=1)
        joint(controlChain[-1], e=True, oj='none')
    
    # Since the spline might shift the joints, make joints at the original pos
    # to constrain to.  This lets us make controls agnostically since we don't.
    # need to maintain offset
    offsetChain = util.dupChain(start, end, '{0}_offset')

    if curve:
        if duplicateCurve:
            crv = duplicate(curve)[0]
        else:
            crv = curve
        mainIk, _effector = ikHandle( sol='ikSplineSolver',
            sj=controlChain[0],  # noqa e128
            ee=controlChain[-1],
            ccv=False,
            pcv=False)
        crv.getShape().worldSpace[0] >> mainIk.inCurve

    else:
        mainIk, _effector, crv = ikHandle( sol='ikSplineSolver',
            sj=controlChain[0],  # noqa e128
            ee=controlChain[-1],
            ns=1)
        
    constraints = util.constrainAtoB( util.getChain(start, end)[:-1], offsetChain[:-1], mo=False)
    
    hide(mainIk, crv, controlChain[0])
    parent( mainIk, crv, container )
    
    startJnt = duplicate( start, po=True )[0]
    startJnt.setParent(w=True)
    endJnt = duplicate( end, po=True )[0]
    endJnt.setParent(w=True)
    
    midCtrl = controllerShape.build( name + "_Mid", controlSpec['middle'], controllerShape.ControlType.SPLINE )
    core.dagObj.lockScale(midCtrl)
    midPoint = pointOnCurve( crv, pr=0.5, p=True, top=True )
    midChain = findClosest(midPoint, util.getChain(start, end))
    core.dagObj.matchTo(midCtrl, midChain)
    midZero = core.dagObj.zero(midCtrl)
    midZero.t.set( midPoint )
    
    midJoint = joint(None)
    midJoint.setParent(midCtrl)
    midJoint.t.set(0, 0, 0)
    midJoint.r.set(0, 0, 0)
    midZero.setParent( container )
    
    # Setup mid controller spaces
    pointSpace = spaceLocator()
    pointSpace.rename('midPoint_{0}'.format(start))
    pointSpace.setParent(container)
    core.dagObj.moveTo(pointSpace, midCtrl)
    pointConstraint( startJnt, endJnt, pointSpace, mo=True )
    hide(pointSpace)
    space.add( midCtrl, pointSpace, spaceName='midPoint')
    
    childSpace = spaceLocator()
    childSpace.rename('midChild_{0}'.format(start))
    childSpace.setParent(container)
    core.dagObj.matchTo(childSpace, midCtrl)
    parentConstraint( startJnt, endJnt, childSpace, mo=True )
    hide(childSpace)
    space.add( midCtrl, childSpace, spaceName='midChild')
    
    pntRotSpace = spaceLocator()
    pntRotSpace.rename('midPntRot_{0}'.format(start))
    pntRotSpace.setParent(container)
    core.dagObj.matchTo(pntRotSpace, midCtrl)
    pointConstraint( startJnt, endJnt, pntRotSpace, mo=True )
    orientConstraint( startJnt, endJnt, pntRotSpace, mo=True )
    hide(pntRotSpace)
    space.add( midCtrl, pntRotSpace, spaceName='midPointRot')
    
    aimer = util.midAimer(startJnt, endJnt, midCtrl)
    aimer.setParent(container)
    hide(aimer)
    space.add( midCtrl, aimer, spaceName='mid_aim')
    
    # Build Start and end controllers
    
    skinCluster(startJnt, endJnt, midJoint, crv, tsb=True)
    
    startCtrl = controllerShape.build( name + '_Start', controlSpec['start'], controllerShape.ControlType.SPLINE )
    core.dagObj.lockScale(startCtrl)
    core.dagObj.matchTo( startCtrl, startJnt )
    startSpace = core.dagObj.zero(startCtrl)
    startSpace.setParent(container)
    
    endCtrl = controllerShape.build( name + '_End', controlSpec['main'], controllerShape.ControlType.SPLINE )
    core.dagObj.lockScale(endCtrl)
    
    #core.dagObj.moveTo( endCtrl, end )
    #core.dagObj.zero( endCtrl ).setParent( container )
    
    """
    ORIGINAL matchEndOrient code
    if not matchEndOrient:
        core.dagObj.matchTo( endCtrl, endJnt )
    else:
        print( 'JUST MOVING' )
        core.dagObj.moveTo( endCtrl, endJnt )
    
    core.dagObj.zero(endCtrl).setParent(container)
    
    if matchEndOrient:
        rot = determineClosestWorldOrient(end)
        endCtrl.r.set( rot )
        storeTrueZero(endCtrl, rot)
    """
    
    # Begin new endOrient enum code (replacing matchEndOrient)
    # matchEndOrient=False == TRUE_ZERO
    # matchEndOrient=True  == JOINT
    if endOrient == util.EndOrient.WORLD:
        core.dagObj.moveTo( endCtrl, endJnt )
        
    elif endOrient == util.EndOrient.JOINT:
        core.dagObj.matchTo( endCtrl, endJnt )
        
    elif endOrient == util.EndOrient.TRUE_ZERO:
        core.dagObj.moveTo( endCtrl, endJnt )
    
    core.dagObj.zero(endCtrl).setParent(container)
    
    if endOrient == util.EndOrient.TRUE_ZERO:
        rot = util.determineClosestWorldOrient(end)
        endCtrl.r.set( rot )
        util.storeTrueZero(endCtrl, rot)
    
    # End new endOrient enum code
    
    util.makeStretchySpline( endCtrl, mainIk )
    
    # Constraint to endJnt, which has the same orientation as end instead of endCtrl
    endJnt.setParent( endCtrl )
    endConstraints = util.constrainAtoB( [end], [endJnt] )
    
    util.driveConstraints( constraints, endConstraints )
    hide( startJnt, endJnt, midJoint )
    
    space.addWorld(endCtrl)
    space.add( endCtrl, start.getParent(), 'parent' )
    space.add( endCtrl, startCtrl, 'start' )
    
    space.add( startCtrl, start.getParent(), 'parent' )
    
    startJnt.setParent( startCtrl )
    
    orientConstraint( endCtrl, controlChain[-1], mo=True )
    
#    ctrls = addControlsToCurve('Blah', crv)

#    startCtrl.setParent( ctrls[0] )
#    endCtrl.setParent( ctrls[3] )
    
#    parentConstraint( ctrls[0], midCtrl, ctrls[1], mo=True )
#    parentConstraint( ctrls[3], midCtrl, ctrls[2], mo=True )
    
    #hide( ctrls[1:3] )
    
    
    # Setup matchers for easy ik switching later
    endMatch = util.createMatcher(endCtrl, end)
    endMatch.setParent(container)
    
    startMatch = util.createMatcher(startCtrl, start)
    startMatch.setParent(container)
    
    distances = {}
    jointChain = util.getChain(start, end)
        
    for j in jointChain:
        distances[ core.dagObj.distanceBetween(j, midCtrl) ] = j
    
    for dist, j in sorted(distances.items()):
        # Make a matcher here
        midMatch = util.createMatcher(midCtrl, j)
        midMatch.setParent(container)
        break
    
    # Setup the endControl as the leader
    
    endCtrl = nodeApi.RigController.convert(endCtrl)
    endCtrl.container = container
    endCtrl.subControl['mid'] = midCtrl
    endCtrl.subControl['start'] = startCtrl

    # Since the chain might have reversed, use the control chain for the twist axes.
    util.advancedTwist(controlChain[0], controlChain[1], startCtrl, endCtrl, mainIk)
    # Since adding the advanced twist can slightly alter things (sometimes),
    # put the offset joints in as the last step
    for ctrl, offset in zip(controlChain, offsetChain):
        offset.setParent(ctrl)
    
    return endCtrl, constraints
Пример #25
0
def jointChain( joints=[], prefix='chain', ctrlNum=3 ):
    if joints:
        pm.select(joints)
    joints = pm.ls(sl=True, type='joint')
    if not joints:
        raise

    if ctrlNum < 2:
        raise
    
    jointNum = len(joints)
    degree = 3
    if ctrlNum == 3:
        degree = 2    

    # =============================
    #
    #  컨트롤러 
    #
    # =============================
    crv = jntToCrv(joints, degree=3, ep=True )
    
    ctrlRbd_crv, ctrlRbd_rbd = pm.rebuildCurve( crv, 
        ch=True, 
        replaceOriginal=False, 
        rebuildType=0, 
        endKnots=1, 
        keepRange=0, 
        keepControlPoints=0, 
        keepEndPoints=1, 
        keepTangents=0, 
        spans=ctrlNum-degree, 
        degree=degree,
        tol=0.01
        )

    # create curve cv clusters    

    anims = []

    pm.select( ctrlRbd_crv.cv )    
    for cv in pm.ls(sl=True, fl=True):
        anims.append( pm.cluster( cv )[0] )
        #anim = pm.cluster( cv, wn=(self.start_T_anim,self.start_T_anim) )[0]

    #
    #
    # ikHandle
    #
    HDL, EFF = pm.ikHandle( solver='ikSplineSolver', startJoint=joints[0], endEffector=joints[-1], createCurve=False, curve=ctrlRbd_crv, parentCurve=False )
    HDL.rename( prefix+'_HDL')
    EFF.rename( prefix+'_EFF')

    #
    #
    # 그루핑
    #
    rigGrp = pm.group(n=prefix+'_jointChain_grp#',em=True)
    rigGrp.v.set(False)
    pm.parent( HDL, crv, ctrlRbd_crv, rigGrp)


    # =============================
    #
    #  spline IK, Stretch & Distribute Joint
    #
    # =============================
    #
    # 커브 리빌드, 익스텐드
    #
    rdbCrv, rbd = pm.rebuildCurve( 
        ctrlRbd_crv, 
        ch=True, 
        replaceOriginal=False, 
        rebuildType=0, # uniform
        endKnots=1,    # 0 - uniform end knots, 1 - multiple end knots
        keepRange=0,   # 0 - reparameterize the resulting curve from 0 to 1, 1 - keep the original curve parameterization, 2 - reparameterize the result from 0 to number of spans
        keepControlPoints=False, 
        keepEndPoints=True, 
        keepTangents=True, 
        spans=len(joints), 
        degree=3, 
        tol=0.001 
        )

    #
    #   Locators on Curve
    #
    unit = 1.0 / (len(joints)-1)
    locOnCrvs = []
    for i in range(len(joints)):
        param = unit * i

        xformOnCrv = pm.spaceLocator( n='xformOnCrv#')

        xformOnCrv.addAttr( 'parameter',        sn='pr',  dv=param, keyable=True )
        xformOnCrv.addAttr( 'turnOnPercentage', sn='top', dv=False, at='bool', keyable=True )
        xformOnCrv.addAttr( 'revRotation',  sn='rot', keyable=True )

        xformOnCrv.it.set(False)
        xformOnCrv.rename( 'xformOnCrv%02d'%i )

        pntOnCrv = pm.PyNode( pm.pointOnCurve( rdbCrv.getShape(), parameter=param, ch=True ) )
        pntOnCrv.turnOnPercentage.set(True)
        pntOnCrv.setAttr('parameter',        keyable=True)
        pntOnCrv.setAttr('turnOnPercentage', keyable=True)
        pntOnCrv.rename( xformOnCrv+'_POC' )

        xformOnCrv.parameter        >> pntOnCrv.parameter
        xformOnCrv.turnOnPercentage >> pntOnCrv.turnOnPercentage
        pntOnCrv.position           >> xformOnCrv.t

        locOnCrvs.append(xformOnCrv)

    #
    # distance Rig
    #
    distNodes = []
    for i in range(len(locOnCrvs)-1):
        dist = pm.createNode( 'distanceDimShape' )
        locOnCrvs[i].worldPosition[0]   >> dist.startPoint
        locOnCrvs[i+1].worldPosition[0] >> dist.endPoint
        distNodes.append( dist )

    #
    # ik핸들 커브 변경
    #
    pm.ikHandle( HDL, e=True, curve=rdbCrv )

    #
    # connect To Joint
    #
    for dist, jnt in zip(distNodes, joints[1:]):
        dist.distance >> jnt.tx

    #
    # 그루핑
    #
    pm.parent(rdbCrv, locOnCrvs, [dist.getParent() for dist in distNodes], rigGrp)
Пример #26
0
def twoPointArcRig( prefix='arc1' ):
    '''
    리깅된 아크 커브를 생성한다.
    a = createTowPointArcRig( 'arc_L' )
    '''
    pointA = pm.spaceLocator()
    pointB = pm.spaceLocator()
    arcCenter = pm.spaceLocator()
    arcCenter.it.set(False)
    center = pm.spaceLocator()
    up = pm.spaceLocator()
    pointA.tx.set(10)
    pointB.tx.set(-10)
    up.ty.set(5)
    
    makeArc = pm.createNode('makeTwoPointCircularArc')
    makeArc.radius.set(20)
    makeArc.directionVector.set(0,1,0)
    
    pointA.worldPosition[0] >> makeArc.pt1
    pointB.worldPosition[0] >> makeArc.pt2

    # upVector
    minus = pm.createNode( 'plusMinusAverage' )
    up.worldPosition[0] >> minus.input3D[0]
    center.worldPosition[0] >> minus.input3D[1]
    minus.operation.set(2) # minus
    minus.output3D >> makeArc.directionVector
    
    pm.select(cl=True)
    crv = pm.group(em=True)
    crv.it.set(False)
    crv.addAttr('radius', keyable=True)
    crv.radius.set(20)
    crvShape = pm.createNode('nurbsCurve', p=crv)
    makeArc.outputCurve >> crvShape.create
    crv.radius >> makeArc.radius
    
    # Point On Curve Node
    poc = pm.PyNode( pm.pointOnCurve( crv, pr=0.5, ch=True ) )
    poc.curvatureCenter >> arcCenter.t

    # Locator on Curve 
    locOnCrv = pm.spaceLocator()
    locOnCrv.it.set(False)
    locOnCrv.addAttr('parameter', keyable=True, dv=0.5, min=0, max=1 )
    poc.p >> locOnCrv.t
    poc.turnOnPercentage.set(True)    
    locOnCrv.parameter >> poc.parameter
    
    # Group
    grp = pm.group( em=True )
    pm.parent( locOnCrv, pointA, pointB, arcCenter, up, center, crv, grp )
    
    # Rename
    pointA.rename( prefix + '_pt1')
    pointB.rename( prefix + '_pt2')
    arcCenter.rename( prefix + '_arcCenter')
    crv.rename( prefix + '_crv')
    grp.rename( prefix + '_grp')
    poc.rename( prefix + '_poc')
    makeArc.rename( prefix + '_makeArc')
    locOnCrv.rename( prefix + '_locOnCrv')   
    up.rename( prefix + '_up')
    center.rename( prefix + '_center')

    # Visible
    center.v.set(False)
    up.v.set(False)
    arcCenter.v.set(False)
    
    return [grp, crv, locOnCrv, pointA, pointB, arcCenter, poc, up, center, makeArc ]