示例#1
0
def snapCurveToClosestVertices(crv, geo):
    ''' Find closest Vertex on geo for each cv on curve and snaps to it
    Args:
        crv (transform): The curve which shall be snapped
        geo (transform): The geo as the base for the search
    Returns: 
         True if no error
    '''
    crvShape = pm.PyNode(crv).getShape()
    geoShape = pm.PyNode(geo).getShape()
    
    numcvs = crvShape.numCVs()
    
    
    for curvePoint in range(numcvs):
        # find closest vertex
        tempLoc = pm.spaceLocator(n='tempLoc')
        pm.xform(tempLoc, t=pm.pointPosition(crvShape.cv[curvePoint]))
        closestVertex = getClosestVertex(tempLoc, geo)
        
        # move curvepoint to closest vertex
        pm.xform(tempLoc, t=pm.pointPosition(closestVertex))
        pm.move(crvShape.cv[curvePoint], pm.pointPosition(closestVertex))
        
        pm.delete(tempLoc)
    return True
def set_pivots_to_bottom():
    """
    Usage:
        set_pivots_to_bottom()
    """
    for obj in pm.ls(sl=True):
        pos = pm.pointPosition(obj.rotatePivot, w=True)
        center = pm.pointPosition(obj.boundingBox, w=True)
示例#3
0
    def meke_mouth_line(self, *args) :
        
        # 現在の口の形を出力
        try :
            pm.delete(pm.PyNode("pinEditor_mouth_line"))
        except :
            pass
        cv = [pm.pointPosition(self.base_transform.vtx[i]) for i in self.pinIndexList ]
        cur = pm.curve(p = cv, n="pinEditor_mouth_line", d = 1)  

        """
        cur = 
        vec     = pm.dt.Vector([vecs[0], vecs[1], vecs[2]])
        source  = pm.dt.Point([sources[0], sources[1], sources[2]])
        target  = source + vec
        atom    = vec / 6
        opt     = pm.dt.Vector([0.0, 0.0, 1.0])
        unit    = vec.cross(opt)
        unit    = unit * atom.length() / unit.length()
        p1      = target - atom + unit
        p2      = target - atom - unit 
        cvList  = [source, target, p1, target, p2]
        cv      = [ [i[0],i[1],i[2]] for i in cvList]
        #print test
        cur     = pm.curve( p = cv, n=test, d = 1 )   
        """

        # 現在のピン(移動前)を出力
        for i in self.sph_befor_move :
            print i
            try :
                pm.delete(i)
                print "deleted"
            except :
                pass

        
        self.sph_befor_move = [ 
                    tools.makeSphere(
                        pm.pointPosition(self.base_transform.vtx[i])
                        ) for i in self.pinIndexList 
                    ] 

        """
        # 現在のピン(移動後)を出力
        temp = [ tools.makeSphere( 
                        curvetool.getCurvePoint(
                                        self.cur, 
                                        [i]
                        )[0]
                )       
                for i in self.paramList ]
        
        self.sph_after_move = [i[0] for i in temp]
        """
        return cur 
 def test_wrap_deforms_target_mesh(self):
     source_cube, target_cube = [self.create_cube() for _ in range(2)]
     initial_target_vert_pos = pm.pointPosition(target_cube.vtx[0])
     wrap_node, base_shape = deformerutils.create_wrap_deformer(
         source_cube, target_cube)
     self.scene_nodes.extend((wrap_node, base_shape))
     pm.move(source_cube.vtx[0], (1, 1, 1))
     target_vert_pos = pm.pointPosition(source_cube.vtx[0])
     result_target_vert_post = pm.pointPosition(target_cube.vtx[0])
     self.assertNotEqual(initial_target_vert_pos, result_target_vert_post)
     self.assertEqual(target_vert_pos, result_target_vert_post)
示例#5
0
def lap(myface, pinID_comp, curPosList_comp) :
    
    if pinID_comp == -1 : 
        pm.warning(u"最適化を用いたブレンドシェイプを実行してください.")
        return

    # ------- ブレンドシェイプをフリーズ ----------
    tools.freeze_blend_shape(
                    myface.obj, 
                    myface.blender, 
                    myface.defaultShape)  # 重い
    # --------------------------------------------

    
    #temp
    print "len", len(curPosList_comp)
    vtxPos = [pm.pointPosition(myface.obj.vtx[i]) for i in pinID_comp]
    print "len", len(vtxPos),  " ", len(vtxPos[0])
    mv = [tools.makeVector([curPosList_comp[i][j]-vtxPos[i][j] for j in range(3)], vtxPos[i]) for i in range(len(curPosList_comp))]
    print len(mv)
    

    print "id : ", pinID_comp
    limitLap.do_lap_limit(myface, pinID_comp, 12, curPosList_comp, debug = True)

    return 1
示例#6
0
def build(crv, name=''):
    '''
    creates a Marco Giordano style eyelid rig

    '''
    params = [curve.getClosestPointOnCurve(crv=crv, point = pmc.pointPosition(cv)) for cv in crv.cv[:]]

    mainGrp = pmc.group(empty=1, name='%s_grp' % name)
    baseGrp = pmc.group(empty=1, name='%s_base_grp' % name)
    baseGrp.setParent(mainGrp)

    mps = curve.nodesAlongCurve(crv=crv.name(), numNodes=len(params), name=name)

    for index in range(len(params)):
        mp = common.getPyNode(mps['mpNodes'][index])
        mp.uValue.set(params[index])
        mp.fractionMode.set(0)

        grp = common.getPyNode(mps['grps'][index])

        aimGrp = pmc.group(empty=1, name='%s_%s_aim_grp' % (name, str(index)))
        aimGrp.setParent(baseGrp)
        con = pmc.aimConstraint(grp, aimGrp, mo=0, wut=2, wuo=baseGrp.name())

        pmc.select(aimGrp, r=1)
        j = pmc.joint(name='%s_%s_jnt' % (name, str(index)))
        j.tx.set(10)
