Пример #1
0
def hierarchyBetween(*args,**keywords):
	sel=[]
	type=''
	if len(args)==0:
		sel=mc.ls(sl=True)
	for a in args:
		if isIterable(a):
			sel.extend(a)
		else:
			sel.append(a)
	for k in keywords:
		if k=='t' or k=='type':
			type=keywords[k]
		elif k in locals():
			exec(k+'=keywords[k]')
	shortNames=mc.ls(sel,sn=True)
	longNames=mc.ls(sel,l=True)
	if shortNames[0] not in longNames[-1].split('|'):
		shortNames.reverse()
		longNames.reverse()
	hierarchy=longNames[-1].split('|')
	if shortNames[0] not in hierarchy: return []
	hierarchyBetween=[]
	for i in range(hierarchy.index(shortNames[0]),len(hierarchy)):
		if type=='':
			h=mc.ls('|'.join(hierarchy[:i+1]))
		else:
			h=mc.ls('|'.join(hierarchy[:i+1]),type=type)
		if isIterable(h) and len(h)>0:
			hierarchyBetween.append(h[0])
	return hierarchyBetween
Пример #2
0
def shape(*args,**keywords):
	all=False
	shortNames={
		'a':'all'
	}
	for k in keywords:
		if k in shortNames:
			exec(shortNames[k]+'=keywords[k]')
		if k in locals():
			exec(k+'=keywords[k]')
	if len(args)==0: args=iterable(mc.ls(sl=True))
	sel=[]
	for a in args:
		if isIterable(a) or mc.objExists(a):
			sel.append(mc.ls(a,o=True))
	shapes=[]
	for s in sel:
		sh=iterable(mc.ls(s,s=True))
		if len(sh)==0:
			sh=mc.listRelatives(s,c=True,s=True,ni=True)
		if len(iterable(sh))>0:
			if all:
				shapes.append(sh)
			else:
				shapes.append(sh[0])
	if len(shapes)==1:
		return shapes[0]
	elif len(shapes)==0:
		return ''
	else:
		return shapes
Пример #3
0
    def __init__(self, *args, **keywords):

        # default options
        self.world = ""
        self.parents = []
        name = ""
        self.scale = True
        self.enumNames = []

        self.enumNames = {
            "s": "scale",
            "w": "world",
            "p": "parents",
            "n": "name",
            "ps": "ParentSpace",
            "en": "enumNames",
        }

        # attributes
        self[:] = []
        self.child = ""
        self.currentParent = ""
        self.parentConstraint = ""
        self.scaleConstraint = ""

        for k in keywords:
            if k in self.__dict__:
                exec("self." + k + "=keywords[k]")
            elif k in self.enumNames:
                exec("self." + enumNames[k] + "=keywords[k]")

        self.enumNames = iterable(self.enumNames)

        sel = []
        if len(args) == 0:
            sel = mc.ls(sl=True)

        for a in args:
            if isIterable(a):
                for aa in a:
                    if mc.objExists(a):
                        sel.append(mc.ls(a))[0]
            elif mc.objExists(a):
                sel.append(mc.ls(a)[0])

        if (len(sel) > 0 or self.child != "") and len(self) == 0:

            if self.child == "":
                self.child = sel[0]

            if mc.objExists(self.child + ".zenParentSpace") and mc.connectionInfo(
                self.child + ".zenParentSpace", id=True
            ):
                self.append(mc.listConnections(sel[0] + ".zenParentSpace", s=True, d=False)[0])
            else:
                self.create(n=name)

            if len(sel) > 1:
                self.addParents(en=self.enumNames, *sel[1:])
                self.setParent(sel[-1])
Пример #4
0
def distanceBetween(*args):  # distance between two points
    if len(args) == 0:
        args = mc.ls(sl=True)
    if len(args) == 0:
        return
    p = []
    for a in args:
        if isIterable(a) and len(a) >= 3 and isinstance(a[0], (float, long, int)) and len(a) >= 3:
            p.append(a)
        elif isinstance(a, basestring) and mc.objExists(a):
            if len(a.split(".")) > 1:
                try:
                    p.append(mc.pointPosition(a))
                except:
                    pass
            else:
                try:
                    p.append(mc.pointPosition(a + ".rp"))
                except:
                    err = True
    if len(p) < 1:
        return
    if len(p) > 2:
        p[:] = p[:2]
    dx = abs(p[0][0] - p[1][0])
    dy = abs(p[0][1] - p[1][1])
    dz = abs(p[0][2] - p[1][2])
    return sqrt(dx * dx + dy * dy + dz * dz)
Пример #5
0
def listNodeConnections(*args,**keywords):

	s=True
	d=True
	sn=False
	
	sel=[]
	if len(args)==0:
		sel=mc.ls(sl=True)
		
	for a in args:
		if isIterable(a):
			sel.extend(a)
		else:
			sel.append(a)
			
	for k in keywords:
		if k=='s' or k=='source':
			s=keywords[k]
		if k=='d' or k=='destination':
			d=keywords[k]
		if k=='sn' or k=='shortName':
			sn=keywords[k]
		elif k in locals():
			exec(k+'=keywords[k]')
	
	connections=[]
	
	for conn in removeDuplicates(mc.listConnections(sel[0],s=s,d=d,p=True)):
		
		if len(sel)==1 or mc.ls(conn,o=True)[0]==sel[1]:
			if mc.connectionInfo(conn,isSource=True):
				for dfs in mc.connectionInfo(conn,dfs=True):
					if mc.ls(dfs,o=True)[0]==sel[0]:
						if sn:
							connections.append\
							(
								[
									mc.ls(conn,o=True)[0]+'.'+mc.listAttr(conn,sn=True)[0],
									mc.ls(dfs,o=True)[0]+'.'+mc.listAttr(dfs,sn=True)[0]
								]
							)
						else:
							connections.append([conn,dfs])
			if mc.connectionInfo(conn,id=True):
				sfd=mc.connectionInfo(conn,sfd=True)
				if mc.ls(sfd,o=True)[0]==sel[0]:
					if sn:
						connections.append\
						(
							[
								mc.ls(sfd,o=True)[0]+'.'+mc.listAttr(sfd,sn=True)[0],
								mc.ls(conn,o=True)[0]+'.'+mc.listAttr(conn,sn=True)[0]
							]
						)
					else:
						connections.append([sfd,conn])
						
	return removeDuplicates(connections)
Пример #6
0
def removeAll(removeList, origList):
	
	if not isIterable(origList):
		if isinstance(origList,(basestring,float,int,long)):
			origList=[origList]
		else:
			return []
	if not isIterable(removeList):
		if isinstance(removeList,(basestring,float,int,long)):
			removeList=[removeList]
		else:
			return []
	returnVal=[]
	if isIterable(removeList):
		for o in origList:
			if o not in removeList:
				returnVal.append(o)
	return returnVal
Пример #7
0
	def addAutoFlex(self,mirror=True,pose={},**keywords):
		"Adds an auto-flex pose from the current pose or a dictionary of attribute/value pairs."
				
		self.bindPose= mc.dagPose(self.Muscle,q=True,bp=True)[0]
		self.root=mc.dagPose(self.bindPose, q=True, m=True )[0]
		startPose=mc.dagPose(self.root,s=True)#store current pose
		
		plug=mel.eval('zenFirstOpenPlug("'+self.Handle+'.zenAutoFlex")')
		verified=False
		attributes={}
		poses=[]
		success=True
				
		offBindPoseJointCount=0
		dp=mc.dagPose(self.bindPose,q=True,ap=True)
		if isIterable(dp):
			offBindPoseJointCount=len(dp)
		
		if(offBindPoseJointCount>0 and len(pose)==0): #create an auto-flex pose from the current position
			command='rigZenMuscleAddAutoFlex("'+self.Handle+'",'+str(int(mirror))+')'
			plug=mel.eval(command)
		elif(len(pose)>0):
			success=self.goToPose(**pose)
			if(success):
				try:
					plug=mel.eval('rigZenMuscleAddAutoFlex("'+self.Handle+'",'+str(int(mirror)*self.getAxis())+')')
				except:
					success=False#raise Warning('Could not add auto flex pose for '+self.Muscle)
			
		if success:
			for k in keywords:
				attr='zenAutoFlex['+str(plug)+'].'+str(k)
				conn=mc.listConnections((self.Handle+'.'+attr),s=True,d=False,p=True)
				if isIterable(conn) and len(conn)>0 and mc.ls(conn[0],o=True)[0]==mc.ls((self.Handle+'.'+attr),o=True)[0]:
					attr=conn[0].split('.')[-1]
				attributes[str(attr)]=keywords[k]
			self.setAttributes(**attributes)
			success=self.goToPose(startPose)		
		else:
			self.goToPose(startPose)

		mc.delete(startPose)
		
		return success
Пример #8
0
def iterable(arg):
	if type(arg).__name__=='NoneType':
		return []
	if not isIterable(arg):
		if isinstance(arg,(basestring,float,int,long)):
			return [arg]
		else:
			return []
	else:
		return arg
Пример #9
0
	def getInfluences(self):
		#get influence objects
		self.influences=list()
		self.allCurves=list()
		
		if(not mc.objExists(self.Handle+'.zmi[0].zmim')): return
			
		for i in range(0,len(mc.ls(self.Handle+'.zmi[*]'))):
			self.influences.append(dict())
			self.influences[i]['mesh']=str(mc.listConnections(self.Handle+'.zmi['+str(i)+'].zmim',sh=True)[0])
			self.influences[i]['curves']=list()
			self.influences[i]['edges']=list()
			self.influences[i]['parents']=list()
			for c in mc.ls(self.Handle+'.zmi['+str(i)+'].zmics[*]'):
				if( isinstance(mc.listConnections(c+'.zmic'),list) and len(mc.listConnections(c+'.zmic'))>0):
					curve=mc.listConnections(c+'.zmic')[0]
					self.influences[i]['curves'].append(curve)
					self.allCurves.append(curve)
					edgeList=[]
					index=c.split('[')[(len(c.split('['))-1)].split(']')[0]
					edgeIndices=mc.getAttr(c+'.zmie')[0]
					if( len(self.influences[i]['mesh'])>0 ):
						for e in edgeIndices:
							edgeList.append(self.influences[i]['mesh']+'.e['+str(int(e))+']')
					self.influences[i]['edges'].append(edgeList)
					parentDictionary={}
					pc=mc.parentConstraint(curve,q=True)
					if(isinstance(pc,basestring)):
						parents=mc.parentConstraint(pc,q=True,tl=True)
						parentWeights=mc.parentConstraint(parents,pc,w=True,q=True)
						if not isIterable(parents): parents=[parents]
						if not isIterable(parentWeights): parentWeights=[parentWeights]
						for ppc in range(0,len(parents)):
							pcName=parents[ppc]
							pcWeight=parentWeights[ppc]
							if isinstance(pcName,basestring) and len(pcName) and isinstance(pcWeight,(float,int,long)):
								parentDictionary[pcName]=pcWeight
					else:
						parents=mc.listRelatives(curve,p=True)
						if(isinstance(parents,list) and len(parents)>0):
							parentDictionary[parents[0]]=1
							
					self.influences[i]['parents'].append(parentDictionary)
Пример #10
0
def generateScript():
	sel=mc.ls("*.zenMuscleInputs",o=True,sl=True)
	if not isIterable(sel) or len(sel)==0:
		sel=mc.ls("*.zenMuscleInputs",o=True)
		if not isIterable(sel):
			raise('You must select one or more muscles or Muscle Handle from which to generate creation scripts.')
	returnVal=''
	completed=[]
	for m in sel:
		myMuscle=Muscle(m)
		if myMuscle.Muscle not in completed:
			returnVal+=myMuscle.generateScript()
			completed.append(myMuscle.Muscle)
			if('opposite' in myMuscle.__dict__): 
				completed.append(myMuscle.opposite.Muscle)
	if len(returnVal)>0:
		returnVal='import maya.mel as mel\nmel.eval("source zenTools")\nimport zen\n'+returnVal
		mel.eval('zenDisplayText("Muscle Script","'+mc.encodeString(returnVal)+'")')
	return returnVal
Пример #11
0
def removeDuplicates(iterable):
	if not isIterable(iterable):
		if isinstance(iterable,(basestring,float,int,long)):
			return [iterable]
		else:
			return []
	returnVal=[]
	for item in iterable:
		if item not in returnVal:
			returnVal.append(item)
	return returnVal
Пример #12
0
def melEncode(arg):
	
	if isinstance(arg,basestring):
		return '"'+mc.encodeString(arg)+'"'
	elif isIterable(arg):
		returnVal='{'
		for i in range(0,len(arg)):
			if(isIterable(arg[i])):
				returnVal+='"'
				for n in range(0,len(arg[i])):
					returnVal+=str(arg[i][n])
					if n<len(arg[i])-1 and len(str(arg[i][n]))>0: 
						returnVal+=','
				returnVal+='"'		
			else:
				returnVal+=melEncode(arg[i])
			if i<len(arg)-1 and len(str(arg[i]))>0: 
				returnVal+=','
		returnVal+='}'
		return returnVal
	return 	unicode(arg)
Пример #13
0
	def set(self,val):
		
		if self.type=='vector':#vectors must be explicitly set
			if isIterable(val):
				if isIterable(val[0]):
					self.array=True
					valString='{'
					for i in range(0,len(val)):
						valString+='<<'+unicode(val[i][0])+','+unicode(val[i][1])+','+unicode(val[i][2])+'>>'
						if i<(len(val)-1): valString+=','
						else: valString+='}'
				else:
					valString='<<'+unicode(val[0])+','+unicode(val[1])+','+unicode(val[2])+'>>'
		else:
			if isIterable(val):
				self.array=True
				if len(val)>0:
					testVal=val[0]
				else:
					testVal=''
			else:
				testVal=val
				
			if isinstance(testVal,basestring):
				self.type='string'
			if isinstance(testVal,(int,long,float)):
				if self.type!='' and self.type in ['int','float']: pass
				else:
					if isinstance(testVal,float): self.type='float'
					else: self.type='int'
			valString=melEncode(val)
			
		cmd=self.type+' '+self.name
		if self.array: cmd+='[]'
		cmd+='='+valString
		
		return mel.eval(cmd)
Пример #14
0
def goToDagPose(*args,**keywords):
	
	bindPose=False
	
	shortNames={'bp':'bindPose'}

	for k in keywords:
		if k in locals():
			exec(k+'=keywords[k]')
		if k in shortNames:
			exec(shortNames[k]+'=keywords[k]')

	sel=[]
	if len(args)==0:
		sel=mc.ls(sl=True)
		
	for a in args:
		if isIterable(a):
			sel.extend(a)
		else:
			sel.append(a)

	if len(iterable(mc.ls(sel,type='dagPose')))==0 or bindPose:
		sel=removeDuplicates(mc.dagPose(mc.listConnections(mc.ls(mc.listHistory(sel)),type='transform'),q=True,bp=True))
		
	if len(sel)==0: return

	mel.eval('DisableAll')
		
	success=True
	err=True
	
	for i in range(0,10):
		try: 
			mc.dagPose(sel[0],r=True)
			err=False
			break
		except:
			err=True
			
	mel.eval('EnableAll')
		
	if err and len(iterable(mc.dagPose(q=True,ap=True))):
		success=False

	if success: return sel[0]
	else: return
Пример #15
0
def sortBy(*args,**keywords):
	
	sorted=[]
	sel=[]
	
	if len(args)==1:
		if isIterable(args[0]) and len(args[0])>1:
			sorted=list(args[0][-1])
			sel=list(args[0][0])
			inputType=type(args[0][0]).__name__
		else:
			return
	elif len(args)>1:
		sorted=list(args[-1])
		sel=list(args[0])
		inputType=type(args[0]).__name__
	
	l=sorted[:]
	for s in l:
		if s not in sel:
			sorted.remove(s)
		
	unsorted=sel[0:0]
	
	for s in sel:
		if s not in sorted:
			unsorted=unsorted+[s]
	
	if inputType=='str' or inputType=='unicode':
		unsorted=''.join(unsorted)
		sorted=''.join(sorted)
	elif inputType=='dict':
		sorted=list(sorted)
		unsorted=list(unsorted)
	else:
		exec('sorted='+inputType+'(sorted)')
		exec('unsorted='+inputType+'(unsorted)')
			
	return(sorted+unsorted)
Пример #16
0
def sortBy(*args, **keywords):

    sorted = []
    sel = []

    if len(args) == 1:
        if isIterable(args[0]) and len(args[0]) > 1:
            sorted = list(args[0][-1])
            sel = list(args[0][0])
            inputType = type(args[0][0]).__name__
        else:
            return
    elif len(args) > 1:
        sorted = list(args[-1])
        sel = list(args[0])
        inputType = type(args[0]).__name__

    l = sorted[:]
    for s in l:
        if s not in sel:
            sorted.remove(s)

    unsorted = sel[0:0]

    for s in sel:
        if s not in sorted:
            unsorted = unsorted + [s]

    if inputType == 'str' or inputType == 'unicode':
        unsorted = ''.join(unsorted)
        sorted = ''.join(sorted)
    elif inputType == 'dict':
        sorted = list(sorted)
        unsorted = list(unsorted)
    else:
        exec('sorted=' + inputType + '(sorted)')
        exec('unsorted=' + inputType + '(unsorted)')

    return (sorted + unsorted)
Пример #17
0
def normalize(*args):#normalize a vector
	aa=[]
	v=[]
	for a in args:
		if isIterable(a):
			aa.extend(a)
		else:
			aa.append(a)
	for a in aa:
		if isinstance(a,(float,int,long)):
			v.append(float(a))
	if len(v)<3: 
		raise Exception('normalize requires an input of 3 numbers')
	if len(v)>3: v[:]=v[:3]		
	factor=1.0
	vLen=v[0]*v[0]+v[1]*v[1]+v[2]*v[2];
	if vLen==0: return
	factor=1.0/sqrt(vLen)
	if factor!=1.0:
		v[0]*=factor
		v[1]*=factor
		v[2]*=factor
	return v