示例#7
0
def rig_makeJointsAlongCurve(module, curve, numJoints):
	'''Create joints along a curve in the same direction as the curve
	Args:
		module (string): what the name of the joint module should be
		curve (pm.PyNode): the curve transform to be used
		numJoints (int): the number of joints to be created
	Returns:
		[pm.nt.Joint]: list of joints
	Usage:
		rig_makeJointsAlongCurve("petalA", pm.ls(sl=True)[0], 15)
		rig_makeJointsAlongCurve("seatbeltDrive", pm.ls(sl=True)[0], 160)
	'''
	#Creating a curve between them
	#pm.curve (d=1, n= 'curve_body',  p=[(startPos[0],startPos[1],startPos[2]),(endPos[0],endPos[1],endPos[2])])
	curve = pm.duplicate(curve)[0]
	pm.rebuildCurve(curve, ch=0, rpo=1, rt=0, end=1, kr=1, kcp=0, kep=1, kt=0, s=numJoints, d=1, tol=0.01)
	#Evenly spacing joints according to the curve
	joints=[]
	for k in range(0,numJoints+1):
		cvPos = pm.pointPosition( '%s.cv[%s]'%(curve,str(k)), w = 1)
		joints.append( pm.joint( n = '%s_0%s_JNT'%(module, str(k+1)), p = cvPos) )

	#Set the rotation order    
	for joint in joints[:-1]:
		joint.secondaryAxisOrient('yup', oj='xyz')
	pm.delete(curve)
	return joints
示例#8
0
    def __init__(self, myface) :
        
        self.myface  = myface
        self.base    = pm.PyNode(self.myface.name)
        self.cur     = myface.curve

        # 口角の位置に球を生成
        self.pinIndexList = myface.parts_vertex[myface.context_parts]
        self.paramList    = myface.param_list
        self.constPinIndexList = self.pinIndexList

        self.mouthcorner_pos  = [pm.pointPosition(self.base.vtx[i]) for i in [self.pinIndexList[0], self.pinIndexList[5]]]
        self.curve_corner_pos = curvetool.getCurvePoint(self.cur, [self.paramList[0],self.paramList[5]])


        self.reflesh_viewer()

        self.ctx             = "paramSetCtx"
        self.make_my_drag_context()
        self.paramProgress   = 0.0
        self.paramProgress_befor = 0.0

        # 現在何番目のピンを操作しているのか
        self.no_of_editing_pin = 0
        self.no_of_editing_pin_max = 1

        pm.setToolTo(self.ctx)
示例#9
0
def point_2D_test():

    distance = 100

    p = pm.pointPosition()
    #camName   =  tools.getCamFromModelPanel()
    cam       =  pm.PyNode("persp")
    c = pm.getAttr(cam.translate)

    pm.move(cam, -1,0,0,r = 1, os = 1, wd = 1)
    moved = pm.getAttr(cam.translate)
    
    pm.move(cam, 1,0,0,r = 1, os = 1, wd = 1)
    scr_x = moved - c

    
    pm.move(cam, 0,-1,0,r = 1, os = 1, wd = 1)
    moved = pm.getAttr(cam.translate)
    pm.move(cam, 0,1,0,r = 1, os = 1, wd = 1)
    scr_y = moved - c
    
    scr_z = scr_x.cross(scr_y)

    scr = c - (distance*scr_z)

    print "axis " , scr_x, scr_y
    
    ret = projection_2D(p,c,scr,scr_x,scr_y)
    print "2D Position : ", ret
示例#10
0
    def rebuildCurve(self, spans):
        # Rebuild the curveNode
        pm.rebuildCurve(self.curveNode, rpo = 1, rt = 0, end = 1, kr = 0, kcp = 0,
                        kep = 1, kt = 0, s = spans, d = 3, tol = 0.01)
        del self._cvPositions[:]

        for j in range (0, self.numCVs):
            self._cvPositions.append(pm.pointPosition(self.curveNode.cv[j], w = 1))
示例#11
0
    def disperse(self, *args):
        """Called when the disperse button is pressed"""
        if self.sourceObj == None or self.targetObjs == None:
            pm.confirmDialog(t='Error', b=['OK'],
                m='Please make sure source and targets are selected.')
            return

        # get copy number
        copyNum = self.copyNum.getValue()
        copyNum = min(copyNum, len(self.vertIndexList))

        # get rotation
        rotationMode = self.rotationModeRC.getSelect()
        rotationMode = pm.control(rotationMode, q=True, fpn=True)
        if rotationMode == self.rotBtnRand:
            origRot = pm.xform(self.sourceObj, ro=True, q=True)
            rotRange = self.rotationRange.getValue()

        # get scale
        scaleMode = self.scaleModeRC.getSelect()
        scaleMode = pm.control(scaleMode, q=True, fpn=True)
        if scaleMode == self.scaleBtnRand:
            scaleRange = self.scaleRange.getValue()

        # make copies
        randVertIndexList = random.sample(self.vertIndexList, copyNum)
        for i in randVertIndexList:
            newObj = pm.duplicate(self.sourceObj, n='%s_copy'%self.sourceObj)
            # decide which target the random vert index falls on
            vertSum = 0
            targetIndex = 0
            targetVertIndex = 0
            for j, k in enumerate(self.targetVertNumList):
                vertSum += k
                if i + 1 <= vertSum:
                    targetIndex = j
                    targetVertIndex = i - (vertSum - k)
                    break
            # apply scale
            if scaleMode == self.scaleBtnRand:
                randScale = random.uniform(scaleRange[0], scaleRange[1])
                pm.xform(newObj, s=(randScale,randScale,randScale))
            # apply rotation
            if rotationMode == self.rotBtnAlign: # normal constraint
                pm.normalConstraint(self.targetObjs[targetIndex], newObj, aim=(0,0,1), u=(0,1,0))
            elif rotationMode == self.rotBtnRand:
                newRotX = random.uniform(origRot[0]-rotRange[0]/2,origRot[0]+rotRange[0]/2)
                newRotY = random.uniform(origRot[1]-rotRange[1]/2,origRot[1]+rotRange[1]/2)
                newRotZ = random.uniform(origRot[2]-rotRange[2]/2,origRot[2]+rotRange[2]/2)
                pm.xform(newObj, ro=(newRotX,newRotY,newRotZ))
            rotatePivot = pm.xform(newObj, rp=True, q=True)
            newPos = pm.pointPosition('%s.vtx[%d]'%(self.targetObjs[targetIndex],targetVertIndex))
            posOffset = [newPos[0]-rotatePivot[0], newPos[1]-rotatePivot[1], newPos[2]-rotatePivot[2]]
            pm.xform(newObj, t=posOffset)
            # remove constraint after translation
            if rotationMode == self.rotBtnAlign:
                pm.delete(newObj, cn=True)
示例#12
0
def create_jointChain( IdName = 'joint', inputCurve = pm.selected(), orientation = 'xyz' ):
    
    # get number of CVs on InputCurve
    numberOfCvs = pm.getAttr( inputCurve[0] + '.cp',s=1 )
    
    # create joints on world space cv locations
    Jnts = []
    for i in range(0, numberOfCvs):
        pm.select( clear = True )
        currentCvPos = pm.pointPosition( inputCurve[0].cv[i], w=1 )
        Jnt = pm.joint( name = '_'.join( ['bn', IdName, str( i+1 )] ) )
        pm.xform( Jnt, t = currentCvPos )
        Jnts.append( Jnt )
        
    # create end joint
    pm.select( clear = True )
    endJntPos = 0.1 * ( pm.getAttr( Jnts[len(Jnts)-1].translate ) - pm.getAttr( Jnts[len(Jnts)-2].translate ) ) + pm.getAttr( Jnts[len(Jnts)-1].translate )
    endJnt = pm.joint( name = 'be_' + IdName, position = endJntPos, a = True )
    Jnts.append( endJnt )
    
    # set aim and orientation vectors, always yup
    aimDict = {}
    aimDict[orientation[0]] = 1
    aimDict[orientation[1]] = 0
    aimDict[orientation[2]] = 0
    aimVec = ( aimDict['x'], aimDict['y'], aimDict['z'] )

    orientDict = {}
    orientDict[orientation[0]] = 0
    orientDict[orientation[1]] = 0
    orientDict[orientation[2]] = 1
    orientVec = ( orientDict['x'], orientDict['y'], orientDict['z'] )
    
    # orient first joint
    JntAimConstrain = pm.aimConstraint( Jnts[1], Jnts[0], aimVector = aimVec, upVector = (0,1,0), worldUpType = "scene" )
    pm.delete( JntAimConstrain )
    Jnts[0].jointOrient.set( Jnts[0].rotate.get() )
    Jnts[0].rotate.set( 0,0,0 )
    
    # orient middle joints
    for i in range( 1, len( Jnts ) - 1 ):
        JntAimConstrain = pm.aimConstraint( Jnts[i+1], Jnts[i], aimVector = aimVec, upVector = orientVec, worldUpType = "objectrotation", worldUpVector = orientVec, worldUpObject = Jnts[i-1] )
        pm.delete( JntAimConstrain )
        Jnts[i].jointOrient.set( Jnts[i].rotate.get() )
        Jnts[i].rotate.set( 0,0,0 )
    
    # orient last joint
    Jnts[len( Jnts ) -1 ].jointOrient.set( Jnts[len( Jnts ) -2 ].jointOrient.get() )
    
    # parent joints
    for i in range( 1, len( Jnts ) ):
        pm.parent( Jnts[i], Jnts[i-1], absolute = True)

    pm.select( Jnts[0] )
    print('Successfully created and oriented joint-chain. Continuing...')
    return Jnts
示例#13
0
def lap(myface, sample = 30, id = [-1,-1]) :

    # ------- ブレンドシェイプをフリーズ ----------
    tools.freeze_blend_shape(
                    myface.obj, 
                    myface.blender, 
                    myface.defaultShape)  # 重い
    # --------------------------------------------

    sampling_point = [ i * (1. / sample) for i in range(sample)]
    point1 = sampling_point[id[0]]
    point2 = sampling_point[id[1]]
    
    # ピンの数
    n = len(myface.parts_vertex[myface.context_parts])
    nu = 5  # 両端を含む,上唇のピンの数
    nl = 5  # 両端を含む,下唇のピンの数
    
    if point2 < point1 :
        point2 += 1
    params = []
    # 上唇
    for i in range(nu - 1) :
        param = point1 + ( ((point2-point1)/(nu-1.)) * float(i) )
        params.append(param - int(param))

    # 下唇
    point1 += 1    
    for i in range(nl - 1) :
        param = point2 + ( ((point1-point2)/(nu-1.)) * float(i) )
        #print " - - - ",point1," ",point2," ",param
        params.append(param - int(param))
    print "params : ", params

    point1 -= 1

    curPosList =  curvetool.getCurvePoint(myface.curve, params, "normal")

    pinID_comp, params_comp = doDMP_completed.complete_pin(myface, params=params)
    curPosList_comp = curvetool.getCurvePoint(myface.curve, params_comp, "normal")
    
    #temp
    print "len", len(curPosList_comp)
    vtxPos = [pm.pointPosition(myface.obj.vtx[i]) for i in pinID_comp]
    print "len", len(vtxPos),  " ", len(vtxPos[0])
    mv = [tools.makeVector([curPosList_comp[i][j]-vtxPos[i][j] for j in range(3)], vtxPos[i]) for i in range(len(curPosList_comp))]
    print len(mv)
    

    print "id : ", pinID_comp
    print "param : ",params
    print "param_comp : ", params_comp
    limitLap.do_lap_limit(myface, pinID_comp, 12, curPosList_comp, debug = True)

    return pinID_comp, params_comp