Пример #18
0
    def addInfluences(self, *influences, **keywords):

        controlObjects = [""]
        baseShapes = [""]
        wrapSmoothness = [1]
        nurbsSamples = [10]
        smooth = -1
        smoothType = 0
        influences = list(influences)

        shortNames = {"co": "controlObjects"}

        for k in keywords:
            if k in locals():
                exec(k + "=keywords[k]")
            elif k in shortNames:
                exec(shortNames[k] + "=keywords[k]")

        controlObjects = iterable(controlObjects)
        baseShapes = iterable(baseShapes)
        wrapSmoothness = iterable(wrapSmoothness)
        nurbsSamples = iterable(nurbsSamples)

        if self.influences == influences:
            self.influences = []
        else:
            influencesHold = influences
            for inf in influencesHold:
                if inf in self.influences:
                    influences.remove(inf)
                else:
                    self.influences.append(inf)

        while len(controlObjects) < len(influences):
            controlObjects.append(controlObjects[-1])
        while len(baseShapes) < len(influences):
            baseShapes.append(baseShapes[-1])
        while len(wrapSmoothness) < len(influences):
            wrapSmoothness.append(wrapSmoothness[-1])
        while len(nurbsSamples) < len(influences):
            nurbsSamples.append(nurbsSamples[-1])

        for i in range(0, len(influences)):

            bsh = baseShapes[i]
            inf = influences[i]
            ctrlObj = controlObjects[i]
            nurbsSample = self.nurbsSamples[i]
            wrapSmooth = self.wrapSmoothness[i]
            infFaces = []
            infSourceShape = ""
            infShape = ""
            infTr = ""
            shapeType = ""

            if isinstance(inf, basestring):

                if len(inf.split(".")) > 1:

                    shapeType = str(mc.getAttr(inf, type=True))

                    if (
                        len(iterable(mc.ls(inf, o=True, type="dagNode"))) > 0
                        and len(iterable(mc.listRelatives(mc.ls(inf, o=True), p=True))) > 0
                    ):
                        infTr = mc.listRelatives(mc.ls(inf, o=True), p=True)[0]
                        infShape = shape(infTr)
                    else:
                        infShapeHist = iterable(mc.ls(iterable(mc.listHistory(inf, f=True, af=True)), type="shape"))
                        if len(infShapeHist) > 0:
                            infShape = infShapeHist[0]
                            infTr = mc.listRelatives(infShape, p=True)

                else:

                    shapeType = mc.nodeType(inf)
                    infShape = infSourceShape = inf
                    infTr = mc.listRelatives(inf, p=True)

            elif isIterable(inf):

                infShape = mc.ls(inf, o=True)[0]
                infTr = mc.listRelatives(infShape, p=True)[0]
                shapeType = mc.nodeType(infShape)

                if mc.nodeType(infShape) == "mesh":

                    inf = mc.polyListComponentConversion(inf, tf=True)

                    inputComponents = []
                    for fStr in inf:
                        inputComponents.append(fStr.split(".")[-1])

                    pco = mc.createNode("polyChipOff")
                    mc.setAttr(pco + ".dup", True)
                    mc.setAttr(pco + ".inputComponents", len(inputComponents), type="componentList", *inputComponents)
                    mc.connectAttr(infShape + ".outMesh", pco + ".ip")

                    psep = mc.createNode("polySeparate")
                    mc.setAttr(psep + ".ic", 2)
                    mc.connectAttr(pco + ".out", psep + ".ip")

                    inf = psep + ".out[1]"

                    if not (isinstance(bsh, basestring) and mc.objExists(bsh)):

                        bshSource = ""

                        for m in removeAll(infShape, mc.ls(iterable(mc.listHistory(infShape)), type="mesh")):

                            if (
                                len(mc.ls(m + ".vtx[*]", fl=True)) == len(mc.ls(infShape + ".vtx[*]", fl=True))
                                and len(mc.ls(m + ".f[*]", fl=True)) == len(mc.ls(infShape + ".f[*]", fl=True))
                                and len(mc.ls(m + ".e[*]", fl=True)) == len(mc.ls(infShape + ".e[*]", fl=True))
                                and len(removeAll(m, mc.listHistory(m))) == 0
                            ):
                                isBSTarget = False
                                for bsConn in iterable(mc.listConnections(m, type="blendShape", p=True)):
                                    if "inputTarget" in ".".join(bsConn.split(".")[1:]):
                                        isBSTarget = True
                                        break
                                if isBSTarget:
                                    continue
                                else:
                                    bshSource = m
                                    break

                        if bshSource == "":

                            bshSource = mc.createNode("mesh", p=infTr)
                            mc.connectAttr(infShape + ".outMesh", bshSource + ".inMesh")
                            mc.blendShape(infShape, bshSource, w=[1, 1])
                            mc.delete(bshSource, ch=True)
                            mc.setAttr(bshSource + ".io", True)

                        pco = mc.createNode("polyChipOff")
                        mc.setAttr(pco + ".dup", True)
                        mc.setAttr(
                            pco + ".inputComponents", len(inputComponents), type="componentList", *inputComponents
                        )
                        mc.connectAttr(bshSource + ".outMesh", pco + ".ip")

                        psep = mc.createNode("polySeparate")
                        mc.setAttr(psep + ".ic", 2)
                        mc.connectAttr(pco + ".out", psep + ".ip")

                        bsh = psep + ".out[1]"

                else:

                    inf = infShape

            plug = firstOpenPlug(self[0] + ".basePoints")

            if isinstance(inf, basestring) and mc.objExists(inf):

                if len(inf.split(".")) <= 1:

                    if mc.nodeType(shape(inf)) == "mesh":
                        inf = shape(inf) + ".outMesh"
                    else:
                        inf = shape(inf) + ".local"

            if isinstance(bsh, basestring) and mc.objExists(bsh):

                if len(bsh.split(".")) <= 1:

                    if mc.nodeType(shape(bsh)) == "mesh":
                        bsh = shape(bsh) + ".outMesh"
                    else:
                        bsh = shape(bsh) + ".local"

            else:

                bshShape = mc.createNode(shapeType)

                if shapeType == "mesh":
                    mc.connectAttr(inf, bshShape + ".inMesh")
                    mc.blendShape(infShape, bshShape, w=(1, 1))
                    mc.delete(bshShape, ch=True)
                    bsh = bsh + ".outMesh"
                else:
                    mc.connectAttr(inf, bshShape + ".create")
                    mc.blendShape(infShape, bshShape, w=(1, 1))
                    mc.delete(bshShape, ch=True)
                    bsh = bsh + ".local"

                mc.setAttr(bshShape + ".io", True)

                # mc.connectAttr(inf,self[0]+'.driverPoints['+str(plug)+']',f=True)
                # mc.connectAttr(bsh,self[0]+'.basePoints['+str(plug)+']',f=True

                # poly smooth
            if shapeType == "mesh":

                pspInf = mc.createNode("polySmoothProxy")
                mc.setAttr(pspInf + ".kb", False)
                mc.connectAttr(inf, pspInf + ".ip")
                inf = pspInf + ".out"

                pspBase = mc.createNode("polySmoothProxy")
                mc.setAttr(pspBase + ".kb", False)
                mc.connectAttr(bsh, pspBase + ".ip")
                bsh = pspBase + ".out"

            mc.connectAttr(inf, self[0] + ".driverPoints[" + str(plug) + "]", f=True)
            mc.connectAttr(bsh, self[0] + ".basePoints[" + str(plug) + "]", f=True)

            # add wrap control attributes

            if not mc.objExists(ctrlObj):
                ctrlObj = infTr

            if shapeType == "mesh":

                if not "wrapSmoothLevels" in mc.listAttr(ctrlObj):
                    mc.addAttr(ctrlObj, ln="wrapSmoothLevels", at="short", dv=0)

                mc.setAttr(ctrlObj + ".wrapSmoothLevels", k=False, cb=True)
                mc.connectAttr(ctrlObj + ".wrapSmoothLevels", pspInf + ".el")
                mc.connectAttr(ctrlObj + ".wrapSmoothLevels", pspBase + ".el")
                mc.connectAttr(ctrlObj + ".wrapSmoothLevels", pspInf + ".ll")
                mc.connectAttr(ctrlObj + ".wrapSmoothLevels", pspBase + ".ll")

                if not "wrapSmoothType" in mc.listAttr(ctrlObj):
                    mc.addAttr(
                        ctrlObj, ln="wrapSmoothType", at="enum", en="exponential:linear", min=0, max=1, dv=smoothType
                    )

                mc.setAttr(ctrlObj + ".wrapSmoothType", k=False, cb=True)
                mc.connectAttr(ctrlObj + ".wrapSmoothType", pspInf + ".mth")
                mc.connectAttr(ctrlObj + ".wrapSmoothType", pspBase + ".mth")

                if not "inflType" in mc.listAttr(ctrlObj):
                    mc.addAttr(ctrlObj, ln="inflType", at="enum", en="none:point:face", min=1, max=2, dv=2)

                mc.setAttr(ctrlObj + ".inflType", k=False, cb=True)
                mc.connectAttr(ctrlObj + ".inflType", self[0] + ".inflType[" + str(plug) + "]")

            else:
                if not "nurbsSamples" in mc.listAttr(ctrlObj):
                    mc.addAttr(ctrlObj, ln="nurbsSamples", at="short", dv=nurbsSample)

                mc.setAttr(ctrlObj + ".nurbsSamples", k=False, cb=True)
                mc.connectAttr(ctrlObj + ".nurbsSamples", self[0] + ".nurbsSamples[" + str(plug) + "]")

            if self.calculateMaxDistance:

                greatestDistance = 0.0

                if shapeType == "mesh":

                    distCheckMesh = mc.createNode("mesh", p=infTr)
                    mc.connectAttr(inf, distCheckMesh + ".inMesh")

                    deformedCP = ""
                    if mc.nodeType(shape(self.deformed[0])) == "mesh":
                        deformedCP = mc.createNode("closestPointOnMesh")
                        mc.connectAttr(self.deformed[0] + ".worldMesh[0]", deformedCP + ".im")
                    elif mc.nodeType(shape(self.deformed[0])) == "nurbsCurve":
                        deformedCP = mc.createNode("closestPointOnCurve")
                        mc.connectAttr(self.deformed[0] + ".worldSpace", deformedCP + ".ic")
                    elif mc.nodeType(shape(self.deformed[0])) == "nurbsSurface":
                        deformedCP = mc.createNode("closestPointOnSurface")
                        mc.connectAttr(self.deformed[0] + ".worldSpace", deformedCP + ".is")

                    for f in mc.ls(distCheckMesh + ".f[*]", fl=True):

                        center = midPoint(f)
                        mc.setAttr(deformedCP + ".ip", *center)
                        closestPoint = mc.getAttr(deformedCP + ".p")[0]
                        distance = distanceBetween(closestPoint, center)

                        if distance > greatestDistance:
                            greatestDistance = distance

                    mc.disconnectAttr(inf, distCheckMesh + ".inMesh")
                    mc.delete(distCheckMesh)

                if greatestDistance * 2 > mc.getAttr(self[0] + ".maxDistance"):
                    mc.setAttr(self[0] + ".maxDistance", greatestDistance * 2)

            if shapeType == "mesh":

                if smooth >= 0:

                    mc.setAttr(ctrlObj + ".wrapSmoothLevels", smooth)

                elif mc.nodeType(shape(self.deformed[0])) == "mesh":

                    faceCount = 0
                    for d in self.deformed:
                        if mc.nodeType(shape(d)) == "mesh":
                            faceCount += len(mc.ls(shape(d) + ".f[*]", fl=True))

                    smoothSampleMesh = mc.createNode("mesh", p=infTr)
                    mc.connectAttr(inf, smoothSampleMesh + ".inMesh")

                    smoothFaceCount = 0
                    n = 0

                    while len(mc.ls(smoothSampleMesh + ".f[*]", fl=True)) < faceCount:
                        mc.setAttr(ctrlObj + ".wrapSmoothLevels", n)
                        n += 1

                    if len(mc.ls(smoothSampleMesh + ".f[*]", fl=True)) > faceCount * 1.5:
                        mc.setAttr(ctrlObj + ".wrapSmoothLevels", mc.getAttr(ctrlObj + ".wrapSmoothLevels") - 1)

                    mc.disconnectAttr(inf, smoothSampleMesh + ".inMesh")
                    mc.delete(smoothSampleMesh)
Пример #19
0
	def generateScript(self):
		
		returnVal=self.Muscle+'=zen.Muscle\\\n'
		returnVal+='(\n'
			
		connections=mc.listConnections(self.Handle+'.zmi',type='transform')
		
		if isIterable(connections) and len(connections)>0:#if this is a mirrored Handle use the original
			if(len(connections)==1):
				if(mc.objExists(connections[0]+'.zmi')):
					opposite=Muscle(Handle=connections[0])
					return(opposite.generateScript())
					
		self.getInfluences()
		
		selectionGroups=[]
		parentConstraintWeights=[]
		
		n=0
		
		for i in range(0,len(self.influences)):#get the span components
			
			selectionGroups.append([])
			#parentConstraintWeights.append({})
			
			mesh=str(self.influences[i]['mesh'])
			curves=self.influences[i]['curves']
			edges=self.influences[i]['edges']
			parents=self.influences[i]['parents']
			
			if(len(parents)):
				for p in parents:
					for pc in p:
						if pc not in selectionGroups[i]: selectionGroups[i].append(pc)
						#parentConstraintWeights[i][pc]=p[pc]
					parentConstraintWeights.append(p)
			if(len(edges)):
				for e in edges:
					for ee in e:
						selectionGroups[i].append(ee)
			else:
				for c in curves:
					selectionGroups[i].append(c)
	
		for i in range(0,len(selectionGroups)):#span selection groups
			returnVal+='	['
			for n in range(0,len(selectionGroups[i])):
				returnVal+='"'+selectionGroups[i][n]+'"'
				if(n==len(selectionGroups[i])-1):
					returnVal+='],\n'
				else:
					returnVal+=','
		
		#set the parent constraint weights
		returnVal+='	pcw=['
		
		dStrings=[]
		for i in range(0,len(parentConstraintWeights)):
			returnVal+='{'
			
			diStrings=[]
			for x in parentConstraintWeights[i]:
				diStrings.append('"'+x+'":'+str(parentConstraintWeights[i][x]))
			
			returnVal+=','.join(diStrings)
			if(i<len(parentConstraintWeights)-1):
				returnVal+='},'
			else:
				returnVal+='}]'
		
		attrList=[]
		delList=[]
		attrList.extend(mc.listAttr(self.Handle,k=True))
		attrList.extend(mc.listAttr(self.Handle,cb=True))
			
		for i in range(0,len(attrList)):
			if mc.objExists(self.Handle+'.'+attrList[i]) and mc.getAttr(self.Handle+'.'+attrList[i],type=True)!='message':
				c=mc.listConnections(self.Handle+'.'+attrList[i],s=True,d=False)
				if isIterable(c) and len(c)>0:
					delList.append(attrList[i])
			else:
				delList.append(attrList[i])
		
		delList.extend(['visibility','translateX','translateY','translateZ','rotateX','rotateY','rotateZ','scaleX','scaleY','scaleZ'])
		for d in delList:
			attrList.remove(d)
				
		tempList=attrList
		attrList=[]
		
		for a in tempList:
			if(len(a.split('.'))==1 and mc.getAttr(self.Handle+'.'+a,type=True)!='message'):
				attrList.append(a)
		
		if(len(attrList)>0):
			returnVal+=',\n	'
			for i in range(0,len(attrList)):
				returnVal+=attrList[i]+'='+str(mc.getAttr(self.Handle+'.'+attrList[i]))
				if(i<len(attrList)-1):
					returnVal+=','
					
		returnVal+=',\n'
		
		#get the name
		if "opposite" in self.__dict__:
			returnVal+='	name=["'+self.Muscle+'","'+self.opposite.Muscle+'"],\n'
		else:
			returnVal+='	name="'+self.Muscle+'",\n'
			
		returnVal+='	axis='+str(self.getAxis())+','
		
		returnVal+='spans='+str(self.spans)+','
			
		if(mc.objExists(self.Handle+'.jiggle')):
			returnVal+='jiggle=True\n'
		else:
			returnVal+='jiggle=False\n'
			
		returnVal+=')\n'
		
		#auto-flex
		
		autoFlexPlugs=mc.ls(self.Handle+'.zaf[*]')
		
		if(isinstance(autoFlexPlugs,list) and len(autoFlexPlugs)>0):
		
			for p in autoFlexPlugs:
				
				infAttrs=mc.listConnections(p+'.zenPoseAttr',p=True,s=True,d=False)
				infAttrValues=[]

				if isIterable(infAttrs):
					for i in range(0,len(infAttrs)):
						attributeValue=mc.getAttr(p+'.zenAttrVal['+str(i)+']')
						if(isinstance(attributeValue,(float,int,long))):
							infAttrValues.append(attributeValue)
						elif(isIterable(attributeValue)):
							infAttrValues.append(attributeValue[0])

				counter=0
				
				if(isinstance(infAttrs,list) and isinstance(infAttrValues,list)):
					
					length=len(infAttrs)
					if(len(infAttrValues)<length): length=len(infAttrValues)
					if(length>0):
						if(counter==0):
							returnVal+=self.Muscle+'.addAutoFlex\\\n(\n'
							if "opposite" in self.__dict__:
								returnVal+='	mirror=True,\n'
							returnVal+='	pose={'
						for i in range(0,length):
							returnVal+='"'+infAttrs[i]+'":'+str(infAttrValues[i])
							if(i<length-1):
								returnVal+=','
							else:
								returnVal+='},\n	'
								
					attrList=mc.listAttr(p,leaf=True)
					if(isinstance(attrList,list) and len(attrList)>0):
						ii=0
						for i in range(0,len(attrList)):
							if mc.objExists(p+'.'+attrList[i]):
								c=mc.listConnections(p+'.'+attrList[i],s=True,d=False)
								if\
								(
									mc.getAttr(p+'.'+attrList[i],type=True)=='double' and 
									(
										not(isIterable(c)) or 
										len(c)==0 or
										mc.ls(c,o=True)[0]==mc.ls(p,o=True)[0]
									)
								):
									if(ii>0): returnVal+=','
									returnVal+=attrList[i]+'='+str(mc.getAttr(p+'.'+attrList[i]))
									ii+=1
								
					counter+=1
					
				if(counter>0):
					returnVal+='\n)\n'
			
		return returnVal