示例#14
0
def diff_3D_max(myface, **kwargs) :

    cur      = myface.curve
    sampling = kwargs.get("sampling", 30)
    
    pinIndexList = kwargs.get( "pinIndex", myface.parts_vertex[myface.context_parts] )
    n = len(pinIndexList)

    pmpoints = [pm.pointPosition(myface.obj.vtx[i]) for i in pinIndexList]
    points = []
    for i in pmpoints :
        points.append(om2.MPoint(i[0], i[1], i[2]))

    dist_max = 0
    for i, p in enumerate(points) :
        
        pbef = points[-1] if i == 0   else points[i-1]
        pnex = points[0]  if i == n-1 else points[i+1]

        v1 = (pbef - p).normal()
        v2 = (pnex - p).normal()
        
        va = (v1 + v2).normal()
        vb = v1 ^ v2
        vn = va ^ vb

        #tools.makeVector(vn, p, "VN")

        dist_cache = -1
        # カーブの各セグと交差判定,近いものを採用.
        for j in range(sampling) :

            end = curvetool.getCurvePoint(cur, [j/float(sampling), (j+1)/float(sampling)], "normal")

            en0 = (end[0]-p)*vn
            en1 = (end[1]-p)*vn 
            if en0 * en1 <= 0 :
                ip = end[0] - (end[1]-end[0])*( en0 / (en1-en0) )
                dist = (ip - p).length()
                
                if dist_cache == -1 or dist <= dist_cache :
                    dist_cache = dist
                    #crspt = ip

        if dist_cache == -1 : 
            print (u"ERROR 交点が見つかりません")
            #return -1
        else:
            if dist_max < dist_cache :
                dist_max = dist_cache
        #tools.makeVector(crspt - p, p, "XtoP")

    #print "max_difference : ", dist_max 
    return dist_max
示例#15
0
def getMostBend(cur) :
    le = len(cur.cv)
    n = 9999
    #point = cur.cv[0]
    
    for i in range(le - 2) :
        p1 = pm.pointPosition (cur.cv[i])
        p2 = pm.pointPosition (cur.cv[i+1])
        p3 = pm.pointPosition (cur.cv[i+2])
        v1 = p2 - p1
        v2 = p3 - p2

        ntemp = v2.dot(v1)
        if ntemp < n :
            n = ntemp
            #point = p2
            index = i+1

    #makeSphere(point)
    return index
示例#16
0
    def calc_params_from_vid(self, indexes) :

        pos1   = pm.pointPosition(self.obj.vtx[indexes[0]])
        dist_inc = [0.]
        sumdist = 0
        for i in indexes[1:] :
            pos2 = pm.pointPosition(self.obj.vtx[i])
            dist = (pos2 -pos1).length() 
            pos1 = pos2[:]
            sumdist += dist
            dist_inc.append(sumdist)
            
        
        print dist_inc
        print sumdist

        params = [d / sumdist for d in dist_inc]
        
        print "calc_params : ", params
        return params
    def shrinkWrap(cls, verts, mesh, progBar='', *args, **kwargs):
        ''' '''
        scaleFactor = 1
        loc = pm.spaceLocator()

        pm.geometryConstraint(mesh, loc)
        pm.progressBar(progBar,
                       edit=True,
                       isInterruptable=True,
                       maxValue=len(verts),
                       vis=True)

        if verts:
            tmpPos = verts[0].getPosition(space='world')
            if len(tmpPos) == 4:
                scaleFactor = 1 / tmpPos[3]

        for vert in verts:
            if pm.progressBar(progBar, query=True, isCancelled=True):
                pm.progressBar(progBar, edit=True, vis=False)
                break
            else:
                currentVert = ((vert.split('.')[1]).lstrip('vtx[')).rstrip(']')

                vertPos = pm.pointPosition(vert, w=True)

                pm.move(loc, [vertPos[0], vertPos[1], vertPos[2]], ws=True)

                locPos = pm.pointPosition(loc)

                pm.move(vert, [locPos[0], locPos[1], locPos[2]], ws=True)

                pm.progressBar(progBar, edit=True, step=1)

        pm.progressBar(progBar, edit=True, vis=False)
        pm.progressBar(progBar, edit=True, endProgress=True)

        pm.delete(loc)

        pm.select(vert.split('.')[0], r=True)
        pm.delete(ch=True)
示例#18
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)
    def getCurveCoords(self):
        pm.select(cl=True)

        #get lowResCurveCoordList
        self.lowResCurveCoordList = []
        for cv in self.lowResCurveTrans.cv[:]:
            self.lowResCurveCoordList.append(pm.pointPosition(cv, w=True))

        #rename
        pm.rename(self.lowResCurveTrans, self.prefix + '_splineIk_curve')

        #get highResCurveCoordList
        self.highResCurveCoordList = []
        for cv in self.highResCurveTrans.cv[:]:
            self.highResCurveCoordList.append(pm.pointPosition(cv, w=True))

        #rename
        pm.rename(self.highResCurveTrans,
                  self.prefix + '_dynamic_splineIk_curve')

        pm.select(cl=True)
	def getCurveCoords(self):
		pm.select(cl = True)
		
		
		#get lowResCurveCoordList
		self.lowResCurveCoordList = []
		for cv in self.lowResCurveTrans.cv[:]:
			self.lowResCurveCoordList.append(pm.pointPosition(cv, w = True))
			
		#rename
		pm.rename(self.lowResCurveTrans, self.prefix +'_splineIk_curve')
		
			
		#get highResCurveCoordList
		self.highResCurveCoordList = []
		for cv in self.highResCurveTrans.cv[:]:
			self.highResCurveCoordList.append(pm.pointPosition(cv, w = True))
			
		#rename
		pm.rename(self.highResCurveTrans, self.prefix +'_dynamic_splineIk_curve')
		
		pm.select(cl = True)
示例#21
0
    def __init__(self, name_in, curve):

        self._curveNode = pm.nt.Transform(pm.rename(curve, name_in))

        self._curveInfo = self._create_curveInfo()

        self._degree = None
        self._spans = None
        self._arcLen = None
        self._numCVs = None

        self._cvPositions = []
        for j in range (0, self.numCVs):
            self._cvPositions.append(pm.pointPosition(self.curveNode.cv[j], w = 1))
示例#22
0
def do_diff_2D(myface) :
    distance = 100

    #p = pm.pointPosition()
    #camName   =  tools.getCamFromModelPanel()
    cam       =  pm.PyNode("persp")
    c = pm.getAttr(cam.translate)

    pm.move(cam, -1,0,0,r = 1, os = 1, wd = 1)
    moved = pm.getAttr(cam.translate)
    pm.move(cam, 1,0,0,r = 1, os = 1, wd = 1)
    scr_x = moved - c

    pm.move(cam, 0,-1,0,r = 1, os = 1, wd = 1)
    moved = pm.getAttr(cam.translate)
    pm.move(cam, 0,1,0,r = 1, os = 1, wd = 1)
    scr_y = moved - c

    scr_z = scr_x.cross(scr_y)
    scr = c - (distance*scr_z)
    print "axis " , scr_x, scr_y


    line1_3D = [pm.pointPosition(i) for i in myface.curve.cv]
    line1_2D = [projection_2D(i,c,scr,scr_x,scr_y) for i in line1_3D]

    pins = myface.parts_vertex["mouth"]
    pinss, params = tools.complete_pinIndenList(myface,pins)
    line2_3D = [pm.pointPosition(myface.obj.vtx[i]) for i in pinss]
    line2_2D = [projection_2D(i,c,scr,scr_x,scr_y) for i in line2_3D]

    print "line1(",len(line1_2D),") ", line1_2D
    print "line2(",len(line2_2D),") ", line2_2D

    dif =  diff_2D(line1_2D,line2_2D)

    return dif
示例#23
0
  def shrinkWrap(cls, verts, mesh, progBar='', *args, **kwargs):
    ''' '''
    scaleFactor = 1
    loc = pm.spaceLocator()

    pm.geometryConstraint(mesh, loc)
    pm.progressBar(progBar, edit=True, isInterruptable=True, maxValue = len(verts), vis=True)

    if verts:
      tmpPos = verts[0].getPosition(space='world')
      if len(tmpPos)==4:
        scaleFactor = 1/tmpPos[3]

    for vert in verts:
      if pm.progressBar(progBar, query=True, isCancelled=True):
        pm.progressBar(progBar, edit=True, vis=False)
        break
      else:
        currentVert = ((vert.split('.')[1]).lstrip('vtx[')).rstrip(']')

        vertPos = pm.pointPosition(vert, w=True)

        pm.move(loc, [vertPos[0], vertPos[1], vertPos[2] ], ws=True)

        locPos = pm.pointPosition(loc)

        pm.move(vert, [locPos[0], locPos[1], locPos[2] ], ws=True)

        pm.progressBar(progBar, edit=True, step=1)

    pm.progressBar(progBar, edit=True, vis=False)
    pm.progressBar(progBar, edit=True, endProgress=True)

    pm.delete(loc)

    pm.select(vert.split('.')[0], r=True)
    pm.delete(ch=True)
示例#24
0
def calc_bwm(myface, indexes, curposlist) :
    
    m     =  []
    num_of_pin = len(curposlist)
    print num_of_pin
    m = np.zeros((3*num_of_pin, 1))
    for i, p in enumerate( curposlist ) :
        for j, a in enumerate( p ) :
            m[3*i + j][0] = a

    posnow = np.array([[pm.pointPosition(myface.obj.vtx[i]) for i in indexes]])

    tt = posnow.T - m

    return np.linalg.norm(tt, ord=2)
class locatorCreate:

    def __init__(self, nameLocator, position=[], scale=[]):
        self.nl = nameLocator
        self.pos = position
        self.scl = scale

    def createLoc(self):
        self.loc = pm.spaceLocator(n=self.nl, p=(self.pos[0], self.pos[1], self.pos[2]))
        print self.loc

    def float[] getPositionInWorld(self):
        self.locPositionWorld = pm.pointPosition(self.nl, w = True)
        print 'the world positions of '+self.nl+' are: x='+str(self.locPositionWorld[0])+', y='+str(self.locPositionWorld[1])+', z='+str(self.locPositionWorld[2])
        return self.locPositionWorld
示例#26
0
def getCurveWorldPoints(crv):
    crv = pm.ls(crv)[0]
    print crv
    ss = crv.getShape()
    if (ss.__class__ is not pm.nodetypes.NurbsCurve):
        print 'Error. No Nurbs Curve'
        return False
    curvepoints = ss.numCVs()
    pointList = []
    pointPosList = []
    for curvepoint in range(curvepoints):
        pointp = pm.pointPosition('%s.cv[%s]'%(ss,curvepoint))
        if(pointp not in pointPosList):
            pointPosList.append(pointp)
            pointList.append(curvepoint)
    return pointList, pointPosList
示例#27
0
def saveCntrlsShape(objs, path):
    sel = [x for x in objs if '_cntrl' in x.name()]
    filename = path
    cntrlShapeDict = {}
    for obj in sel:
        tempDict = {}
        for shp in obj.getShapes():
            if pm.nodeType(shp) == 'nurbsCurve':
                pointList = []
                for i in range(len(shp.cv)):
                    pointList.append(pm.pointPosition(shp.cv[i], l=True))
                tempDict[shp.name()] = pointList
        cntrlShapeDict[obj.name()] = tempDict
    with open(filename, 'wb') as f:
        pickle.dump(cntrlShapeDict, f)
    print 'cntrl save ok'