Пример #20
0
	def __init__(self,*args,**keywords):

		#check to make sure unique names are used in scene
		uniqueNames(iterable(mc.ls(type='dagNode')),re=True)

		# default options
		self.createSurface=False # use for IK's etc. - creates a surface instead of a curve
		self.scaleLength=True # use for IK's etc. - compensates for scale

		self.stretch=-1 # maximum stretch %: 0 > Infinity
		self.squash=-1 # maximum squash %: 0 > 100
		self.arcWeight=.5 # controls the balance of rotational control weight alloted to the end Handle vs the base Handle
		self.width=1 # surface width
		self.length=10 # only used if no arguments are passed

		self.parents=['',''] # create under parent or parents
		self.softParents=['','']
		self.parentSpaces=['','']
		self.names=['ArcCtrl#','arcCtrl_handle#'] #
		self.handleType=['locator','locator'] # see 'Handle' class - 'locator','doubleEllipse',
		self.handleOptions=[{},{}] # dictionaries passed on to the Handle class for options concerning placement of handles

		self.aim=(0,1,0)
		self.poleVector=(0,0,1) # if only two arc points are given, it will try to point the arc in this direction if possible


		# option abbreviations
		shortNames=\
		{
			'p':'parents',
			'cs':'createSurface',
			'pv':'poleVector',
			'st':'stretch',
			'sq':'squash',
			'cs':'createSurface',
			'n':'names',
			'ho':'handleOptions',
			'w':'width',
			'pv':'poleVector',
			'aw':'arcWeight',
			'ht':'handleType',
			'sp':'softParents'
		}

		if 'shortNames' in self.__dict__: # this is done so that we don't wipe out added short names in inheriting classes
			for sn in shortNames:
				self.shortNames[sn]=shortNames[sn]
		else:
			self.shortNames=shortNames

		for k in keywords: #get user options
			if k in self.shortNames:
				exec('self.'+self.shortNames[k]+'=keywords[k]')
			elif k in self.__dict__:
				exec('self.'+k+'=keywords[k]')

		#check and format options

		if\
		(
			len(iterable(self.aim))<3 or
			not isinstance(self.aim[0],(float,int,long)) or
			not isinstance(self.aim[1],(float,int,long)) or
			not isinstance(self.aim[2],(float,int,long))
		):
			self.aim=(0,1,0)
		if\
		(
			len(iterable(self.poleVector))<3 or
			not isinstance(self.poleVector[0],(float,int,long)) or
			not isinstance(self.poleVector[1],(float,int,long)) or
			not isinstance(self.poleVector[2],(float,int,long))
		):
			self.poleVector=(0,0,1)

		self.aim=normalize(self.aim)
		self.poleVector=normalize(self.poleVector)

		if len(iterable(self.softParents))==1:
			self.softParents=[iterable(self.softParents)[0],iterable(self.softParents)[0]]
		elif len(iterable(self.softParents))==0:
			self.softParents=['','']

		if len(iterable(self.parents))==1:
			self.parents=[iterable(self.parents)[0],iterable(self.parents)[0]]
		elif len(iterable(self.parents))==0:
			self.parents=['','.']

		if len(iterable(self.names))==1:
			self.names=[iterable(self.names)[0],iterable(self.names)[0]]
		if len(iterable(self.names))==0:
			self.names=['','']

		if len(iterable(self.handleType))==1:
			self.handleType=[iterable(self.handleType)[0],iterable(self.handleType)[0]]
		if len(iterable(self.handleType))==0:
			self.handleType=['','']

		if isinstance(self.handleOptions,dict): self.handleOptions=[self.handleOptions,self.handleOptions]
		if isinstance(self.handleOptions,(list,tuple)) and\
			len(self.handleOptions)==1 and\
			isinstance(self.handleOptions[0],dict):
				self.handleOptions=[self.handleOptions[0],self.handleOptions[0]]

		if self.stretch>=0 and self.squash<0 or self.stretch<0 and self.squash>=0:# squash & stretch come as a pair, set one to 0 if only 1 is set
			if self.stretch<0: self.stretch=0
			if self.squash<0: self.squash=0

		if not isinstance(self.poleVector,tuple): self.poleVector=tuple(self.poleVector)

		# attributes
		self.outputCurve=''
		self.outputNormal=''
		self.surface=''
		self.outputSurface=''
		self.handleShapes=[]
		self.curveShapes=[]
		self.arcPoints=[]
		self.handles=[]

		# parse arguments
		if len(args)==0: args=iterable(mc.ls(sl=True,fl=True)) # if no arguments are input, use selection
		if len(args)==0: args=[[0.0,0.0,0.0]]

		sel=[]
		for a in args:
			if isIterable(a) and not isinstance(a[0],(float,long,int)):
				sel.extend(a)
			else:
				sel.append(a)
		for s in sel:
			if isIterable(s) and isinstance(s[0],(float,long,int)) and len(s)>=3:
				self.arcPoints.append(s)
			elif isinstance(s,basestring) and mc.objExists(s):
				err=True
				if len(s.split('.'))>1:
					try:
						self.arcPoints.append(mc.pointPosition(s))
						err=False
					except:
						err=True
				else:
					try:
						self.arcPoints.append(mc.pointPosition(s+'.rp'))
						err=False
					except:
						err=True

		if len(self.arcPoints)<2:
			if len(self.arcPoints)==0: self.arcPoints=[[0.0,0.0,0.0]]
			self.arcPoints=\
			[
				self.arcPoints[0],
				[
					float(self.arcPoints[0][0])+float(self.aim[0])*self.length,
					float(self.arcPoints[0][1])+float(self.aim[1])*self.length,
					float(self.arcPoints[0][2])+float(self.aim[2])*self.length
				]
			]

		self.create()
Пример #21
0
	def __init__(self,*args,**keywords):
		
		#set defaults
		name=''
		self.spanGroups={}
		attributes={}
		self.axis=0
		self.jiggle=0
		self.script=0
		self.cMuscleShape=''
		self.Muscle=''
		self.muscleShape=''
		self.Handle=''
		self.allCurves=[]
		self.selectionGroups=[]
		pcw={}
		self.resMult=1.5
		self.spans=12
		
		for k in keywords:
			
			if(isinstance(keywords[k],list) and (k=='pcw' or k=='parentConstraintWeights')):#interpret parent constraint weights
				pcw=keywords[k]
			if(isinstance(keywords[k],bool)):#convert booleans to integers
				exec('self.'+k+'='+str(int(keywords[k])))
			elif(k=='axis'):#convert axis input to integer
				if(isinstance(keywords[k],str)):
					if(keywords[k].lower()=='x'):
						self.axis=1
					if(keywords[k].lower()=='y'):
						self.axis=2
					if(keywords[k].lower()=='z'):
						self.axis=3
				elif(isinstance(keywords[k],int)):
					self.axis=keywords[k]
			elif(k=='name'):
				name=keywords[k]
			elif(k in self.__dict__):
				exec('self.'+k+'=keywords[k]')
			else:
				attributes[k]=keywords[k]
		
		if len(args)==0 and len(self.Handle)==0 and len(self.Muscle)==0 and len(self.muscleShape)==0: args=mc.ls(sl=True)
		
		for arg in args:
			if(isinstance(arg,list)):
				aList=arg
			else:
				aList=[arg]
			sList=aList
			for a in aList:	
				if(mc.objExists(a) and mc.ls(a,o=True)[0]==mc.ls(a)[0]):
					if(mc.objExists(a+'.zmi')):
						self.Handle=a
						sList.remove(a)
					else:
						if(mc.nodeType(a)=='nurbsSurface'):
							aShape=a
						else:
							try: aShape=mc.listRelatives(c=True,s=True,ni=True,type='nurbsSurface')[0]
							except: aShape=''

						if(mc.objExists(aShape)):
							messageConnections=mc.listConnections(aShape+'.message',p=True,d=True,s=False)	
							if(isinstance(messageConnections,list) and len(messageConnections)>0):
								for c in mc.listConnections(a+'.message',p=True,d=True):
									if(c.split('.')[1]=='zenMuscle'):
										self.Handle=c.split('.')[0]
										sList.remove(a)
			if isIterable(sList) and len(sList)>0: self.selectionGroups.append(sList)
			
		if(len(self.Muscle)>0 and len(self.muscleShape)==0):
			try: 
				self.muscleShape=mc.listRelatives(self.Muscle,s=True,ni=True,type='nurbsSurface')[0]
			except:
				pass
			
		if(len(self.muscleShape)>0 and len(self.Handle)==0):
			for c in listConnections(self.muscleShape+'.message',p=True,d=True,s=False):
				if(c.split('.')[1]=='zenMuscle'):
					self.Handle=c.split('.')[0]
					break
					
		if(len(self.Handle)>0 and len(self.Muscle)==0 and mc.objExists(self.Handle+'.zenMuscle')): #if we know the Handle already, get the Muscle
			try:	self.Muscle=mc.listConnections(self.Handle+'.zenMuscle')[0]
			except:	pass
			
		if(len(self.Handle)>0 and len(self.muscleShape)==0 and mc.objExists(self.Handle+'.zenMuscle')):#get the Muscle shape
			try:	self.muscleShape=mc.listConnections(self.Handle+'.zenMuscle',sh=True)[0]
			except:	pass
			try:	self.handleGroup=mc.listConnections(self.Handle+'.zenMuscleCtrlGroup')[0]
			except: pass
			
		if(len(self.Handle)>0 and self.axis>=0):#see if there is an opposite
			if(isinstance(mc.listConnections(self.Handle+'.zenOpposite'),list)):
				opp=mc.listConnections(self.Handle+'.zenOpposite')[0]
				if(mc.objExists(opp)):
					self.opposite=Muscle(Handle=opp,axis=-1)
					
		if len(self.muscleShape):
			self.spans=mc.getAttr(self.muscleShape+'.spansU')
			
		if( len(self.selectionGroups)>0 ):
				
			if(len(self.Muscle)==0 and len(self.Handle)==0):
				self.create()
				
		self.getInfluences()
		
		if( len(self.selectionGroups)>0 ):
			
			if(len(name)>0):                                     
				if(isinstance(name,str)):
					self.rename(name)
				elif(isinstance(name,list)):
					self.rename(name[0])
					if "opposite" in self.__dict__:
						self.opposite.rename(name[1])
						
			self.setAttributes(**attributes)
			self.setParentConstraintWeights(*pcw)
Пример #22
0
	def create(self):

		worldMatrixNode=mc.createNode('fourByFourMatrix')
		wm=\
		[
			[1,0,0,0],
			[0,1,0,0],
			[0,0,1,0],
			[0,0,0,1]
		]
		for a in range(0,4):
			for b in range(0,4):
				mc.setAttr( worldMatrixNode+'.in'+str(a)+str(b), wm[a][b] )

		self.worldMatrix=worldMatrixNode+'.o'

		wsMatrices=[]

		cleanup=[]

		lattices=[]
		uvPos=[]
		antipodes=[]

		cpos=mc.createNode('closestPointOnSurface')

		if 'surfaceAttr' not in self.__dict__ or len(self.surfaceAttr)==0 and len(self.edges)>0:
			mc.select(self.edges)
			rebuildNode,surfaceNodeTr=mel.eval('zenLoftBetweenEdgeLoopPathRings(2)')[:2]
			self.surfaceAttr=rebuildNode+'.outputSurface'

			children=mc.listRelatives(surfaceNodeTr,c=True,s=True,ni=True,type='nurbsSurface')
			if isIterable(children) and len(children)>0:
				self.uSpans=mc.getAttr(children[0]+'.spansU')
				self.vSpans=mc.getAttr(children[0]+'.spansV')

			mc.disconnectAttr(self.surfaceAttr,surfaceNodeTr+'.create')
			mc.delete(surfaceNodeTr)


		if self.uSpans<0 or self.vSpans<0:
			tempTr=mc.createNode('transform')
			tempCurve=mc.createNode('nurbsCurve',p=tempTr)
			mc.connectAttr(self.surfaceAttr,tempCurve+'.create')
			self.uSpans=mc.getAttr(tempCurve+'.spansU')
			self.vSpans=mc.getAttr(tempCurve+'.spansV')
			mc.disconnectAttr(self.surfaceAttr,tempCurve+'.create')
			mc.delete(tempTr)

		orderedTrs=[]
		orderedCtrls=[]

		if self.distribute not in ['u','v']: #calculate the axis of distribution
			if len(self.trs)!=0:
				mc.connectAttr(self.surfaceAttr,cpos+'.inputSurface')
				uMin=100
				vMin=100
				uMax=0
				vMax=0
				uPosList=[]
				vPosList=[]

				for i in range(0,self.number):

					orderedTrs.append('')
					orderedCtrls.append('')
					t=self.trs[i]

					if mc.objExists(t): # find the closest point
						if self.hasGeometry:
							center=mc.objectCenter(t)
							mc.setAttr(cpos+'.ip',*center)
							posCenter,uCenter,vCenter=mc.getAttr(cpos+'.p')[0],mc.getAttr(cpos+'.u'),mc.getAttr(cpos+'.v')

						rp=mc.xform(t,ws=True,q=True,rp=True)
						mc.setAttr(cpos+'.ip',*rp)
						posRP,uRP,vRP=mc.getAttr(cpos+'.p')[0],mc.getAttr(cpos+'.u'),mc.getAttr(cpos+'.v')

						# see which is closer - object center or rotate pivot
						if self.hasGeometry:
							distCenter=distanceBetween(posCenter,center)
							distRP=distanceBetween(posRP,rp)

						if self.hasGeometry==False or abs(distCenter)>abs(distRP) :
							uPosList.append(uRP)
							vPosList.append(vRP)
							if uRP<uMin: uMin=uRP
							if uRP>uMax: uMax=uRP
							if vRP<vMin: vMin=vRP
							if vRP>vMax: vMax=vRP
						else:
							uPosList.append(uCenter)
							vPosList.append(vCenter)
							if uCenter<uMin: uMin=uCenter
							if uCenter>uMax: uMax=uCenter
							if vCenter<vMin: vMin=vCenter
							if vCenter>vMax: vMax=vCenter

			cfsi=mc.createNode('curveFromSurfaceIso')

			mc.connectAttr(self.surfaceAttr,cfsi+'.is')
			mc.setAttr(cfsi+'.idr',0)
			mc.setAttr(cfsi+'.iv',.5)
			mc.setAttr(cfsi+'.r',True)
			mc.setAttr(cfsi+'.rv',True)

			if len(self.trs)!=0:
				mc.setAttr(cfsi+'.min',uMin)
				mc.setAttr(cfsi+'.max',uMax)

			ci=mc.createNode('curveInfo')
			mc.connectAttr(cfsi+'.oc',ci+'.ic')
			uLength=mc.getAttr(ci+'.al')

			mc.setAttr(cfsi+'.idr',1)

			if len(self.trs)!=0:
				mc.setAttr(cfsi+'.min',vMin)
				mc.setAttr(cfsi+'.max',vMax)

			vLength=mc.getAttr(ci+'.al')

			mc.delete(cfsi,ci)

			if uLength>vLength:
				self.distribute='u'

				if len(self.trs)!=0:
					searchList=uPosList
					orderedList=uPosList[:]
					orderedList.sort()
			else:
				self.distribute='v'

				if len(self.trs)!=0:
					searchList=vPosList
					orderedList=vPosList[:]
					orderedList.sort()

			reverseTrs=False

			orderIDList=[]
			for n in range(0,self.number):
				s=searchList[n]
				for i in range(0,self.number):
					if s==orderedList[i] and i not in orderIDList:
						orderIDList.append(i)
						orderedTrs[i]=self.trs[n]
						orderedCtrls[i]=self.ctrls[n]
						if n==0 and i>len(self.trs)/2:
							reverseTrs=True
						break

			if reverseTrs:
				orderedTrs.reverse()
				self.trs=orderedTrs
				orderedCtrls.reverse()
				self.ctrls=orderedCtrls
			else:
				self.trs=orderedTrs
				self.ctrls=orderedCtrls

		if self.rebuild: # interactive rebuild, maintains even parameterization over the rivet surface, use with caution

			if self.distribute=='u':
				self.surfaceAttr=mel.eval('zenUniformSurfaceRebuild("'+self.surfaceAttr+'",'+str(self.uSpans*2)+',-1)')+'.outputSurface'
			else:
				self.surfaceAttr=mel.eval('zenUniformSurfaceRebuild("'+self.surfaceAttr+'",-1,'+str(self.vSpans*2)+')')+'.outputSurface'

		if not mc.isConnected(self.surfaceAttr,cpos+'.inputSurface'):
			mc.connectAttr(self.surfaceAttr,cpos+'.inputSurface',f=True)

		if self.taper=='distance' or self.createAimCurve or self.closestPoint=='geometry': # find the closest points ( and antipodes )

			for i in range(0,self.number):
				t=self.trs[i]
				cp=ClosestPoints(self.surfaceAttr,t)
				self.ClosestPoints.append(cp)

				if self.taper=='distance' or self.createAimCurve: # antipodes are used for lattice allignment and curve calculations
					antipodes.append(cp.getAntipodes(1))

		if self.taper!='none' or self.scale!='none': # measures scale with scaling

			cfsiLength=mc.createNode('curveFromSurfaceIso')
			ciLength=mc.createNode('curveInfo')
			lengthMultiplierNode=mc.createNode('multDoubleLinear')

			mc.setAttr(cfsiLength+'.relative',True)
			mc.setAttr(cfsiLength+'.relativeValue',True)

			if self.distribute=='u':
				mc.setAttr(cfsiLength+'.isoparmDirection',0)
			else:
				mc.setAttr(cfsiLength+'.isoparmDirection',1)

			mc.setAttr(cfsiLength+'.minValue',0)
			mc.setAttr(cfsiLength+'.maxValue',1)

			mc.setAttr(cfsiLength+".isoparmValue",.5)

			mc.connectAttr(self.surfaceAttr,cfsiLength+'.inputSurface')

			if mc.objExists(self.spaceTr):

				lengthCurve=mc.createNode('nurbsCurve',p=self.spaceTr)
				lengthCurveTG=mc.createNode('transformGeometry')

				mc.connectAttr(self.spaceTr+'.worldMatrix[0]',lengthCurveTG+'.txf')
				mc.connectAttr(cfsiLength+'.outputCurve',lengthCurveTG+'.ig')
				mc.connectAttr(lengthCurveTG+'.og',lengthCurve+'.create')
				mc.connectAttr(lengthCurve+'.worldSpace',ciLength+'.inputCurve')
				mc.setAttr(lengthCurve+'.intermediateObject',True)

				cleanup.extend([lengthCurveTG,cfsiLength])

			else:

				mc.connectAttr(cfsiLength+'.outputCurve',ciLength+'.inputCurve')

			mc.connectAttr(ciLength+'.al',lengthMultiplierNode+'.i1')
			mc.setAttr(lengthMultiplierNode+'.i2',1.0/float(mc.getAttr(ciLength+'.al')))

			lengthMultiplier=lengthMultiplierNode+'.o'


		uvPos=[]
		closestDistanceToCenter=Decimal('infinity')
		centerMostRivetID=0
		closestDistancesToCenter=[Decimal('infinity'),Decimal('infinity')]
		centerMostRivetIDs=[0,0]

		uvMultipliers=[]
		aimGroups=[]

		for i in range(0,self.number):

			pTrs=mc.listRelatives(self.trs[i],p=True)
			parentTr=''
			if len(iterable(pTrs))>0:
				parentTr=pTrs[0]

			t=self.trs[i]
			c=self.ctrls[i]
			r=mc.createNode('transform',n='Rivet#')

			wsMatrices.append(mc.xform(t,q=True,ws=True,m=True))

			if self.constraint: mc.setAttr(r+'.inheritsTransform',False)

			if not mc.objExists(c):
				c=t
				if not mc.objExists(t):
					c=r

			if not mc.objExists(c+'.zenRivet'):
				mc.addAttr(c,at='message',ln='zenRivet',sn='zriv')

			mc.connectAttr(r+'.message',c+'.zriv',f=True)

			if not mc.objExists(c+'.uPos'):
				mc.addAttr(c,k=True,at='double',ln='uPos',dv=50)
			if not mc.objExists(c+'.vPos'):
				mc.addAttr(c,k=True,at='double',ln='vPos',dv=50)

			if self.closestPoint=='geometry':
				up,vp=self.ClosestPoints[i].uvs[0]
			else:
				if mc.objExists(t):
					if self.hasGeometry:
						center=mc.objectCenter(t)
						mc.setAttr(cpos+'.ip',*center)
						posCenter,uCenter,vCenter=mc.getAttr(cpos+'.p')[0],mc.getAttr(cpos+'.u'),mc.getAttr(cpos+'.v')

					rp=mc.xform(t,ws=True,q=True,rp=True)
					mc.setAttr(cpos+'.ip',*rp)
					posRP,uRP,vRP=mc.getAttr(cpos+'.p')[0],mc.getAttr(cpos+'.u'),mc.getAttr(cpos+'.v')

					if self.hasGeometry:
						distCenter=distanceBetween(posCenter,center)
						distRP=distanceBetween(posRP,rp)

					if self.hasGeometry==False or abs(distCenter)>abs(distRP):
						up=uRP
						vp=vRP
					else:
						up=uCenter
						vp=vCenter

				elif len(distribute)>0:

					if self.distribute=='u':
						up=(i+1)/self.number
						vp=.5
					else:
						up=.5
						vp=(i+1)/self.number

			if up>float(self.uSpans)-.01: up=float(self.uSpans)-.01
			if vp>float(self.vSpans)-.01: vp=float(self.vSpans)-.01
			if up<.01: up=.01
			if vp<.01: vp=.01

			uvPos.append((up,vp))

			if up<.5 and self.distribute=='u' and Decimal(str(abs(.5-up)))<Decimal(str(closestDistancesToCenter[0])):
				closestDistancesToCenter[0]=abs(.5-up)
				centerMostRivetIDs[0]=i

			if up>.5 and self.distribute=='u' and Decimal(str(abs(.5-up)))<Decimal(str(closestDistancesToCenter[1])):
				closestDistancesToCenter[1]=abs(.5-up)
				centerMostRivetIDs[1]=i

			if up<.5 and self.distribute=='v' and Decimal(str(abs(.5-vp)))<Decimal(str(closestDistancesToCenter[0])):
				closestDistancesToCenter[0]=abs(.5-vp)
				centerMostRivetIDs[0]=i

			if up>.5 and self.distribute=='v' and Decimal(str(abs(.5-vp)))<Decimal(str(closestDistancesToCenter[1])):
				closestDistancesToCenter[1]=abs(.5-vp)
				centerMostRivetIDs[1]=i

			mc.setAttr(c+'.uPos',up*100)
			mc.setAttr(c+'.vPos',vp*100)

			posi=mc.createNode('pointOnSurfaceInfo')
			mc.setAttr((posi+".caching"),True)
			#mc.setAttr((posi+".top"),True)

			multiplyU=mc.createNode('multDoubleLinear')
			mc.connectAttr(c+".uPos",multiplyU+".i1")
			mc.setAttr(multiplyU+'.i2',.01)
			multiplyV=mc.createNode('multDoubleLinear')
			mc.connectAttr(c+".vPos",multiplyV+".i1")
			mc.setAttr(multiplyV+'.i2',.01)

			uvMultipliers.append([multiplyU,multiplyV])

			mc.connectAttr(self.surfaceAttr,posi+".inputSurface");
			mc.connectAttr(multiplyU+".o",posi+".parameterU")
			mc.connectAttr(multiplyV+".o",posi+".parameterV")

			dm=mc.createNode('decomposeMatrix')
			mc.setAttr(dm+'.caching',True)
			fbfm=mc.createNode('fourByFourMatrix')
			mc.setAttr(fbfm+'.caching',True)

			mc.connectAttr(posi+'.nnx',fbfm+'.in00')
			mc.connectAttr(posi+'.nny',fbfm+'.in01')
			mc.connectAttr(posi+'.nnz',fbfm+'.in02')
			mc.connectAttr(posi+'.nux',fbfm+'.in10')
			mc.connectAttr(posi+'.nuy',fbfm+'.in11')
			mc.connectAttr(posi+'.nuz',fbfm+'.in12')
			mc.connectAttr(posi+'.nvx',fbfm+'.in20')
			mc.connectAttr(posi+'.nvy',fbfm+'.in21')
			mc.connectAttr(posi+'.nvz',fbfm+'.in22')
			mc.connectAttr(posi+'.px',fbfm+'.in30')
			mc.connectAttr(posi+'.py',fbfm+'.in31')
			mc.connectAttr(posi+'.pz',fbfm+'.in32')

			if self.constraint:# and not self.parent:
				mc.connectAttr(fbfm+'.output',dm+'.inputMatrix')
			else:
				multMatrix=mc.createNode('multMatrix')
				mc.connectAttr(r+'.parentInverseMatrix',multMatrix+'.i[1]')
				mc.connectAttr(fbfm+'.output',multMatrix+'.i[0]')
				mc.connectAttr(multMatrix+'.o',dm+'.inputMatrix')

			mc.connectAttr(dm+'.outputTranslate',r+'.t')
			mc.connectAttr(dm+'.outputRotate',r+'.r')

			if t!=r:

				if self.createAimCurve:
					aimGroup=mc.createNode('transform',n='rivetAimGrp#')
					mc.parent(aimGroup,t,r=True)
					mc.parent(aimGroup,r)
					if self.keepPivot or self.closestPoint=='pivot':
						mc.xform(aimGroup,ws=True,piv=mc.xform(t,q=True,ws=True,rp=True))
					else:
						mc.xform(aimGroup,ws=True,piv=self.ClosestPoints[i][1])
					self.aimGroups.append(aimGroup)

				if self.constraint:

					if self.parent: # parent and constraint == ParentSpace

						self.parentSpaces.append(ParentSpace(t,r))
						pc=self.parentSpaces[i].parentConstraint

						sc=self.parentSpaces[i].scaleConstraint

						skip=['x']
						if\
						(
							(self.distribute=='v' and 'length' in self.scaleDirection) or
							(self.distribute=='u' and 'width' in self.scaleDirection) or
							t in self.skipScaleObjects
						):
							skip.append('y')
						if\
						(
							(self.distribute=='u' and 'length' in self.scaleDirection) or
							(self.distribute=='v' and 'width' in self.scaleDirection) or
							t in self.skipScaleObjects
						):
							skip.append('z')

						mc.scaleConstraint(sc,e=True,sk=skip)

						if t in self.skipRotateObjects:
							mc.parentConstraint(pc,e=True,sr=('x','y','z'))
						if t in self.skipTranslateObjects:
							mc.parentConstraint(pc,e=True,st=('x','y','z'))

					else: #just constraint

						if t in self.skipRotateObjects:
							pc=mc.parentConstraint(r,t,sr=('x','y','z'),mo=True)[0]#
						if t in self.skipTranslateObjects:
							pc=mc.parentConstraint(r,t,st=('x','y','z'),mo=self.mo)[0]
						if t not in self.skipRotateObjects and t not in self.skipTranslateObjects:
							pc=mc.parentConstraint(r,t,mo=self.mo)[0]



					pcTargets=mc.parentConstraint(pc,q=True,tl=True)

					pcIDs=[]

					nsc=listNodeConnections(r,pc,s=False,d=True)

					for n in range(0,len(nsc)):
						if len(nsc[n])==2 and mc.objExists(nsc[n][-1]):
							pcID=getIDs(nsc[n][-1])
							if isinstance(pcID,int):
								pcIDs.append(pcID)

					pcIDs=removeDuplicates(pcIDs)

					for pcID in pcIDs:
						mc.connectAttr(self.worldMatrix,pc+'.tg['+str(pcID)+'].tpm',f=True)
						mc.connectAttr(dm+'.outputTranslate',pc+'.tg['+str(pcID)+'].tt',f=True)
						mc.connectAttr(dm+'.outputRotate',pc+'.tg['+str(pcID)+'].tr',f=True)

					cleanup.append(r)

					if self.parent:

						scTargets=mc.scaleConstraint(sc,q=True,tl=True)

						scIDs=[]

						nsc=listNodeConnections(r,sc,s=False,d=True)

						for n in range(0,len(nsc)):
							if len(nsc[n])==2 and mc.objExists(nsc[n][-1]):
								scIDs.append(getIDs(nsc[n][-1]))

						scIDs=removeDuplicates(scIDs)

						scMD=mc.createNode('multiplyDivide')
						mc.setAttr(scMD+'.i1',1,1,1)
						mc.setAttr(scMD+'.i2',1,1,1)

						for scID in scIDs:

							mc.connectAttr(self.worldMatrix,sc+'.tg['+str(scID)+'].tpm',f=True)
							#mc.connectAttr(scMD+'.o',sc+'.tg['+str(scID)+'].ts',f=True)
							mc.connectAttr(scMD+'.ox',sc+'.tg['+str(scID)+'].tsx',f=True)
							mc.connectAttr(scMD+'.oy',sc+'.tg['+str(scID)+'].tsy',f=True)
							mc.connectAttr(scMD+'.oz',sc+'.tg['+str(scID)+'].tsz',f=True)

						r=self.parentSpaces[i][0]
						#xfm=mc.xform(r,q=True,ws=True,m=True)
						#mc.setAttr(r+'.inheritsTransform',False)
						#mc.xform(r,m=xfm)
						#mc.connectAttr(self.surfaceMatrix,multMatrix+'.i[1]',f=True)#self.parentSpaces[i][0]+'.parentInverseMatrix'

				elif self.createAimCurve:
					mc.parent(t,w=True)
					mc.setAttr(t+'.inheritsTransform',False)
					mc.parent(t,r,r=True)
				else:
					mc.parent(t,r)

				if mc.objExists(parentTr) and (self.parent or self.createAimCurve) and not self.constraint:

					if not (parentTr in iterable(mc.listRelatives(r,p=True))):

						if mc.getAttr(r+'.inheritsTransform')==True:
							mc.parent(r,parentTr,r=True)
						else:
							mc.parent(r,parentTr)

					if mc.getAttr(r+'.inheritsTransform')==False:

						dm=mc.createNode('decomposeMatrix')
						mc.connectAttr(parentTr+'.worldMatrix',dm+'.inputMatrix')
						mc.connectAttr(dm+'.os',t+'.s',f=True)

			if self.taper!='none' or self.scale!='none':

				cfsiU=mc.createNode('curveFromSurfaceIso')

				mc.setAttr(cfsiU+'.relative',True)
				mc.setAttr(cfsiU+'.relativeValue',True)
				mc.setAttr(cfsiU+'.isoparmDirection',0)
				mc.setAttr(cfsiU+'.minValue',0)
				mc.setAttr(cfsiU+'.maxValue',1)

				mc.connectAttr(multiplyV+".o",cfsiU+".isoparmValue")
				mc.connectAttr(self.surfaceAttr,cfsiU+'.inputSurface')

				cfsiV=mc.createNode('curveFromSurfaceIso')

				mc.setAttr(cfsiV+'.relative',True)
				mc.setAttr(cfsiV+'.relativeValue',True)
				mc.setAttr(cfsiV+'.isoparmDirection',1)
				mc.setAttr(cfsiV+'.minValue',0)
				mc.setAttr(cfsiV+'.maxValue',1)

				mc.connectAttr(multiplyV+".o",cfsiV+".isoparmValue")
				mc.connectAttr(self.surfaceAttr,cfsiV+'.inputSurface')

				subtractNode=mc.createNode('addDoubleLinear')
				mc.setAttr(subtractNode+'.i1',-(1/(self.number*2)))
				addNode=mc.createNode('addDoubleLinear')
				mc.setAttr(addNode+'.i1',1/(self.number*2))
				addSubClampNode=mc.createNode('clamp')
				mc.setAttr(addSubClampNode+'.min',0,0,0)
				mc.setAttr(addSubClampNode+'.max',1,1,1)
				mc.connectAttr(subtractNode+'.o',addSubClampNode+'.inputR')
				mc.connectAttr(addNode+'.o',addSubClampNode+'.inputG')

				if self.distribute=='u':
					mc.connectAttr(multiplyU+".o",subtractNode+".i2")
					mc.connectAttr(multiplyU+".o",addNode+".i2")
					mc.connectAttr(addSubClampNode+'.outputR',cfsiU+'.minValue')
					mc.connectAttr(addSubClampNode+'.outputG',cfsiU+'.maxValue')
				else:
					mc.connectAttr(multiplyV+".o",subtractNode+".i2")
					mc.connectAttr(multiplyV+".o",addNode+".i2")
					mc.connectAttr(addSubClampNode+'.outputR',cfsiV+'.minValue')
					mc.connectAttr(addSubClampNode+'.outputG',cfsiV+'.maxValue')

				ciU=mc.createNode('curveInfo')
				mc.connectAttr(cfsiU+'.outputCurve',ciU+'.inputCurve')

				ciV=mc.createNode('curveInfo')
				mc.connectAttr(cfsiV+'.outputCurve',ciV+'.inputCurve')

				mdlU=mc.createNode('multDoubleLinear')
				mc.connectAttr(ciU+'.al',mdlU+'.i1')
				mc.setAttr(mdlU+'.i2',1/float(mc.getAttr(ciU+'.al')))

				mdlV=mc.createNode('multDoubleLinear')
				mc.connectAttr(ciV+'.al',mdlV+'.i1')
				mc.setAttr(mdlV+'.i2',1/float(mc.getAttr(ciV+'.al')))

				if not mc.objExists(c+'.minScaleWidth'): mc.addAttr(c,ln='minScaleWidth',at='double',k=True,min=0,dv=self.minScaleWidth)
				if not mc.objExists(c+'.maxScaleWidth'): mc.addAttr(c,ln='maxScaleWidth',at='double',k=True,min=0,dv=self.maxScaleWidth)
				if not mc.objExists(c+'.minScaleLength'): mc.addAttr(c,ln='minScaleLength',at='double',k=True,min=0,dv=self.minScaleLength)
				if not mc.objExists(c+'.maxScaleLength'): mc.addAttr(c,ln='maxScaleLength',at='double',k=True,min=0,dv=self.maxScaleLength)

				clampNode=mc.createNode('clamp')

				minScaleLengthNode=mc.createNode('multDoubleLinear')
				maxScaleLengthNode=mc.createNode('multDoubleLinear')
				minScaleWidthNode=mc.createNode('multDoubleLinear')
				maxScaleWidthNode=mc.createNode('multDoubleLinear')

				mc.connectAttr(c+'.minScaleLength',minScaleLengthNode+'.i1')
				mc.connectAttr(lengthMultiplier,minScaleLengthNode+'.i2')

				mc.connectAttr(c+'.maxScaleLength',maxScaleLengthNode+'.i1')
				mc.connectAttr(lengthMultiplier,maxScaleLengthNode+'.i2')

				mc.connectAttr(c+'.minScaleWidth',minScaleWidthNode+'.i1')
				mc.connectAttr(lengthMultiplier,minScaleWidthNode+'.i2')

				mc.connectAttr(c+'.maxScaleWidth',maxScaleWidthNode+'.i1')
				mc.connectAttr(lengthMultiplier,maxScaleWidthNode+'.i2')

				if self.distribute=='u':
					mc.connectAttr(minScaleLengthNode+'.o',clampNode+'.minR')
					mc.connectAttr(maxScaleLengthNode+'.o',clampNode+'.maxR')
					mc.connectAttr(minScaleWidthNode+'.o',clampNode+'.minG')
					mc.connectAttr(maxScaleWidthNode+'.o',clampNode+'.maxG')
				else:
					mc.connectAttr(minScaleWidthNode+'.o',clampNode+'.minR')
					mc.connectAttr(maxScaleWidthNode+'.o',clampNode+'.maxR')
					mc.connectAttr(minScaleLengthNode+'.o',clampNode+'.minG')
					mc.connectAttr(maxScaleLengthNode+'.o',clampNode+'.maxG')

				mc.connectAttr(mdlU+'.o',clampNode+'.ipr')
				mc.connectAttr(mdlV+'.o',clampNode+'.ipg')

				if self.scale=='relative' and self.parent:#or len(self.scaleDirection)<2:#

					if\
					(
						(self.distribute=='u' and 'length' in self.scaleDirection) or
						(self.distribute=='v' and 'width' in self.scaleDirection)
					):
						if self.constraint:
							mc.connectAttr(clampNode+'.opr',scMD+'.i1y')
						else:
							mc.connectAttr(clampNode+'.opr',r+'.sy',f=True)
					if\
					(
						(self.distribute=='v' and 'length' in self.scaleDirection) or
						(self.distribute=='u' and 'width' in self.scaleDirection)
					):
						if self.constraint:
							mc.connectAttr(clampNode+'.opg',scMD+'.i1z')
						else:
							mc.connectAttr(clampNode+'.opg',r+'.sz',f=True)


				elif self.taper!='none' and self.parent:

					#self.autoFlexGroups

					mc.setAttr(t+'.sx',lock=True)
					mc.setAttr(t+'.sy',lock=True)
					mc.setAttr(t+'.sz',lock=True)
					mc.setAttr(t+'.tx',lock=True)
					mc.setAttr(t+'.ty',lock=True)
					mc.setAttr(t+'.tz',lock=True)
					mc.setAttr(t+'.rx',lock=True)
					mc.setAttr(t+'.ry',lock=True)
					mc.setAttr(t+'.rz',lock=True)

					aimTr=mc.createNode('transform',p=t)
					mc.xform(aimTr,ws=True,t=antipodes[i])

					#mc.setAttr(db+'.p1',*self.ClosestPoints[i][0])
					#mc.setAttr(db+'.p2',*antipodes[i])
					axisLength=distanceBetween(self.ClosestPoints[i][0],antipodes[i])#mc.getAttr(db+'.d')

					ffd,lattice,latticeBase=mc.lattice(t,divisions=(2,2,2),objectCentered=True,ol=1)
					latticeLowEndPoints=mc.ls(lattice+'.pt[0:1][0:0][0:1]',fl=True)
					latticeHighEndPoints=mc.ls(lattice+'.pt[0:1][1:1][0:1]',fl=True)

					mc.parent(latticeBase,lattice)

					mc.setAttr(lattice+'.sy',axisLength)

					lattices.append([ffd,lattice,latticeBase])

					mc.parent(lattice,t)
					mc.xform(lattice,ws=True,a=True,t=mc.xform(r,q=True,ws=True,a=True,rp=True))
					mc.xform(lattice,os=True,a=True,ro=(0,0,0))
					mc.move(0,axisLength/2,0,lattice,r=True,os=True,wd=True)

					xSum,ySum,zSum=0,0,0
					for p in latticeLowEndPoints:
						px,py,pz=mc.pointPosition(p,w=True)
						xSum+=px
						ySum+=py
						zSum+=pz

					mc.xform(lattice,ws=True,piv=(xSum/len(latticeLowEndPoints),ySum/len(latticeLowEndPoints),zSum/len(latticeLowEndPoints)))
					mc.xform(latticeBase,ws=True,piv=(xSum/len(latticeLowEndPoints),ySum/len(latticeLowEndPoints),zSum/len(latticeLowEndPoints)))

					ac=mc.aimConstraint(aimTr,lattice,aim=(0,1,0),wut='objectrotation',wuo=r,u=(0,0,1),mo=False)
					mc.delete(ac)

					ac=mc.aimConstraint(aimTr,aimGroup,aim=(0,1,0),wut='objectrotation',wuo=r,u=(0,0,1),mo=False)
					mc.delete(ac,aimTr)

					lowEndCluster,lowEndClusterHandle=mc.cluster(latticeLowEndPoints)[:2]
					highEndCluster,highEndClusterHandle=mc.cluster(latticeHighEndPoints)[:2]

					lowEndClusterHandleShape=mc.listRelatives(lowEndClusterHandle,c=True)[0]
					highEndClusterHandleShape=mc.listRelatives(highEndClusterHandle,c=True)[0]

					#mc.parent(highEndClusterHandle,t)

					if mc.isConnected(lowEndClusterHandleShape+'.clusterTransforms[0]',lowEndCluster+'.clusterXforms'):
						mc.disconnectAttr(lowEndClusterHandleShape+'.clusterTransforms[0]',lowEndCluster+'.clusterXforms')
					if mc.isConnected(highEndClusterHandleShape+'.clusterTransforms[0]',highEndCluster+'.clusterXforms'):
						mc.disconnectAttr(highEndClusterHandleShape+'.clusterTransforms[0]',highEndCluster+'.clusterXforms')

					self.autoFlexGroups.append\
					(
						(
							mc.createNode('transform',n='rivetBaseAutoFlex#',p=r),
							mc.createNode('transform',n='rivetEndAutoFlex#',p=aimGroup)
						)
					)

					self.handles.append\
					(
						(
							mc.createNode('transform',n='rivetBaseCtrl#',p=self.autoFlexGroups[i][0]),
							mc.createNode('transform',n='rivetEndCtrl#',p=self.autoFlexGroups[i][1])
						)
					)

					self.handleShapes.append\
					(
						(
							mc.createNode('locator',p=self.handles[i][0]),
							mc.createNode('locator',p=self.handles[i][1])
						)
					)

					mc.setAttr(self.handleShapes[i][0]+'.los',.5,.5,.5)
					mc.setAttr(self.handleShapes[i][1]+'.los',.5,.5,.5)

					mc.xform(self.autoFlexGroups[i][0],ws=True,a=True,t=mc.xform(t,q=True,ws=True,rp=True))
					mc.xform(self.autoFlexGroups[i][0],ws=True,a=True,piv=mc.xform(t,q=True,ws=True,rp=True))

					for bp in self.bindPoses: mc.dagPose((self.handles[i][0],self.handles[i][1]),a=True,n=bp)

					mc.xform(self.autoFlexGroups[i][1],ws=True,t=antipodes[i])

					mc.hide(lattice)

					mc.connectAttr(self.handles[i][0]+'.worldInverseMatrix[0]',lowEndCluster+'.bindPreMatrix',f=True)
					mc.disconnectAttr(self.handles[i][0]+'.worldInverseMatrix[0]',lowEndCluster+'.bindPreMatrix')

					mc.connectAttr(self.handles[i][0]+'.worldMatrix[0]',lowEndCluster+'.matrix',f=True)

					mc.connectAttr(self.handles[i][1]+'.worldInverseMatrix[0]',highEndCluster+'.bindPreMatrix',f=True)
					mc.disconnectAttr(self.handles[i][1]+'.worldInverseMatrix[0]',highEndCluster+'.bindPreMatrix')

					mc.connectAttr(self.handles[i][1]+'.worldMatrix[0]',highEndCluster+'.matrix',f=True)

					aimGroups.append(aimGroup)

					if self.distribute=='u':
						mc.connectAttr(clampNode+'.opr',self.autoFlexGroups[i][0]+'.sy')
					else:
						mc.connectAttr(clampNode+'.opg',self.autoFlexGroups[i][0]+'.sz')

					mc.delete([lowEndClusterHandle,highEndClusterHandle])

				self.rivets.append(r)

		if self.createAimCurve and self.parent:

			pmm=mc.createNode('pointMatrixMult')
			arcPoints=[]
			ids=[0,centerMostRivetIDs[0],centerMostRivetIDs[1],-1]

			for id in ids:

				measureTr=mc.createNode('transform')
				aimTr=mc.createNode('transform',p=self.trs[id])
				mc.parent(measureTr,self.trs[id])

				mc.xform(aimTr,ws=True,t=antipodes[id])
				mc.xform(measureTr,ws=True,t=mc.xform(self.rivets[id],q=True,ws=True,a=True,rp=True))
				#mc.xform(measureTr,os=True,a=True,ro=(0,0,0),s=(1,1,1))

				ac=mc.aimConstraint(aimTr,measureTr,aim=(0,1,0),wut='objectrotation',wuo=self.rivets[id],u=(0,0,1),mo=False)
				mc.delete(ac,aimTr)

				mc.connectAttr(measureTr+'.worldInverseMatrix',pmm+'.inMatrix',f=True)

				maxYID=-1
				maxY=0.0
				yVal=0.0

				for i in range(0,self.number):

					mc.setAttr(pmm+'.ip',*antipodes[i])
					yVal=mc.getAttr(pmm+'.oy')
					if yVal>maxY:
						maxY=yVal
						maxYID=i

				mc.setAttr(pmm+'.ip',*antipodes[maxYID])

				oy=mc.getAttr(pmm+'.oy')

				mc.setAttr(pmm+'.ip',*antipodes[id])

				ox=mc.getAttr(pmm+'.ox')
				oz=mc.getAttr(pmm+'.oz')

				mc.connectAttr(measureTr+'.worldMatrix',pmm+'.inMatrix',f=True)
				mc.setAttr(pmm+'.ip',ox,oy,oz)

				ap=mc.getAttr(pmm+'.o')[0]

				arcPoints.append(ap)

				mc.disconnectAttr(measureTr+'.worldMatrix',pmm+'.inMatrix')

				mc.delete(measureTr)

			mc.delete(pmm)

			arcCtrlArg=arcPoints
			arcCtrlKeys={'arcWeight':self.arcWeight,'p':self.parents,'sp':self.softParents}

			for k in arcCtrlKeys:
				if type(arcCtrlKeys[k]).__name__=='NoneType':
					del(arcCtrlKeys[k])

			self.ArcCtrl=ArcCtrl(*arcCtrlArg,**arcCtrlKeys)

			mc.addAttr(self.ArcCtrl[0],at='bool',ln='showHandles',k=True,dv=False)
			mc.setAttr(self.ArcCtrl[0]+'.showHandles',k=False,cb=True)
			mc.setAttr(self.ArcCtrl[0]+'.v',k=False,cb=True)
			mc.setAttr(self.ArcCtrl[1]+'.v',k=False,cb=True)

			for h in self.handles:
				mc.connectAttr(self.ArcCtrl[0]+'.showHandles',h[0]+'.v')
				mc.connectAttr(self.ArcCtrl[0]+'.showHandles',h[1]+'.v')

			for bp in self.bindPoses: mc.dagPose(self.ArcCtrl,a=True,n=bp)

			cpoc=mc.createNode('closestPointOnCurve')
			mc.connectAttr(self.ArcCtrl.outputCurve,cpoc+'.inCurve')

			for i in range(0,self.number):

				aimTr=mc.createNode('transform')
				poci=mc.createNode('pointOnCurveInfo')
				dm=mc.createNode('decomposeMatrix')
				fbfm=mc.createNode('fourByFourMatrix')

				mc.connectAttr(poci+'.nnx',fbfm+'.in00')
				mc.connectAttr(poci+'.nny',fbfm+'.in01')
				mc.connectAttr(poci+'.nnz',fbfm+'.in02')
				mc.connectAttr(poci+'.ntx',fbfm+'.in10')
				mc.connectAttr(poci+'.nty',fbfm+'.in11')
				mc.connectAttr(poci+'.ntz',fbfm+'.in12')

				mc.connectAttr(self.ArcCtrl.outputNormal+'X',fbfm+'.in20')
				mc.connectAttr(self.ArcCtrl.outputNormal+'Y',fbfm+'.in21')
				mc.connectAttr(self.ArcCtrl.outputNormal+'Z',fbfm+'.in22')

				mc.connectAttr(poci+'.px',fbfm+'.in30')
				mc.connectAttr(poci+'.py',fbfm+'.in31')
				mc.connectAttr(poci+'.pz',fbfm+'.in32')

				mc.connectAttr(fbfm+'.output',dm+'.inputMatrix')
				mc.connectAttr(dm+'.outputTranslate',aimTr+'.t')
				mc.connectAttr(dm+'.outputRotate',aimTr+'.r')

				mc.setAttr(cpoc+'.ip',*antipodes[i])
				cpu=mc.getAttr(cpoc+'.u')
				mc.setAttr(poci+'.parameter',cpu)

				mc.connectAttr(self.ArcCtrl.outputCurve,poci+'.inputCurve')

				ac=mc.aimConstraint(aimTr,self.aimGroups[i],aim=(0,1,0),wut='objectrotation',wuo=aimTr,u=(0,0,1),mo=not(self.realign))[0]

				disconnectNodes(aimTr,ac)

				mc.connectAttr(fbfm+'.output',ac+'.worldUpMatrix',f=True)
				mc.connectAttr(dm+'.ot',ac+'.target[0].targetTranslate',f=True)

				mc.delete(aimTr)

				sc=mc.createNode('subCurve')

				mc.setAttr(sc+'.relative',True)
				mc.setAttr(sc+'.minValue',0)
				mc.setAttr(sc+'.maxValue',1)

				mc.connectAttr(self.ArcCtrl.outputCurve,sc+'.ic')

				if self.distribute=='u':
					uMultAttr=uvMultipliers[i][0]+".o"
				else:
					uMultAttr=uvMultipliers[i][1]+".o"

				#adjust for offset

				multOffsetCalc=mc.createNode('multDoubleLinear')
				mc.setAttr(multOffsetCalc+'.i1',1/mc.getAttr(uMultAttr))
				mc.connectAttr(uMultAttr,multOffsetCalc+'.i2')

				multOffset=mc.createNode('multDoubleLinear')
				mc.setAttr(multOffset+'.i1',cpu)
				mc.connectAttr(multOffsetCalc+'.o',multOffset+'.i2')

				mc.connectAttr(multOffset+'.o',poci+'.parameter',f=True)

				subtractNode=mc.createNode('addDoubleLinear')
				mc.setAttr(subtractNode+'.i1',-(1.0/(self.number*2)))
				addNode=mc.createNode('addDoubleLinear')
				mc.setAttr(addNode+'.i1',1.0/(self.number*2))
				addSubClampNode=mc.createNode('clamp')
				mc.setAttr(addSubClampNode+'.min',0,0,0)
				mc.setAttr(addSubClampNode+'.max',1,1,1)
				mc.connectAttr(subtractNode+'.o',addSubClampNode+'.inputR')
				mc.connectAttr(addNode+'.o',addSubClampNode+'.inputG')

				mc.connectAttr(multOffset+".o",subtractNode+".i2")
				mc.connectAttr(multOffset+".o",addNode+".i2")
				mc.connectAttr(addSubClampNode+'.outputR',sc+'.minValue')
				mc.connectAttr(addSubClampNode+'.outputG',sc+'.maxValue')

				ciU=mc.createNode('curveInfo')
				mc.connectAttr(sc+'.outputCurve',ciU+'.inputCurve')

				mdlU=mc.createNode('multDoubleLinear')
				mc.connectAttr(ciU+'.al',mdlU+'.i1')
				mc.setAttr(mdlU+'.i2',1/float(mc.getAttr(ciU+'.al')))

				clampNode=mc.createNode('clamp')

				if not mc.objExists(c+'.minScaleEnd'): mc.addAttr(self.ctrls[i],ln='minScaleEnd',at='double',k=True,min=0,max=1,dv=0)
				if not mc.objExists(c+'.maxScaleEnd'): mc.addAttr(self.ctrls[i],ln='maxScaleEnd',at='double',k=True,min=0,dv=1)

				mc.connectAttr(self.ctrls[i]+'.minScaleEnd',clampNode+'.minR')
				mc.connectAttr(self.ctrls[i]+'.maxScaleEnd',clampNode+'.maxR')

				mc.connectAttr(mdlU+'.o',clampNode+'.ipr')

				if self.distribute=='u':
					mc.connectAttr(clampNode+'.opr',self.autoFlexGroups[i][1]+'.sz')
				else:
					mc.connectAttr(clampNode+'.opr',self.autoFlexGroups[i][1]+'.sy')

			mc.delete(cpoc)

		if self.parent:
			self[:]=self.rivets
		else:
			self[:]=self.trs
		#if self.mo:
		#	#for i in len(self.trs):
		#		#try: mc.xform(t,q=True,ws=True,m=wsMatrices[i]))
		#		#except: pass

		cleanup.append(cpos)

		for c in cleanup:
			if mc.objExists(c):
				disconnectNodes(c)
				mc.delete(c)

		if self.snapToSurface:
			if self.createAimCurve or self.taper:
				for i in range(0,self.number):
					mc.xform(self.handles[i][0],ws=True,t=mc.xform(self.rivets[i],q=True,ws=True,rp=True))
					mc.xform(self.trs[i],ws=True,rp=mc.xform(self.rivets[i],q=True,ws=True,rp=True))
			else:
				for i in range(0,self.number):
					mc.xform(self.trs[i],ws=True,t=mc.xform(self.rivets[i],q=True,ws=True,rp=True))
					mc.xform(self.trs[i],ws=True,ro=mc.xform(self.rivets[i],q=True,ws=True,ro=True))