示例#28
0
    def __init__(self, objName, nameModuleCreator, listLocs):
        self.objName = objName
        self.nameModuleCreator = nameModuleCreator
        self.listLocs = listLocs
        # pm.select("*_LOC")
        # listLocs = pm.ls(sl=True)

        # print listLocs
        listJoints = []
        if self.listLocs == '':
            list = self.nameModuleCreator.getListLocs()
        else:
            list = listLocs

        print list

        jointList = []
        chainFather = ''

        for i in range(0, len(list)):
            positionLocs = pm.pointPosition(list[i], w=True)
            nameLoc = list[i]
            subName = nameLoc[0:len(list[i]) - 3]
            nameJnt = subName + 'JNT'
            pm.joint(p=(positionLocs[0], positionLocs[1], positionLocs[2]),
                     n=nameJnt)
            jointList.append(nameJnt)
            pm.parent(nameJnt, w=True)
            pm.setAttr(nameJnt + '.radius', 0.5)

        for i in range(0, len(list)):
            obj = pm.getAttr(list[i] + '.locFather')
            print '\n\r Loc Father: ' + obj + '\n\r'
            if obj != 'self':
                subName = obj[0:len(obj) - 3]
                print '\n\r SubName: ' + subName + '\n\r'
                jointFather = subName + 'JNT'
                pm.parent(jointList[i], jointFather)
            else:
                chainFather = jointList[i]
        #joint -e  -oj yzx -secondaryAxisOrient xup -ch -zso;
        pm.joint(chainFather,
                 e=True,
                 oj='yzx',
                 secondaryAxisOrient='xup',
                 ch=True,
                 zso=True)
        def vertLocators():
            """ Iterates through vertices on surface, attaches locators and objects
            """

            aimLoc = pm.spaceLocator(n="aimLoc")

            # Selects all vertices, puts all vertice coordinates in a list
            pm.select(nameOfSurface)
            vs = pm.polyEvaluate(v=True)
            verts = []
            vertLocCount = 0
            for i in range(0, vs):
                verts += (pm.pointPosition(nameOfSurface + '.vtx[' + str(i) +
                                           ']'), )

            # Creates locators
            for v in verts:
                numGen = r.random()
                if (numGen <= num):
                    vertLoc = pm.spaceLocator(n="vertexLoc{0}".format(1),
                                              p=(v[0], v[1], v[2]))
                    pm.xform(centerPivots=True)
                    pm.delete(
                        pm.aimConstraint(aimLoc,
                                         vertLoc,
                                         aimVector=[0, -1, 0],
                                         upVector=[0, 1, 0],
                                         worldUpVector=[0, 1, 0]))
                    duplicatedObject = pm.instance(selectedObject, lf=True)
                    rotVal = pm.getAttr(vertLoc + '.rotate')
                    pm.setAttr(duplicatedObject[0] + '.translate', v[0], v[1],
                               v[2])
                    pm.setAttr(duplicatedObject[0] + '.rotate', rotVal[0],
                               rotVal[1], rotVal[2])

                    if setToNormals is False:
                        pm.setAttr(duplicatedObject[0] + '.rotate', 0, 0, 0)
                        pm.setAttr(vertLoc + '.rotate', 0, 0, 0)

                    pm.parent(vertLoc, duplicatedObject[0], duplicateGroup)
                    vertLocCount += 1

            pm.delete(aimLoc)
            totalVerts = round(float(vertLocCount) / vs * 100.0, 2)
            _logger.debug("Generated " + str(vertLocCount) +
                          " locators at vertices for " + str(vs) +
                          " possible vertices. (" + str(totalVerts) + "%) ")
示例#30
0
    def __init__(self) :
        
        # 初期状態を保存
        self.blender       = pm.PyNode(self.blender_name)
        [ pm.setAttr(w,0.0) for w in self.blender.w ]
        self.obj           = pm.PyNode(self.name) 
        self.defaultShape  = [ pm.pointPosition(v) for v in self.obj.vtx ]


        # パラメータ保存用オブジェクトから顔パーツのパラメータを設定
        # パラメータがアトリビュートとして存在しない場合,アトリビュートを作成
        if pm.objExists(self.param_obj_name) :
            obj = pm.PyNode(self.param_obj_name)
            for i in self.parts_vertex :
                attname = self.param_obj_name + "." + i
                
                # 各部位の頂点IDを読み込みOR保存
                if pm.objExists(attname) :
                    if pm.getAttr(attname) == None :
                        pm.setAttr(attname, self.parts_vertex[i])
                    self.parts_vertex[i] = pm.getAttr(attname)
                else :
                    pm.addAttr(obj, ln = i, dataType = "Int32Array")
                    pm.setAttr(attname, self.parts_vertex[i])
            
            """
            # メッシュデータのパスを読み込みOR保存
            attname = self.param_obj_name + "." + "mesh_data_path"
            if pm.objExists(attname) :
                self.mesh_data_path = pm.getAttr(attname)
                
            else :
                pm.addAttr(obj, ln = "mesh_data_path", dataType = "string")
                pm.setAttr(attname, self.mesh_data_path)
            """

        else :
            obj = pm.spaceLocator(n = self.param_obj_name)
            for i in self.parts_vertex :
                pm.addAttr(obj, ln = i, dataType = "Int32Array")
                attname = self.param_obj_name + "." + i
                pm.setAttr(attname, self.parts_vertex[i])

        # 所定の名前のカーブオブジェクトがあればカーブオブジェクトを登録
        if pm.objExists("projectionCurve") :
            self.curve = pm.PyNode("projectionCurve")
示例#31
0
def createVertSphere():
	'''
	create a poly sphere that will be used to determine 
	what verts should be influenced.
	'''
	sel = pm.selected()
	
	for s in sel:
		print pm.objectType(s)
		if pm.objectType(s) == 'joint':
			userPos = pm.xform(s, q = True, t = True, ws = True)
		elif pm.objectType(s) == 'mesh':
			userPos = pm.pointPosition(s, w = True)
		
		vSphere = pm.polySphere(n = '{0}_vtxSphere'.format(s), ch = False)
		pm.move(userPos[0],userPos[1],userPos[2], vSphere)
		
		return vSphere
示例#32
0
def attachToVertices(source, targetVertices=None):
    """Instances source, and attaches each instance to each
    vertice.

    If targetVertices == None, the selected vertices are used.
    """

    if not targetVertices:
        targetVertices = pm.filterExpand(pm.ls(sl=True), expand=True, sm=31)
    else:
        if not hasattr("__next__", targetVertices):
            raise TypeError("targetVertices is not iterable.")

    for v in targetVertices:
        p = pm.pointPosition(v, w=True)

        target = pm.PyNode(v).node()

        attach(source, target, p)
示例#33
0
def attachToVertices(source, targetVertices=None):
    """Instances source, and attaches each instance to each
    vertice.

    If targetVertices == None, the selected vertices are used.
    """

    if not targetVertices:
        targetVertices = pm.filterExpand(pm.ls(sl=True), expand=True, sm=31)
    else:
        if not hasattr("__next__", targetVertices):
            raise TypeError("targetVertices is not iterable.")

    for v in targetVertices:
        p = pm.pointPosition(v, w=True)

        target = pm.PyNode(v).node()

        attach(source, target, p)
示例#34
0
def addCtrlsToLattice(lattice, name=''):
    '''
    Creates a control at each lattice point, creates a constrained joint for each ctrl, skins lattice to joints
    '''
    main_grp = pmc.group(empty=1, name='%s_GRP' % name)
    ctrlsGrp = coreUtils.addChild(main_grp,
                                  'group',
                                  name='%s_ctrls_GRP' % name)
    rigGrp = coreUtils.addChild(main_grp, 'group', name='%s_rig_GRP' % name)

    divs = lattice.getDivisions()
    points = []
    for x in range(divs[0]):
        for y in range(divs[1]):
            for z in range(divs[2]):
                points.append(lattice.pt[x][y][z])

    positions = [pmc.pointPosition(p, w=1) for p in points]

    ctrlSize = (
        (lattice.sx.get() + lattice.sy.get() + lattice.sz.get()) / 3.0) * .25

    joints = []

    for i in range(len(points)):
        num = str(i + 1).zfill(2)
        p = points[i]

        c = controls.crossCtrl(name='%s_%s_CTRL' % (name, num), size=ctrlSize)
        c.setParent(ctrlsGrp)
        c.t.set(positions[i])
        coreUtils.addParent(c, 'group', '%s_%sCtrl_ZERO' % (name, num))

        j = coreUtils.createAlignedNode(c, 'joint', '%s_%s_BND' % (name, num))
        j.setParent(rigGrp)
        coreUtils.addParent(j, 'group', '%s_%sCtrl_ZERO' % (name, num))
        joints.append(j)

        c.t.connect(j.t)

    rigGrp.visibility.set(0)

    pmc.skinCluster(joints, lattice, mi=1)
示例#35
0
def show_sketch(myface, cam=None, cur=None, overwrite=True, name =None):
    print "スケッチの複製を前に出して見えるようにします."
    if not cur : cur = myface.curve
    if not name : name = "curveshow" 
    if overwrite :
        if pm.objExists(name) :
            c = pm.PyNode(name)
            pm.delete(c)
    
    print "n"

    cur = pm.duplicate(cur, n = name)[0]

    print "n"

    if not cam : cam = pm.PyNode(tools.getCamFromModelPanel())

    campos = pm.getAttr(cam.translate)

    print cur
    for p in cur.cv :
        ppos = pm.pointPosition(p)
        newpos = ppos + (campos - ppos) * 0.1
        pm.move(p, newpos)

    pm.select(cur)

    # レンダリング用のシェーダを設定
    pm.setAttr(cur.aiRenderCurve,True)
    pm.setAttr(cur.aiCurveWidth, 0.2)
    # シェーダを確認
    if not pm.objExists("ai_line_shader") :
        global shadingEngine
        myShader , shadingEngine = pm.createSurfaceShader("aiFlat")
        pm.rename(myShader, "ai_line_shader")
    else :
        print "すでにライン用シェーダが存在します。"
        myShader = pm.PyNode("ai_line_shader")
        
    pm.setAttr(myShader.color, (1,0,0))
    pm.connectAttr(myShader.outColor, cur.aiCurveShader)

    pm.select(cur)
示例#36
0
def creatSoftModCtrl(vtx):
        
    for i in vtx:
        a = str(type(i))
        if a == "<class 'pymel.core.general.MeshVertex'>":
            name = (str(i))
            ModifiedName = re.sub(r'[^\w]', '_', name)    
            print (ModifiedName)
        else:
            print('Wrong Selection, Only select verticies')
            break
        pos = pm.pointPosition(i)
        
        name = (str(i))
        ModifiedName = re.sub(r'[^\w]', '_', name)    
        ctl = pm.curve(n = ModifiedName +'_SoftMod_Handle_Ctrl' ,d=1, p=[(1, 1, 1),(1, 1, -1),(-1, 1, -1),(-1, 1, 1),(1, 1, 1),(1, -1, 1),(1, -1, -1),(1, 1, -1),(-1, 1, -1),(-1, -1, -1),(1, -1, -1),(-1, -1, -1),(-1, -1, 1),(-1, 1, 1),(-1, -1, 1),(1, -1, 1)], k=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15])
            
        pm.addAttr(ctl , ln = 'fallOff', at = 'double', dv = 20) 
        pm.setAttr(ctl.fallOff, k=1)
        pm.addAttr(ctl , ln = 'fallOffMode', at = 'enum', en = 'volume:surface') 
        pm.setAttr(ctl.fallOffMode, k=1)    
        pm.addAttr(ctl , ln = 'globalScale', at = 'double', dv = 1) 
        pm.setAttr(ctl.globalScale, k=1)   
        grp = pm.createNode('transform',n = ModifiedName + '_ctrl_grp' )
        loc = pm.spaceLocator(n = ModifiedName+'_SoftMod_Ctrl') 
        pm.select(cl=1)
        pm.parent(loc,grp)
        pm.parent(ctl,loc)
        grp.translate.set(pos)
        mesh = pm.listTransforms(i.split('.')[0])[0]
        pm.select(mesh)
        sfMod = cmds.softMod(wn = (str(mesh),str(mesh)))
        pm.select(cl=1)
        cmds.softMod(sfMod[0],e=1,wn = (str(ctl),str(ctl)))
        pm.setAttr(sfMod[0]+'.falloffAroundSelection',0)
        pm.connectAttr(loc.worldPosition[0],sfMod[0]+'.falloffCenter')
        mdl = pm.createNode('multDoubleLinear',n = ModifiedName+'_MDL')
        pm.connectAttr(ctl.fallOffMode,sfMod[0]+'.falloffMode')
        ctl.fallOff>>mdl.input1
        ctl.globalScale>>mdl.input2
        pm.connectAttr(mdl.output,sfMod[0]+'.falloffRadius')
        pm.connectAttr(loc.worldInverseMatrix[0],str(sfMod[0])+'.bindPreMatrix')