Пример #23
0
	def create(self):

		mc.cycleCheck(e=False)

		if mc.objExists(self.parent):
			self.group=mc.createNode('transform',n=uniqueNames(self.name),p=self.parent)
		else:
			self.group=mc.createNode('transform',n=uniqueNames(self.name))

		self.jointParent=''
		if len(iterable(mc.listRelatives(self.joints[0],p=True)))>0:
			self.jointParent=mc.listRelatives(self.joints[0],p=True)[0]
		else:
			self.jointParent=mc.createNode('transform',n=uniqueNames(self.name+'CtrlJointGroup'))
			mc.parent(self.joints[0],self.jointParent)

		cMuscleObjects=[]

		# create control joints

		self.ctrlJoints=[]
		for j in self.joints:

			cj=mc.createNode('joint',p=j,n=uniqueNames(self.name+'CtrlJoint'))

			if len(self.ctrlJoints)==0:
				mc.parent(cj,self.group)
				if mc.objExists(self.jointParent):
					self.jointParent=mc.rename(ParentSpace(cj,self.jointParent)[0],self.name+'CtrlJoints')
				else:
					self.jointParent=mc.rename(ParentSpace(cj)[0],self.name+'CtrlJoints')
			else:
				mc.parent(cj,self.ctrlJoints[-1])

			mc.setAttr(cj+'.r',*mc.getAttr(j+'.r')[0])
			mc.setAttr(cj+'.jo',*mc.getAttr(j+'.jo')[0])
			self.originalRotations[cj+'.r']=list(mc.getAttr(cj+'.r')[0])

			mc.setAttr(j+'.r',0,0,0)
			mc.setAttr(cj+'.r',0,0,0)

			mc.setAttr(cj+'.s',1,1,1)
			mc.setAttr(cj+'.radius',mc.getAttr(j+'.radius')*1.5)#0)
			mc.setAttr(cj+'.ovc',10)
			mc.connectAttr(j+'.pa',cj+'.pa')

			if self.joints.index(j)<len(self.joints)-1:
				childList=removeAll\
				(
					iterable(mc.listRelatives(self.joints[self.joints.index(j)+1],c=True,ad=True))+[self.joints[self.joints.index(j)+1]],
					iterable(mc.listRelatives(j,c=True,ad=True))+[j]
				)

				chList=childList
				for c in chList:
					if mc.nodeType(c) not in ['transform','joint','cMuscleObject']:
						childList.remove(c)
					if mc.nodeType(c) in ['transform','joint']:
						for a in ['.t','.tx','.ty','.tz','.r','.rx','.ry','.rz']:
							if mc.connectionInfo(c+a,id=True) or mc.getAttr(c+a,l=True) or mc.getAttr(c+'.io'):
								childList.remove(c)
								break

				if j==self.joints[-2]:
					childList.append(self.joints[-1])

				for jc in childList:
					if mc.nodeType(jc)=='transform' or mc.nodeType(jc)=='joint':
						if jc in self.joints[:-1]:
							mc.parentConstraint(cj,jc,mo=True)
						else:
							mc.parentConstraint(cj,jc,sr=('x','y','z'),mo=True)
					elif 'cMuscle' in mc.nodeType(jc):
						cMuscleObjects.append(jc)

			else:
				mc.parentConstraint(cj,j,st=('x','y','z'),mo=True)

			self.ctrlJoints.append(cj)

		mc.hide(self.jointParent)
		mc.setAttr(self.ctrlJoints[1]+'.ssc',False)

		# create ik

		self.ikHandle,self.endEffector=mc.ikHandle(sol='ik2Bsolver',sj=self.ctrlJoints[0],ee=self.ctrlJoints[-1],n=uniqueNames(self.name+'Handle'))
		self.endEffector=mc.rename(self.endEffector,self.name+'Effector')
		mc.setAttr(self.ikHandle+'.snapEnable',False)
		mc.hide(self.ikHandle)
		mc.setAttr(self.ikHandle+'.ikBlend',0)

		for j in self.originalRotations:
			if isIterable(self.originalRotations[j]):
				mc.setAttr(j,*self.originalRotations[j])
			else:
				mc.setAttr(j,self.originalRotations[j])

		# look for twist joints

		if self.twist:
			skipAxis=removeAll(self.orientAxis,['x','y','z'])
			twistJoints=removeAll([self.joints[-2],self.joints[-1]],hierarchyBetween(self.joints[-2],self.joints[-1],type='joint'))
			for i in range(0,len(twistJoints)):
				tj=twistJoints[i]
				oc=mc.orientConstraint(self.ctrlJoints[-1],tj,sk=skipAxis,mo=True)
				if i>0:
					oc=mc.orientConstraint(self.ctrlJoints[-2],tj,sk=skipAxis,mo=True)
					wal=mc.orientConstraint(oc,q=True,wal=True)
					distToBend=distanceBetween(self.ctrlJoints[-2],tj)
					distToEnd=distanceBetween(self.ctrlJoints[-1],tj)
					mc.setAttr(oc+'.'+wal[-1],distToEnd/(distToBend+distToEnd))
					mc.setAttr(oc+'.'+wal[-2],distToBend/(distToBend+distToEnd))

		# make stretchy

		db=mc.createNode('distanceBetween')
		mc.connectAttr(self.ctrlJoints[0]+'.t',db+'.p1')

		pmm1=mc.createNode('pointMatrixMult')
		pmm2=mc.createNode('pointMatrixMult')

		mc.connectAttr(self.ikHandle+'.t',pmm1+'.ip')
		mc.connectAttr(self.ikHandle+'.pm[0]',pmm1+'.im')

		mc.connectAttr(pmm1+'.o',pmm2+'.ip')
		mc.connectAttr(self.ctrlJoints[0]+'.pim[0]',pmm2+'.im')

		mc.connectAttr(pmm2+'.o',db+'.p2')

		mdl=mc.createNode('multDoubleLinear')
		mc.connectAttr(db+'.d',mdl+'.i1')
		mc.setAttr(mdl+'.i2',1.0/mc.getAttr(db+'.d'))
		cn=mc.createNode('clamp')
		for i in range(0,3):
			c=['r','g','b'][i]
			a=['x','y','z'][i]
			mc.connectAttr(mdl+'.o',cn+'.ip'+c)
			mc.setAttr(cn+'.mn'+c,1)
			mc.connectAttr(mdl+'.o',cn+'.mx'+c)
			mc.connectAttr(cn+'.op'+c,self.ctrlJoints[0]+'.s'+a)

		for cmo in cMuscleObjects:
			mdlcm=mc.createNode('multDoubleLinear')
			mc.setAttr(mdlcm+'.i1',mc.getAttr(cmo+'.length'))
			mc.connectAttr(cn+'.op'+['r','g','b'][['x','y','z'].index(self.orientAxis)],mdlcm+'.i2')
			mc.connectAttr(mdlcm+'.o',cmo+'.length')


		# create control objects or set control object pivots

		poleOffset=distanceBetween(self.ctrlJoints[1],self.ctrlJoints[0])*2

		for i in range(0,len(self.controlObjects)-1):
			if mc.objExists(self.controlObjects[i]):
				mc.xform(self.controlObjects[i],ws=True,piv=mc.xform(self.ctrlJoints[-1],q=True,ws=True,rp=True))
			else:
				if 'r' not in self.handleOptions[i] and 'radius' not in self.handleOptions[i]:
					self.handleOptions[i]['r']=distanceBetween(self.ctrlJoints[-1],self.ctrlJoints[0])/4
				if 'name' not in self.handleOptions[i] and 'n' not in self.handleOptions[i]:
					self.handleOptions[i]['n']=self.joints[i]+'_ctrl'
				if 'x' not in self.handleOptions[i] and 'xform' not in self.handleOptions[i]:
					self.handleOptions[i]['xform']=self.joints[i]
				if 'aim' not in self.handleOptions[i] and 'a' not in self.handleOptions[i]:
					self.handleOptions[i]['aim']=self.aimVector
				self.handleOptions[i]['parent']=self.group
				self.handleOptions[-i]['pointTo']=self.joints[i]
				self.handleOptions[i]['aimAt']=self.joints[i]
				self.handles.append(Handle(**self.handleOptions[i]))
				self.controlObjects[i]=(self.handles[-1].transforms[-1])

		if not mc.objExists(self.controlObjects[-1]):
			if 'name' not in self.handleOptions[-1] and 'n' not in self.handleOptions[-1]:
				self.handleOptions[-1]['n']=self.joints[1]+'_aimCtrl'
			if 'x' not in self.handleOptions[-1] and 'xform' not in self.handleOptions[-1]:
				self.handleOptions[-1]['x']=self.ctrlJoints[1]
			if 'aim' not in self.handleOptions[i] and 'a' not in self.handleOptions[i]:
				self.handleOptions[i]['aim']=self.poleVector
			self.handleOptions[-1]['parent']=self.group
			self.handleOptions[-1]['pointTo']=self.joints[1]
			self.handleOptions[-1]['aimAt']=self.joints[1]
			self.handles.append(Handle(**self.handleOptions[-1]))
			self.controlObjects[-1]=(self.handles[-1].transforms[-1])
			mc.move\
			(
				poleOffset*(self.poleVector[0]),
				poleOffset*(self.poleVector[1]),
				poleOffset*(self.poleVector[2]),
				self.controlObjects[-1],
				r=True,os=True,wd=True
			)

		# add and set control attributes

		mc.setAttr(self.controlObjects[-1]+'.v',k=False)
		for attr in ['.sx','.sy','.sz']:
			mc.setAttr(self.controlObjects[-1]+attr,l=True,k=False,cb=False)
			mc.setAttr(self.ikHandle+attr,l=True,k=False,cb=False)
		for attr in ['.rx','.ry','.rz']:
			mc.setAttr(self.controlObjects[-1]+attr,k=False,cb=False)
		for attr in ['.tx','.ty','.tz']:
			mc.setAttr(self.group+attr,l=True,k=False,cb=False)
			mc.setAttr(self.controlObjects[0]+attr,l=True,k=False,cb=False)

		mc.setAttr(self.ikHandle+'.v',k=False,cb=False)

		for attr in ['.tx','.ty','.tz']:
			mc.setAttr(self.controlObjects[1]+attr,l=True,k=False,cb=False)

		if not mc.objExists(self.controlObjects[-2]+'.twist'):
			mc.addAttr(self.controlObjects[-2],at='doubleAngle',ln='twist',k=True)
		if not mc.objExists(self.controlObjects[-2]+'.sway') and self.sway:
			mc.addAttr(self.controlObjects[-2],at='doubleAngle',ln='sway',k=1)
		if not mc.objExists(self.controlObjects[-2]+'.stretch'):
			mc.addAttr(self.controlObjects[-2],at='double',ln='stretch',k=1,dv=self.stretch,min=0)
		if not mc.objExists(self.controlObjects[-2]+'.squash'):
			mc.addAttr(self.controlObjects[-2],at='double',ln='squash',k=1,dv=self.squash,min=0,max=99)
		if not mc.objExists(self.controlObjects[-2]+'.ikSwitch'):
			mc.addAttr(self.controlObjects[-2],at='enum',ln='ikSwitch',en='ik:fk',k=True,dv=1)# if self.switch=='fk' else 0

		#sway control

		if self.sway:

			adl=mc.createNode('addDoubleLinear')
			mc.connectAttr(self.ctrlJoints[1]+'.r'+self.poleAxis,adl+'.i1')
			mc.connectAttr(self.controlObjects[-2]+'.sway',adl+'.i2')
			childList=removeAll\
			(
				iterable(mc.listRelatives(self.joints[2],c=True,ad=True)),
				iterable(mc.listRelatives(self.joints[1],c=True,ad=True))
			)+[self.joints[2],self.joints[1]]
			for c in childList:
				if mc.nodeType(c)=='transform' or mc.nodeType(c)=='joint':
					pc=mc.parentConstraint(c,q=True)
					nc=listNodeConnections(self.ctrlJoints[1],pc,s=True,d=True)
					for conn in nc:
						if conn[0]==self.ctrlJoints[1]+'.rotate':
							mc.disconnectAttr(conn[0],conn[1])
							for a in removeAll(self.poleAxis,['x','y','z']):
								mc.connectAttr(conn[0]+a.upper(),conn[1]+a.upper(),f=True)
							mc.connectAttr(adl+'.o',conn[1]+self.poleAxis.upper(),f=True)

		# ik/fk switch

		for i in range(0,3):

			c=['r','g','b'][i]
			a=['x','y','z'][i]
			adl=mc.createNode('addDoubleLinear')
			mdl1=mc.createNode('multDoubleLinear')
			mc.setAttr(mdl1+'.i2',.01)
			mdl2=mc.createNode('multDoubleLinear')
			mc.setAttr(mdl2+'.i2',.01)
			revNode=mc.createNode('reverse')
			mc.setAttr(adl+'.i1',1)

			mc.connectAttr(	mdl1+'.o',adl+'.i2')
			mc.connectAttr(self.controlObjects[-2]+'.stretch',mdl1+'.i1')

			mc.connectAttr(	mdl2+'.o',revNode+'.ix')
			mc.connectAttr(self.controlObjects[-2]+'.squash',mdl2+'.i1')

			mc.connectAttr(adl+'.o',cn+'.mx'+c,f=True)
			mc.connectAttr(revNode+'.ox',cn+'.mn'+c,f=True)

		if not mc.objExists(self.controlObjects[-2]+'.zenPreviousIKState'):
			if self.switch=='fk':
				mc.addAttr(self.controlObjects[-2],at='long',ln='zenPreviousIKState',k=0,dv=1)
			else:
				mc.addAttr(self.controlObjects[-2],at='long',ln='zenPreviousIKState',k=0,dv=0)
		if not mc.objExists(self.controlObjects[-2]+'.zenPreviousIKParent'):
			if self.switch=='fk':
				mc.addAttr(self.controlObjects[-2],at='long',ln='zenPreviousIKParent',k=0,dv=1)
			else:
				mc.addAttr(self.controlObjects[-2],at='long',ln='zenPreviousIKParent',k=0,dv=0)

		for i in range(0,2):
			for c in mc.listRelatives(self.controlObjects[i],s=True):
				mc.connectAttr(self.controlObjects[-2]+'.ikSwitch',c+'.v')

		mc.connectAttr(self.controlObjects[-2]+'.twist',self.ikHandle+'.twist')

		rev=mc.createNode('reverse')
		mc.connectAttr(self.controlObjects[-2]+'.ikSwitch',rev+'.ix')
		mc.connectAttr(rev+'.ox',self.ikHandle+'.ikBlend')

		for c in mc.listRelatives(self.controlObjects[-1],s=True):
			mc.connectAttr(rev+'.ox',c+'.v')

		# parent spaces

		for i in [0,1,2]:
			if(mc.objExists(self.jointParent)and i in [0,2]):
				ParentSpace(self.controlObjects[i],self.jointParent)
			else:
				ParentSpace(self.controlObjects[i],self.controlObjects[i-1])

		ParentSpace(self.controlObjects[-1],self.controlObjects[-2])
		if mc.objExists(self.jointParent):
			ParentSpace(self.controlObjects[-1],self.jointParent).setParent(self.jointParent)
			ParentSpace(self.controlObjects[-2],self.jointParent).setParent(self.jointParent)
		else:
			ParentSpace(self.controlObjects[-1],self.controlObjects[0])

		if self.switch=='fk':
			ParentSpace(self.controlObjects[2],self.controlObjects[1])

		for co in self.controlObjects[2:]:
			freeze(co,t=True)

		mc.aimConstraint\
		(
			self.ctrlJoints[1],self.controlObjects[-1],
			aim=(self.aimVector[0],self.aimVector[1],self.aimVector[2]),
			wuo=self.ctrlJoints[1],
			wut='objectrotation',
			mo=True
		)

		if mc.objExists(self.jointParent):
			mc.setAttr(self.controlObjects[0]+'.parentTo',l=True,k=False,cb=False)
		mc.setAttr(self.controlObjects[1]+'.parentTo',l=True,k=False,cb=False)

		#constraints

		orientConstraints=['','','']
		for i in [2,1,0]:
			orientConstraints[i]=mc.orientConstraint(self.controlObjects[i],self.ctrlJoints[i],mo=True)[0]
			mc.setAttr(self.controlObjects[i]+'.v',k=False)
			for attr in ['.sx','.sy','.sz']:
				mc.setAttr(self.controlObjects[i]+attr,l=True,k=False,cb=False)
			if i==1:
				if not self.sway:
					mc.setAttr(self.controlObjects[i]+'.r'+self.poleAxis,l=True,k=False,cb=False)
				mc.setAttr(self.controlObjects[i]+'.r'+self.orientAxis,l=True,k=False,cb=False)

		self.poleVectorConstraint=mc.poleVectorConstraint(self.controlObjects[-1],self.ikHandle)[0]

		for oc in orientConstraints[:-1]:
			octl=mc.orientConstraint(oc,q=True,tl=True)
			ocwal=mc.orientConstraint(oc,q=True,wal=True)
			weightAlias=ocwal[octl.index(self.controlObjects[orientConstraints.index(oc)])]
			mc.connectAttr(self.controlObjects[-2]+'.ikSwitch',oc+'.'+weightAlias)

		mc.parent(self.ikHandle,self.controlObjects[2],r=False)

		if self.switch=='ik':
			mc.setAttr(self.controlObjects[-2]+'.ikSwitch',0)

		# link for asset detection

		if 'zenIkFkLimbCtrls' not in mc.listAttr(self.group):
			mc.addAttr(self.group,ln='zenIkFkLimbCtrls',at='message',m=True)
		if 'zenIkFkLimbCtrlJoints' not in mc.listAttr(self.group):
			mc.addAttr(self.group,ln='zenIkFkLimbCtrlJoints',at='message',m=True)
		for co in self.controlObjects:
			if 'zenCtrl' not in mc.listAttr(co):
				mc.addAttr(co,ln='zenCtrl',at='message')
			mc.connectAttr(co+'.zenCtrl',self.group+'.zenIkFkLimbCtrls['+str(firstOpenPlug(self.group+'.zenIkFkLimbCtrls'))+']')
		for cj in self.ctrlJoints:
			if 'zenCtrl' not in mc.listAttr(cj):
				mc.addAttr(cj,ln='zenCtrl',at='message')
			mc.connectAttr(cj+'.zenCtrl',self.group+'.zenIkFkLimbCtrlJoints['+str(firstOpenPlug(self.group+'.zenIkFkLimbCtrlJoints'))+']')

		for bp in self.bindPoses:
			for co in self.controlObjects:
				mc.dagPose(co,a=True,n=bp)

		self[:]=[self.group]+self.controlObjects

		mc.cycleCheck(e=True)

		mc.select(self[-2])