示例#37
0
    def previous_pin(self, *args) :
        print u" - - - 前のピンへ移動します。- - - "
        if self.no_of_editing_pin != 0 :
            self.no_of_editing_pin -= 1
        else :
            self.no_of_editing_pin = self.no_of_editing_pin_max - 1

        print u"no_of_editing_pin  :", self.no_of_editing_pin
        print u"parameter          :", self.paramList[self.no_of_editing_pin]

        # 球を強調する
        index = self.constPinIndexList[self.no_of_editing_pin]
        v = pm.PyNode(self.base_name).vtx[index]
        try :
            pm.delete(pm.PyNode("tempmouth"))
        except :
            pass
        pos = pm.pointPosition(v)
        sp = pm.sphere(n = "tempmouth", r=0.3)[0]
        pm.move(sp,[pos[0],pos[1],pos[2]])
示例#38
0
        def vertLocators():
            """ Iterates through vertices on surface, attaches Locators """

            # Selects all vertices, puts all vertice coordinates in a list
            pm.select(nameOfSurface)
            vs = pm.polyEvaluate(v=True)
            verts = []
            vertLocCount = 0
            for i in range(0, vs):
                verts += (pm.pointPosition(nameOfSurface + '.vtx[' + str(i) +
                                           ']',
                                           world=True), )

            # Creates locators
            for v in verts:
                numGen = r.random() * 10.0
                if (numGen <= num):
                    pm.spaceLocator(n="vertexLoc{0}".format(1),
                                    p=(v[0], v[1], v[2]))
                    duplicatedObject = pm.instance(selectedObject, leaf=True)
                    pm.setAttr(duplicatedObject[0] + '.translate', v[0],
                               v[1] + scaleOfItems, v[2])

                    vertRotations = calculateRotations(node=nameOfSurface,
                                                       vertPositions=v)

                    if (randomScale is True):
                        pm.setAttr(duplicatedObject[0] + '.scale',
                                   (scaleOfItems * numGen),
                                   (scaleOfItems * numGen),
                                   (scaleOfItems * numGen))
                    else:
                        pm.setAttr(duplicatedObject[0] + '.scale',
                                   scaleOfItems, scaleOfItems, scaleOfItems)

                    vertLocCount += 1

            totalVerts = round(float(vertLocCount) / vs * 100.0, 2)
            print("Generated " + str(vertLocCount) +
                  " locators at vertices for " + str(vs) +
                  " possible vertices. (" + str(totalVerts) + "%)")
示例#39
0
def symmetry_surface(source, target):
    u"""对称surface

    :param source:
    :param target:
    :return:
    """
    num_u = pm.PyNode(source).getShape().attr("degreeU").get() + pm.PyNode(
        source).getShape().attr("spansU").get()
    num_v = pm.PyNode(source).getShape().attr("degreeV").get() + pm.PyNode(
        source).getShape().attr("spansV").get()

    for index_u in range(0, num_u):
        for index_v in range(0, num_v):
            source_position = pm.pointPosition('{}.cv[{}][{}]'.format(
                source, index_u, index_v),
                                               w=True)
            pm.move(
                source_position[0] * -1, source_position[1],
                source_position[2],
                pm.PyNode("{}.cv[{}][{}]".format(target, index_u, index_v)))
    return True
示例#40
0
    def make_joints_along_curve(cls, curve, name, num_joints=0, rebuild=False, parent=None):
        '''Create joints along a curve in the same direction as the curve
        Args:
            curve (pm.PyNode): the curve transform to be used
            num_joints (int): the number of joints to be created, if 0 will use CVs
            rebuild (bool): whether we rebuild and normalize the curve or not
            parent (pm.nt.Transform): final parent of the joints
        Returns:
            [pm.nt.Joint]: list of joints
        Usage:
            rig_makeJointsAlongCurve("petalA", pm.ls(sl=True)[0], 15)
            rig_makeJointsAlongCurve("seatbeltDrive", pm.ls(sl=True)[0], 160)
        '''
        poci = None
        
        #Creating a curve between them
        curve = pm.duplicate(curve)[0]
        
        if rebuild:
            pm.rebuildCurve(curve, ch=0, rpo=1, rt=0, end=1, kr=1, kcp=0, kep=1, kt=0, 
                            s=num_joints, d=1, tol=0.01)
        
        # Detecting if we're doing cv based or not
        if not num_joints:
            cvs = True
            num_joints = curve.getShape().numCVs() - 1
        else:
            cvs = False
            poci = pm.createNode('pointOnCurveInfo')
            curve.getShape().worldSpace[0].connect(poci.inputCurve)
            poci.turnOnPercentage.set(1)
        
        #Evenly spacing joints according to the curve
        joints=[]
        cls.namer.set(name)
        cls.namer.var.set('A')
        cls.namer.type.set('joint')
        names = cls.namer.get_chain(num_joints)
        
        # Clear the selection since the stupid joint command sucks at parenting
        pm.select(cl=True)
        for joint_index, name in enumerate(names):
            jnt_pos = [0,0,0]
            
            if cvs:
                jnt_pos = pm.pointPosition( curve.getShape().cv[joint_index], w = 1)
            else:
                poci.parameter.set(float(joint_index)/float(num_joints))
                jnt_pos = poci.position.get()
            
            joints.append(pm.joint(n = name, p = jnt_pos))

        #Set the rotation order    
        for joint in joints[:-1]:
            joint.secondaryAxisOrient('yup', oj='xyz')
        
        # if parent is set, do it.
        if parent:
            pm.setParent(joints[0], parent)
        
        # Cleanup
        pm.delete(curve)
        if cvs:
            pm.delete(poci)
        
        return joints