Пример #24
0
	def addAttributes(self,**keywords):

		#organize:
		sortedKeywords=sortBy\
		(
			keywords,
			[
				'position',
				'scale',
				'sweep',
				'spin',
				'radius',
				'normal'
			]
		)

		for k in sortedKeywords:

			attrVal=eval('self.'+k)

			if isIterable(attrVal):
				attrType='double3'
			else:
				attrType='double'

			if k in self.attributeTypes:
				attrType=self.attributeTypes[k]
			else:
				self.attributeTypes[k]=attrType

			if not k in mc.listAttr(self.shapes[-1]):

				if k in self.attributeShortNames:
					mc.addAttr(self.shapes[-1],ln=k,sn=self.attributeShortNames[k],at=attrType)
				else:
					mc.addAttr(self.shapes[-1],ln=k,at=attrType)

				if isIterable(attrVal):

					subAttrType=attrType[:-1]
					if k in self.attributeShortNames:
						mc.addAttr(self.shapes[-1],ln=k+'X',sn=self.attributeShortNames[k]+'x',at=subAttrType,p=k)
						mc.addAttr(self.shapes[-1],ln=k+'Y',sn=self.attributeShortNames[k]+'y',at=subAttrType,p=k)
						mc.addAttr(self.shapes[-1],ln=k+'Z',sn=self.attributeShortNames[k]+'z',at=subAttrType,p=k)
					else:
						mc.addAttr(self.shapes[-1],ln=k+'X',at=subAttrType,p=k)
						mc.addAttr(self.shapes[-1],ln=k+'Y',at=subAttrType,p=k)
						mc.addAttr(self.shapes[-1],ln=k+'Z',at=subAttrType,p=k)

					mc.setAttr(self.shapes[-1]+'.'+k+'X',k=False,cb=True)
					mc.setAttr(self.shapes[-1]+'.'+k+'Y',k=False,cb=True)
					mc.setAttr(self.shapes[-1]+'.'+k+'Z',k=False,cb=True)

					if k in self.attributeLimits:
						mc.addAttr(self.shapes[-1]+'.'+k+'X',e=True,min=self.attributeLimits[k][0][0],max=self.attributeLimits[k][-1][0])
						mc.addAttr(self.shapes[-1]+'.'+k+'Y',e=True,min=self.attributeLimits[k][0][1],max=self.attributeLimits[k][-1][1])
						mc.addAttr(self.shapes[-1]+'.'+k+'Z',e=True,min=self.attributeLimits[k][0][2],max=self.attributeLimits[k][-1][2])
				else:
					if k in self.attributeLimits:
						mc.addAttr(self.shapes[-1]+'.'+k,e=True,min=self.attributeLimits[k][0],max=self.attributeLimits[k][-1])

			if isIterable(attrVal):
				mc.setAttr(self.shapes[-1]+'.'+k,*attrVal,**{'cb':True,'k':False})
			else:
				mc.setAttr(self.shapes[-1]+'.'+k,attrVal,k=False,cb=True)

			if isIterable(keywords[k]):
				connectTo=keywords[k]
			else:
				connectTo=[keywords[k]]

			for c in connectTo:
				if isinstance(connectTo,dict):
					for cc in connectTo:
						if not mc.isConnected(self.shapes[-1]+'.'+k+cc,connectTo[cc]):
							mc.connectAttr(self.shapes[-1]+'.'+k+cc,connectTo[cc],f=True)
				else:
					if not mc.isConnected(self.shapes[-1]+'.'+k,c):
						mc.connectAttr(self.shapes[-1]+'.'+k,c,f=True)
Пример #25
0
	def __init__(self,*args,**keywords):

		#defaults
		self.parent=''
		self.transforms=[]
		self.name=''
		self.pointTo=''
		self.aimAt=''
		self.aim=[0,1,0]
		self.up=[0,0,1]
		self.pivot=[]
		self.type='locator'
		self.shape=''
		self.shapes=[]
		self.radius=1
		self.sweep=90
		self.position=[0,0,0]
		self.scale=[1,1,1]
		self.xform=''
		self.spin=0
		self.xformMatrix=[]
		self.freeze=False
		self.softParent=''

		# attributes

		self.parentSpaces=[]


		self.shortNames=\
		{
			'p':'parent',
			'f':'freeze',
			'n':'name',
			'tan':'tangent',
			'pv':'pivot',
			'piv':'pivot',
			'tr':'transform',
			'pct':'parentCtrl',
			'pctrl':'parentCtrl',
			'ctrl':'control',
			'rad':'radius',
			'r':'radius',
			'sw':'sweep',
			'pos':'position',
			't':'type',
			'x':'xform',
			'aa':'aimAt',
			'sp':'softParent'
		}

		self.attributeTypes=\
		{
			'normal':'float3',
			'up':'double3',
			'aim':'double3',
			'sweep':'double',
			'spin':'double'
		}

		self.attributeLimits=\
		{
			'normal':[[-1,-1,-1],[1,1,1]],
			'up':[[-1,-1,-1],[1,1,1]],
			'aim':[[-1,-1,-1],[1,1,1]],
			'sweep':[0,180],
			'spin':[-225,135],
			'radius':[0,10000000]
		}

		self.attributeShortNames=\
		{
			'position':'pos',
			'radius':'rad',
			'spin':'sp',
			'sweep':'sw',
			'normal':'nr'
		}

		for k in keywords:
			if k in self.shortNames:
				exec('self.'+self.shortNames[k]+'=keywords[k]')
			elif k in self.__dict__:
				exec('self.'+k+'=keywords[k]')

		if len(args)==0 and not mc.objExists(self.xform): args=mc.ls(sl=True)

		sel=[]

		for a in args:
			if isIterable(a):
				sel.extend(a)
			else:
				sel.append(a)

		for s in sel:
			if mc.ls(s)==mc.ls(s,type='transform'):
				self.transforms.append(mc.ls(s)[0])
			elif mc.ls(s)==mc.ls(s,type='shape'):
				self.transforms.append(mc.ls(s)[0])

		# parse options

		if self.name=='': self.name='Handle#'

		if not isIterable(self.position):
			if isinstance(self.position,basestring) and mc.objExists(self.position):
				if len(iterable(self.position.split('.')))>1:
					try:
						self.position=mc.pointPosition(self.position)
					except:
						self.position=mc.pointPosition(self.position+'.rp')
				else:
					self.position=mc.pointPosition(self.position+'.rp')
		elif len(self.position)<3:
			self.position=[0.0,0.0,0.0]

		if self.transforms==[]:
			if 'freeze' not in keywords and 'f' not in keywords:
				self.freeze=True
			if mc.objExists(self.xform):
				self.transforms.append(mc.createNode('transform',n=self.name,p=self.xform))
				mc.setAttr(self.transforms[-1]+'.r',0,0,0)
			else:
				self.transforms.append(mc.createNode('transform',n=self.name))

			if mc.objExists(self.parent):
				mc.parent(self.transforms[-1],self.parent)
			else:
				mc.parent(self.transforms[-1],w=True)

			"""if mc.objExists(self.xform):

				xfm=mc.xform(self.xform,q=True,ws=True,a=True,m=True)
				wsro=mc.xform(self.xform,q=True,ws=True,ro=True)
				wst=mc.xform(self.xform,q=True,ws=True,t=True)
				wsrp=mc.xform(self.xform,q=True,ws=True,rp=True)
				wsra=mc.xform(self.xform,q=True,ws=True,ra=True)
				wssp=mc.xform(self.xform,q=True,ws=True,sp=True)
				print self.transforms[-1]
				print xfm
				mc.xform(self.transforms[-1],ws=True,a=True,m=xfm)
				mc.xform(self.transforms[-1],ws=True,ro=wsro)
				mc.xform(self.transforms[-1],ws=True,t=wst)
				mc.xform(self.transforms[-1],ws=True,rp=wsrp)
				mc.xform(self.transforms[-1],ws=True,ra=wsra)
				mc.xform(self.transforms[-1],ws=True,sp=wssp)

				print mc.xform(self.transforms[-1],q=True,a=True,ws=True,m=True)"""

		elif mc.objExists(self.parent):
			for t in self.transforms:
				mc.parent(t,self.parent)

		if mc.objExists(self.softParent):
			for t in self.transforms:
				self.parentSpaces.append(ParentSpace(t,self.softParent))

		if self.freeze:
			freeze(self.transforms[-1],t=True)

		if mc.objExists(self.pointTo):
			self.aimCurve=mc.createNode('nurbsCurve',p=self.transforms[0])

		if len(self.shapes)==0:
			exec('self.mk'+self.type[0].upper()+self.type[1:]+'()')

		if mc.objExists(self.pointTo):
			self.mkAim()

		for t in self.transforms:
			if not 'zenHandleShape' in mc.listAttr(t):
				mc.addAttr(t,ln='zenHandleShape',m=True,at='message')

		for s in self.shapes:
			if not 'zenHandle' in mc.listAttr(s):
				mc.addAttr(s,ln='zenHandle',at='message')

		for t in self.transforms:
			for s in self.shapes:
				mc.connectAttr\
				(
					s+'.zenHandle',
					t+'.zenHandleShape['+str(firstOpenPlug(t+'.zenHandleShape'))+']'
				)

		if len(self.transforms)>1:
			for t in self.transforms[1:]:
				pass

		self[:]=self.shapes
Пример #26
0
	def __init__(self,*args,**keywords):

		#default options
		self.targets=[]
		self.origin='local'
		self.frontOfChain=True
		self.deleteTargets=False
		self.base=[]
		self.baseIndex=0
		self.useExisting=True
		self.controlObjects=[]
		self.controlAttributes=[]
		self.before=False
		self.after=False
		self.name='blendShape#'
		self.goals=[] # use to specify exact goal weights for each target in each target list
		self.range=[[0,10]] # use to specify range of goals for each target
		self.weights=[0]
		self.prune=False
		self.baseIndex=0
		self.createControlObject=False
		self.control=True

		# any of the following abbreviations can be substituted
		self.shortNames=\
		{
			'o':'origin',
			'foc':'frontOfChain',
			'dt':'deleteTargets',
			'b':'base',
			'ue':'useExisting',
			'co':'controlObjects',
			'control':'controlObjects',
			'ca':'controlAttributes',
			'n':'name',
			'g':'goals',
			'goal':'goals',
			'gm':'goalMax',
			'p':'prune',
			'r':'range',
			't':'targets',
			'w':'weights',
			'c':'control'
		}

		unusedKeys={}
		for k in keywords:
			if k in self.shortNames:
				exec('self.'+self.shortNames[k]+'=keywords[k]')
			elif k in self.__dict__:
				exec('self.'+k+'=keywords[k]')
			else:
				unusedKeys[k]=keywords[k]

		self.controlObjects=iterable(self.controlObjects)

		if not isIterable(self.range[0]): self.range=[self.range]

		if len(args)==0: args=mc.ls(sl=True)

		sel=[]
		for a in args:
			if isinstance(a,basestring) and mc.objExists(a) and mc.nodeType(a)=='blendShape':
				self.append(a)
				self.base=mc.blendShape(a,q=True,g=True)
				for i in range(0,len(self.base)): self.base[i]=shape(self.base[i])
				break
			else:
				sel.append(a)

		if len(self.base)>self.baseIndex and mc.objExists(self.base[self.baseIndex]):
			self.targets.extend(removeAll([self[0],self.base[self.baseIndex]],sel))
		else:
			self.targets.extend(sel[:-1])
			self.base=[shape(args[-1])]

		if self.useExisting and len(self[:])==0: self.find()

		if len(self)==0: self.create()

		self.addTargets(**self.__dict__)
Пример #27
0
def deferExec(*args,**keywords):
    #defaults
    melCommand=False
    repeatable=True
    showErrors=True
    shortNames={
        'mel':'melCommand',
        're':'repeatable',
        'se':'showErrors'
    }
    if len(args)==0: return
    for k in keywords:
        if k in locals():
            exec(k+'=keywords[k]')
        elif k in shortNames:
            exec(shortNames[k]+'=keywords[k]')
    zdc=MelGlobalVar('zenDelayedCommands')
    dcStr=zdc.get()
    if isinstance(dcStr,basestring):
        dc=dcStr.split(';')
    else:
        dcStr=''
        dc=[]
    dcsjVar=MelGlobalVar('zenDelayedCommandsSJ')
    dcsj=dcsjVar.get()
    if type(dcsj).__name__=='NoneType':
        dcsj=''
    for a in args:
        if not repeatable:
            dc.remove(a)
        if isinstance(a,basestring):
            if melCommand:
                dc.append(a)
            else:
                lines=a.split('\n')
                if len(lines)==1:
                    dc.append('python('+melEncode(a)+')')
                else:
                    pyCmd='python(\n'
                    for l in lines:
                        pyCmd+=melEncode(l+'\n')+'+\n'
                    pyCmd=pyCmd[:-2]+')'
                    dc.append(pyCmd)
    sjExists=False
    if isIterable(dc) and len(dc)>0 and isinstance(dcsj,(int,long,float)) and dcsj!=0 and mel.eval('scriptJob -ex '+str(dcsj)):
        sjExists=True
    dc=removeAll([''],dc)
    zdc.set(';'.join(dc))
    if not(sjExists):
        cmd=(
            'scriptJob \n'+
            '    -ro true\n'+
            '    -e "idle" \n'+
            '    (\n'+
            '        '+melEncode('string $zenDeferExec_errCmds[]={};\n')+'+\n'+
            '        '+melEncode('for($c in (stringArrayRemoveDuplicates(stringToStringArray($zenDelayedCommands,\";\"))))\n')+'+\n'+
            '        '+melEncode('{\n')+'+\n'+
            '        '+melEncode('    if(catch(`eval($c)`)) $zenDeferExec_errCmds[size($zenDeferExec_errCmds)]=$c;\n')+'+\n'+
            '        '+melEncode('}\n')+'+\n'+
            '        '+melEncode('for($c in $zenDeferExec_errCmds) warning("errors encountered: \\n"+$c+"\\n");\n')+'+\n'+
            '        '+melEncode('$zenDelayedCommands="";\n')+'+\n'+
            '        '+melEncode('$zenDelayedCommandsSJ=0;\n')+'\n'+
            '    )'
        )
        dcsjVar.set(mel.eval(cmd))
Пример #28
0
    def __init__(self, *args, **keywords):

        # default options

        self.controlObjects = [""]
        self.baseShapes = [""]
        self.influences = []
        self.deformed = []
        self.nurbsSamples = [10.0]
        self.smoothness = [0.0]
        self.nurbsSamples = [10]
        self.wrapSmoothness = [1]
        self.exclusiveBind = True
        self.maxDistance = 0
        self.calculateMaxDistance = False
        self.smooth = -1
        self.smoothType = 0

        self.wrapOptions = {
            "name": "",
            "before": False,
            "after": False,
            "split": False,
            "frontOfChain": False,
            "parallel": False,
            "prune": False,
        }

        self.shortNames = {
            "co": "controlObject",
            "bsa": "baseShapeAttr",
            "dsa": "deformShapeAttr",
            "d": "deformed",
            "n": "name",
            "bf": "before",
            "af": "after",
            "sp": "split",
            "foc": "frontOfChain",
            "par": "parallel",
            "pr": "prune",
            "eb": "exclusiveBind",
            "md": "maxDistance",
            "cmd": "calculateMaxDistance",
        }

        # attributes

        self.inputType = []

        for k in keywords:
            if k in self.__dict__:
                exec("self." + k + "=keywords[k]")
            elif k in self.wrapOptions:
                exec('self.wrapOptions["' + k + '"]=keywords[k]')
            elif k in self.shortNames:
                if shortNames[k] in self.__dict__:
                    exec("self." + shortNames[k] + "=keywords[k]")
                elif shortNames[k] in self.wrapOptions:
                    exec('self.wrapOptions["' + shortNames[k] + '"]=keywords[k]')

        if isinstance(self.smoothType, basestring) and self.smoothType in ["exponential", "linear"]:
            self.smoothType = ["exponential", "linear"].index(self.smoothType)

        self.influences = iterable(self.influences)
        self.baseShapes = iterable(self.baseShapes)
        self.deformed = iterable(self.deformed)

        # parse arguments

        if len(args) == 0 and (len(self.influences) == 0 or len(self.deformed) == 0):
            args = mc.ls(sl=True)

        sel = []
        for a in args:
            if (
                isinstance(a, basestring)
                and len(a.split(".")) > 1
                and str(mc.getAttr(a, type=True)) in ["mesh", "nurbsCurve", "nurbsSurface"]
            ) or (
                isIterable(a)
                and len(mc.ls(a, o=True)) > 0
                and mc.nodeType(mc.ls(a, o=True)[0]) in ["mesh", "nurbsCurve", "nurbsSurface"]
            ):
                sel.append(a)
            elif isinstance(a, basestring) and mc.nodeType(shape(a)) in ["mesh", "nurbsCurve", "nurbsSurface"]:
                sel.append(shape(a))

        if len(self.influences) == 0 and len(self.deformed) == 0:
            self.influences = sel[:-1]
            self.deformed = sel[-1:]
        elif len(self.influences) == 0 and len(self.deformed) > 0:
            self.influences = sel
        elif len(self.influences) > 0 and len(self.deformed) == 0:
            self.deformed = sel

        self.create()

        self.addInfluences(
            nurbsSamples=self.nurbsSamples,
            wrapSmoothness=self.wrapSmoothness,
            controlObjects=self.controlObjects,
            smooth=self.smooth,
            smoothType=self.smoothType,
            *self.influences
        )
Пример #29
0
	def __init__(self,*args,**keywords):

		# default options

		self.name='limb'
		self.stretch=20
		self.squash=0
		self.twist=True # performs auto detect
		self.sway=True
		self.switch='ik' # initial ik/fk switch state
		self.handleOptions=[{'type':'doubleEllipse','spin':-180},{'type':'doubleEllipse','spin':-90},{'type':'doubleEllipse'},{'type':'locator'}]
		self.tol=1.0 # angle tolerance for preferred angles
		self.parent=''

		self.shortNames=\
		{
			'n':'name',
			'p':'parent',
			'sp':'softParent',
			'co':'controlObjects',
			'ho':'handleOptions'
		}

		# attributes

		self.controlObjects=['','','','']
		self.bindPoses=[]
		self.joints=[]
		self.group=''
		self.orientAxis=''
		self.bendAxis=''
		self.poleAxis=''
		self.ctrlJoints=[]
		self.handles=[]
		self.endEffector=''
		self.ikHandle=''
		self.jointParent=''
		self.jointParent=''
		self.originalRotations={}
		self.bendDirection=0
		self.poleVector=[]
		self.poleVectorWorld=[]
		self.upVector=[]
		self.aimVector=[]
		self.parentSpaces=[]

		for k in keywords:

			if k in self.__dict__:
				exec('self.'+k+'=keywords[k]')
			elif k in self.shortNames:
				exec('self.'+self.shortNames[k]+'=keywords[k]')

		uniqueNames(re=True)

		if len(args)==0:
			args=mc.ls(sl=True)

		sel=[]
		for a in args:
			sel.extend(iterable(a))
		sel=hierarchyOrder(sel)

		# parse options

		defualtHandleOptions=[{'type':'doubleEllipse','spin':-180},{'type':'doubleEllipse','spin':-90},{'type':'doubleEllipse'},{'type':'locator'}]

		i=len(self.handleOptions)
		while len(self.handleOptions)<4:
			self.handleOption.append(defualtHandleOptions[i])
			i+=1

		if isinstance(self.handleOptions,dict):
			self.handleOptions=[self.handleOptions,self.handleOptions,self.handleOptions]
		elif isIterable(self.handleOptions):
			if len(self.handleOptions)==0:
				self.handleOptions.append({})
			while len(self.handleOptions)<3:
				self.handleOptions.append(self.handleOptions[-1])
		else:
			self.handleOptions=[{},{},{}]

		self.controlObjects=iterable(self.controlObjects)
		self.orientAxis=self.orientAxis.lower()

		self.baseTwist=''
		self.hierarchy=[]
		if len(sel)>2:
			for j in sel[:-1]:
				if len(hierarchyBetween(j,sel[-1]))>len(self.hierarchy):
					self.hierarchy=hierarchyBetween(j,sel[-1])
			closest=9e999
			for s in removeAll([self.hierarchy[0],self.hierarchy[-1]],sel):
				if\
				(
					len(iterable(mc.listRelatives(self.hierarchy[0],p=True)))==0 or
					s in mc.listRelatives(mc.listRelatives(self.hierarchy[0],p=True)[0],c=True,type='joint')
				):
					dist=distanceBetween(s,self.hierarchy[0])
					if dist<closest:
						closest=dist
						self.baseTwist=s
		else:
			self.hierarchy=hierarchyBetween(sel[0],sel[-1])

		self.bindPoses=iterable(getBindPoses(self.hierarchy))

		self.joints=['','','']

		if len(self.hierarchy)<3:
			raise Exception('There are no joints between your start and end joint. No IK created.')

		self.joints[0]=self.hierarchy[0]
		self.joints[-1]=self.hierarchy[-1]

		# find the orientation axis

		self.orientAxis='x'
		axisLen={'x':0,'y':0,'z':0}
		for j in self.hierarchy[1:]:
			for a in ['x','y','z']:
				axisLen[a]+=abs(mc.getAttr(j+'.t'+a))
				if axisLen[a]>axisLen[self.orientAxis]:
					self.orientAxis=a

		# find bend joint and pole vector

		self.originalRotations={}

		for j in self.hierarchy[1:-1]: # check to see if any have a non-zero preferred angle
			for a in removeAll(self.orientAxis,['x','y','z']):
				if abs(mc.getAttr(j+'.pa'+a))>=self.tol:
					self.originalRotations[j+'.r'+a]=mc.getAttr(j+'.r'+a)
					mc.setAttr(j+'.r'+a,mc.getAttr(j+'.pa'+a))
		greatestAngle=0
		for j in self.hierarchy[1:-1]:
			jPos=mc.xform(j,q=True,ws=True,rp=True)
			prevJPos=mc.xform(self.hierarchy[self.hierarchy.index(j)-1],q=True,ws=True,rp=True)
			nextJPos=mc.xform(self.hierarchy[self.hierarchy.index(j)+1],q=True,ws=True,rp=True)
			vAngle=mc.angleBetween(v1=normalize(jPos[0]-prevJPos[0],jPos[1]-prevJPos[1],jPos[2]-prevJPos[2]),v2=normalize(nextJPos[0]-jPos[0],nextJPos[1]-jPos[1],jPos[2]-jPos[2]))[-1]
			if abs(vAngle)>greatestAngle:
				greatestAngle=abs(vAngle)
				self.joints[1]=j

		mp=midPoint\
		(
			self.hierarchy[0],self.hierarchy[-1],
			bias=\
			(
				distanceBetween(self.hierarchy[0],self.joints[1])/
				(distanceBetween(self.hierarchy[0],self.joints[1])+distanceBetween(self.joints[1],self.hierarchy[-1]))
			)
		)

		bendPoint=mc.xform(self.joints[1],q=True,ws=True,rp=True)

		self.poleVectorWorld=normalize\
		(
			bendPoint[0]-mp[0],
			bendPoint[1]-mp[1],
			bendPoint[2]-mp[2]
		)

		pmm=mc.createNode('pointMatrixMult')
		mc.setAttr(pmm+'.vm',True)
		mc.connectAttr(self.joints[1]+'.worldInverseMatrix',pmm+'.im')
		mc.setAttr(pmm+'.ip',*self.poleVectorWorld)

		self.poleVector=mc.getAttr(pmm+'.o')[0]

		disconnectNodes(pmm)
		mc.delete(pmm)

		greatestLength=0.0
		for i in [0,1,2]:
			if abs(self.poleVector[i])>greatestLength and ['x','y','z'][i]!=self.orientAxis:
				self.poleAxis=['x','y','z'][i]
				greatestLength=abs(self.poleVector[i])
				self.bendDirection=-abs(self.poleVector[i])/self.poleVector[i]

		for r in self.originalRotations:
			mc.setAttr(r,self.originalRotations[r])

		preferredAngleWarning=False
		if not mc.objExists(self.joints[1]):
			preferredAngleWarning=True
			mp=midPoint(self.hierarchy[0],self.hierarchy[-1])
			cd=9e999
			dist=0
			for j in self.hierarchy[1:-1]:
				dist=distanceBetween(j,mp)
				if dist<cd:
					cd=dist
					self.joints[1]=j
					self.bendAxis=removeAll(self.orientAxis,['z','y','x'])[0]

		if self.poleAxis=='': self.poleAxis=removeAll([self.orientAxis,self.bendAxis],['x','y','z'])[0]
		if self.bendAxis=='': self.bendAxis=removeAll([self.orientAxis,self.poleAxis],['x','y','z'])[0]
		if self.orientAxis=='': self.orientAxis=removeAll([self.bendAxis,self.poleAxis],['x','y','z'])[0]

		if self.poleAxis=='x': self.poleVector=[-self.bendDirection,0.0,0.0]
		if self.poleAxis=='y': self.poleVector=[0.0,-self.bendDirection,0.0]
		if self.poleAxis=='z': self.poleVector=[0.0,0.0,-self.bendDirection]

		if self.bendAxis=='x': self.upVector=[-self.bendDirection,0.0,0.0]
		if self.bendAxis=='y': self.upVector=[0.0,-self.bendDirection,0.0]
		if self.bendAxis=='z': self.upVector=[0.0,0.0,-self.bendDirection]

		if self.orientAxis=='x': self.aimVector=[self.bendDirection,0.0,0.0]
		if self.orientAxis=='y': self.aimVector=[0.0,self.bendDirection,0.0]
		if self.orientAxis=='z': self.aimVector=[0.0,0.0,self.bendDirection]

		if mc.objExists(self.baseTwist):

			conn=False
			for a in ['.r','.rx','.ry','.rz']:
				if mc.connectionInfo(self.baseTwist+a,id=True):
					conn=True
			if not conn:
				mc.orientConstraint(self.joints[0],self.baseTwist,sk=self.orientAxis)

		# load ik2Bsolver - ikRPSolver does not work well with this setup

		mel.eval('ik2Bsolver')

		self.create()

		if preferredAngleWarning:
			raise Warning('Warning: Joints are co-linear and no preferred angles were set. Results may be unpredictable.')
Пример #30
0
def midPoint(*args, **keywords):  # weighted midPoint

    world = False
    local = False

    bias = 0.5  # 0.0==point1, 1.0==point2

    shortNames = {"w": "world", "l": "local", "b": "bias"}

    for k in keywords:
        if k in locals():
            exec(k + "=keywords[k]")
        if k in shortNames:
            exec(shortNames[k] + "=keywords[k]")

    if not (world or local):
        world = True

    if len(args) == 0:
        args = mc.ls(sl=True)
    if len(args) == 0:
        return

    p = []
    for a in args:
        if isIterable(a) and len(a) >= 3 and isinstance(a[0], (float, long, int)) and len(a) >= 3:
            p.append(a)

        elif isinstance(a, basestring) and mc.objExists(a):

            if len(a.split(".")) > 1:
                try:
                    p.append(mc.pointPosition(a, w=world, l=local))
                except:
                    if mc.nodeType(mc.ls(a, o=True)) == "mesh":
                        for v in iterable(mc.ls(mc.polyListComponentConversion(a, tv=True), fl=True)):
                            p.append(mc.pointPosition(v, w=world, l=local))
            else:
                try:
                    p.append(mc.pointPosition(a + ".rp", w=world, l=local))
                except:
                    err = True

    if len(p) < 1:
        return
    if len(p) == 1:
        return p[0]

    mp = [0.0, 0.0, 0.0]

    if len(p) == 2:  # use bias

        mp = (
            (float(p[0][0]) * (1 - bias) + float(p[-1][0]) * bias),
            (float(p[0][1]) * (1 - bias) + float(p[-1][1]) * bias),
            (float(p[0][2]) * (1 - bias) + float(p[-1][2]) * bias),
        )

    else:  # disregard bias

        for pp in p:

            mp = (
                mp[0] + (float(pp[0]) * (1.0 / float(len(p)))),
                mp[1] + (float(pp[1]) * (1.0 / float(len(p)))),
                mp[2] + (float(pp[2]) * (1.0 / float(len(p)))),
            )

    return mp
Пример #31
0
	def __init__(self,*args,**keywords):

		#check to make sure unique names are used in scene
		uniqueNames(iterable(mc.ls(type='dagNode')),re=True)

		#default options
		self.number=1 #if there are no transforms, create this many rivets
		self.distribute=''
		self.parents=['','']
		self.rebuild=False
		self.taper='none' # none, normal, distance
		self.scale='none' # none, uniform, or relative
		self.scaleDirection=['length','width'] # length, width
		self.createAimCurve=False
		self.aimCurve=''
		self.handles=[]
		self.handleShapes=[]
		self.autoFlexGroups=[]
		self.mo=True # maintain offset
		self.ctrls=[] #by default control attributes are placed on given transforms
		self.keepPivot=True
		self.snapToSurface=False
		self.realign=False
		self.rivets=[]
		self.ClosestPoints=[]
		self.aimGroups=[]
		self.softParents=[]
		self.ArcCtrl=[]
		self.arcWeight=.5
		self.closestPoint='' # geometry, pivot
		self.organize=True
		self.constraint=False # use a parent constraint
		self.parent=False # create a transform and parent objects to it

		self.spaceTr=''
		self.surfaceAttr=''
		self.bindPoses=[]
		self.parentSpaces=[]
		self.hasGeometry=True
		self.skipRotate=[]
		self.skipTranslate=[]
		self.skipScale=[]
		self.skipScaleObjects=[]
		self.skipRotateObjects=[]
		self.skipTranslateObjects=[]
		self.minScaleWidth=0
		self.maxScaleWidth=1
		self.minScaleLength=0
		self.maxScaleLength=1
		self.surfaceMatrix=''
		self.surfaceInverseMatrix=''
		self.worldMatrix=''
		self.trs=[]
		self.uSpans=-1
		self.vSpans=-1
		self.skins=[]

		self.shortNames=\
		{
			'sd':'scaleDirection',
			'p':'parents',
			'sp':'softParents'
		}

		sel=[]
		if len(args)==0:
			sel=mc.ls(sl=True)
		for a in args:
			sel.extend(iterable(a))

		self.bindPoses=iterable(getBindPoses(sel))

		if len(self.bindPoses)>0:
			goToDagPose(self.bindPoses[0])

		self.edges=PolyEdgeList(sel,f=True)
		self.trs=removeDuplicates(mc.ls(self.edges.etcObj,tr=True))

		if len(self.edges)==0: #look for a surface or surface attribute
			reversedObjList=getReversed(self.edges.etcObj)
			for obj in reversedObjList:
				if len(obj.split('.'))>1 and mc.getAttr(obj,type=True)=='nurbsSurface':
					self.surfaceAttr=obj
					obj=mc.ls(self.surfaceAttr,o=True)[0]
					if mc.nodeType(obj)=='nurbsSurface':
						self.uSpans=mc.getAttr(obj+'.spansU')
						self.vSpans=mc.getAttr(obj+'.spansV')
						self.spaceTr=mc.listRelatives(obj,p=True)[0]
					break
				elif mc.nodeType(obj)=='nurbsSurface':
					self.surfaceAttr=obj+'.worldSpace[0]'
					self.spaceTr=mc.listRelatives(obj,p=True)[0]
					self.uSpans=mc.getAttr(obj+'.spansU')
					self.vSpans=mc.getAttr(obj+'.spansV')
					self.trs.remove(obj)
					break
				else:
					children=mc.listRelatives(obj,c=True,s=True,ni=True,type='nurbsSurface')
					if isIterable(children) and len(children)>0:
						self.spaceTr=mc.ls(obj)[0]
						self.surfaceAttr=children[0]+'.worldSpace[0]'
						self.uSpans=mc.getAttr(children[0]+'.spansU')
						self.vSpans=mc.getAttr(children[0]+'.spansV')
						self.trs.remove(obj)
						break
		else:
			self.spaceTr=self.edges.getTr()

		for k in keywords:
			if k in self.__dict__:
				exec('self.'+k+'=keywords[k]')
			elif k in self.shortNames:
				exec('self.'+self.shortNames[k]+'=keywords[k]')

		if len(iterable(self.parents))==1:
			self.parents=[iterable(self.parents)[0],iterable(self.parents)[0]]
		if len(iterable(self.softParents))==1:
			self.softParents=[iterable(self.softParents)[0],iterable(self.softParents)[0]]

		if len(self.ctrls)==0:
			self.ctrls=self.trs
		while len(self.ctrls)<len(self.trs):
			self.ctrls.append(self.ctrls[-1])

		if len(self.skipRotate)>0:
			for i in self.skipRotate:
				self.skipRotateObjects.append(self.trs[self.skipRotate[i]])
		if len(self.skipTranslate)>0:
			for i in self.skipTranslate:
				self.skipTranslateObjects.append(self.trs[self.skipTranslate[i]])
		if len(self.skipScale)>0:
			for i in self.skipScale:
				self.skipScaleObjects.append(self.trs[self.skipScale[i]])

		if len(self.trs)>0:
			for t in self.trs:
				shCount=len\
				(
					removeDuplicates(mc.listRelatives(t,c=True,type='nurbsSurface'))+
					removeDuplicates(mc.listRelatives(t,c=True,type='nurbsCurve'))+
					removeDuplicates(mc.listRelatives(t,c=True,type='mesh'))
				)

				if shCount==0:
					self.hasGeometry=False
					self.closestPoint='pivot'
					break

		if self.closestPoint=='' and self.hasGeometry: # default to pivot if using snap to surface, otherwise defualts to geometry
			if self.snapToSurface:
				self.closestPoint='pivot'
			else:
				self.closestPoint='geometry'

		if len(self.trs)!=0:
			self.number=len(self.trs)

		if len(self.ctrls)<len(self.trs):
			self.ctrls=self.trs

		if not self.parent and not self.constraint:
			self.parent=True

		if self.createAimCurve:
			self.parent=True
			#self.constraint=False

		#find the root joint if present
		try:
			joints=removeDuplicates(mc.listConnections(iterable(mc.ls(iterable(mc.listHistory(self.surfaceAttr)))),type='joint'))
			if len(joints)>0: self.spaceTr=hierarchyOrder(joints)[0]
		except:
			pass

		self.create()