示例#1
0
	def arcCheck(self):

		if len(self.arcPoints)>4: # if more than the maximum of 4 points have been given, determine which to use
			if float(int(float(len(self.arcPoints)-1)/3.0))==float(len(self.arcPoints)-1)/3.0: #divisible by 3
				self.arcPoints=\
				[
					self.arcPoints[0],
					self.arcPoints[int((len(self.arcPoints)-1)/3.0)], # 1/3
					self.arcPoints[int((2*len(self.arcPoints)-1)/3.0)], # 2/3
					self.arcPoints[-1]
				]
			elif float(int(float(len(self.arcPoints)-1)/2.0))==float(len(self.arcPoints)-1)/2.0: #even
				self.arcPoints=\
				[
					self.arcPoints[0],
					self.arcPoints[int(float(len(self.arcPoints)-1)/2.0)], # 1/2
					self.arcPoints[int(float(len(self.arcPoints)-1)/2.0)], # 1/2
					self.arcPoints[-1]
				]
			else:
				self.arcPoints=\
				[
					self.arcPoints[0],
					self.arcPoints[int(float(len(self.arcPoints)-1)/2.0)], # 1/2-
					self.arcPoints[int(float(len(self.arcPoints)-1)/2.0)+1], # 1/2+
					self.arcPoints[-1]
				]

		# check to see that all the points are not on the same vector ( co-linear )
		vA=vB=vC=cD=[]
		realArcPoints=self.arcPoints[:]
		mp=midPoint(self.arcPoints[0],self.arcPoints[-1])

		dist=distanceBetween(self.arcPoints[0],self.arcPoints[-1])
		zp=dist/1000
		offsets=[[self.poleVector[0]*zp,self.poleVector[1]*zp,self.poleVector[2]*zp],(0,zp,0),(0,0,zp),(zp,0,0)]
		for i in range(1,10):
			for offset in offsets:
				if len(self.arcPoints)>2:
					vA=normalize(self.arcPoints[1][0]-self.arcPoints[0][0],self.arcPoints[1][1]-self.arcPoints[0][1],self.arcPoints[1][2]-self.arcPoints[0][2])
					vB=normalize(self.arcPoints[-1][0]-self.arcPoints[1][0],self.arcPoints[-1][1]-self.arcPoints[1][1],self.arcPoints[-1][2]-self.arcPoints[1][2])
					vC=normalize(self.arcPoints[-2][0]-self.arcPoints[0][0],self.arcPoints[-2][1]-self.arcPoints[0][1],self.arcPoints[-2][2]-self.arcPoints[0][2])
					vD=normalize(self.arcPoints[-1][0]-self.arcPoints[-2][0],self.arcPoints[-1][1]-self.arcPoints[-2][1],self.arcPoints[-1][2]-self.arcPoints[-2][2])
				if distanceBetween(vA,vB)<zp/4 or distanceBetween(vC,vD)<zp/4 or len(self.arcPoints)==2:
					self.arcPoints=realArcPoints[:]
					if len(self.arcPoints)==2:
						 self.arcPoints=[self.arcPoints[0],[],self.arcPoints[-1]]
					self.arcPoints[1]=(mp[0]+offset[0]*i,mp[1]+offset[1]*i,mp[2]+offset[2]*i)
				else:
					break
			if distanceBetween(vA,vB)<zp/4 or distanceBetween(vC,vD)<zp/4 or len(self.arcPoints)==2: break
示例#2
0
文件: ikLimb.py 项目: jonntd/zentools
	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.')
示例#3
0
def geoConnect(*args,**keywords):
	
	"""
Connects shapes and worldSpace transforms of one shape to another, or all shapes in one file or namespace to another.
Accepts an input of 2 or more file names, 2 or more name spaces, or any even number of objects.
	"""
	
	# default options
	driverNameSpace=''
	drivenNameSpace=''
	drivers=[]
	driven=[]
	hide=[]
	recursive=False
	maintainOffset=False
	output=''
	
	returnVal=[]
	
	shortNames=\
	{
		'r':'recursive',
		'mo':'maintainOffset',
		'o':'output',
		'rv':'returnVal',
		'h':'hide'
	}
			
	for k in keywords:
		if k in locals():
			exec(k+'=keywords[k]')
		elif k in shortNames:
			exec(shortNames[k]+'=keywords[k]')
			
	if len(args)==0 and driverNameSpace=='' and drivenNameSpace=='':
		sel=iterable(mc.ls(sl=True))
		
	sel=[]
	for a in args:
		sel.extend(iterable(a))
		
	for i in range(0,len(sel)):
		if sel[i]=='':
			sel[i]=':'
	
	fromFiles=True
	for i in range(0,len(sel)):
		if len(sel[i].split('.'))>1:
			if not os.path.isfile(sel[i]):
				filePath=findFile(sel[i])
				if os.path.isfile(filePath):
					sel[i]=filePath
				else:
					fromFiles=False
					break
		else:
			fromFiles=False
			break
			
	hide=iterable(hide)
						
	while len(hide)<len(sel):
		hide.append(False)

	matchByNameSpace=True
	
	if fromFiles:
		if len(sel)==1:
			sel.append(sel[0])
			sel[0]=mc.file(q=True,l=True)[0]
		else:
			if mc.file(q=True,l=True)[0]!=sel[0]:
				mc.file(sel[0],o=True,f=True)
		driverNameSpace=mc.namespaceInfo(cur=True)
		drivenNameSpace=os.path.basename(sel[1].split('.')[0])
		mc.file(sel[1],i=True,ra=True,namespace=drivenNameSpace,pr=True,loadReferenceDepth='all',options='v=1')
	else:
		nameSpaces=[':']+iterable(mc.namespaceInfo(lon=True))
		for s in sel:
			if s not in nameSpaces:
				matchByNameSpace=False
				break
			
		if not matchByNameSpace:
			sel=iterable(mc.ls(sel))
		
	matchNames=False
	
	if matchByNameSpace:
		
		currentNameSpace=mc.namespaceInfo(cur=True)
		
		if not fromFiles:
			if len(sel)>1:
				driverNameSpace=sel[0]
			if len(sel)==1:
				driverNameSpace=':'
			drivenNameSpace=sel[1]
			mc.namespace(set=driverNameSpace)
				
		for d in iterable(mc.ls(mc.namespaceInfo(ls=True),type=('mesh','nurbsCurve','nurbsSurface'))):
			if mc.getAttr(d+'.io')==False:
				drivers.append(d)
		
		mc.namespace(set=drivenNameSpace)
				
		for d in iterable(mc.ls(mc.namespaceInfo(ls=True),type=('mesh','nurbsCurve','nurbsSurface'))):
			if mc.getAttr(d+'.io')==False:
				driven.append(d)
		
		mc.namespace(set=currentNameSpace)
		
		drivers.sort()
		driven.sort()
		
		matchNames=True
		
	elif len(sel)>1:
			
		driven=sel[int(len(sel)/2):int(len(sel)/2)*2]
		drivers=sel[:int(len(sel)/2)]
		
		if recursive:
			
			matchNames=True

			drs=drivers
			dns=driven
			
			if len(drs)<=len(dns):
				r=len(drs)
			else:
				r=len(dns)
			
			for i in range(0,r):
				
				dr=drs[i]
				dn=dns[i]
				
				if shape(dr)!=dr or shape(dn)!=dn:
					
					drivers.remove(dr)
					driven.remove(dn)
					
				if shape(dr)!=dr and shape(dn)!=dn:
					
					drc=[]
					for dr in iterable(mc.listRelatives(dr,ad=True,type=('mesh','nurbsCurve','nurbsSurface'))):
						if mc.getAttr(dr+'.io')==False:
							drc.append(dr)
					drc.sort()
					
					dnc=[]
					for dn in iterable(mc.listRelatives(dn,ad=True,type=('mesh','nurbsCurve','nurbsSurface'))):
						if mc.getAttr(dn+'.io')==False:
							dnc.append(dn)
					dnc.sort()
							
					drivers.extend(drc)
					driven.extend(dnc)
							
		else:
			
			#check to see if we can match by name spaces
			if len(drivers[0].split(':'))>1 or len(driven[0].split(':'))>1:

				if len(drivers[0].split(':'))>1:
					driverNameSpace=':'.join(drivers[0].split(':')[:-1])
				if len(driven[0].split(':'))>1:
					drivenNameSpace=':'.join(driven[0].split(':')[:-1])
					
				matchNames=True
				
				if len(drivers)<=len(driven):
					r=len(drivers) 
				else:
					r=len(driven)
				
				for i in range(0,r):
					
					if\
					(
						(
							(driverNameSpace=='' and len(drivers[i].split(':'))<2) or
							':'.join(drivers[i].split(':')[:-1])==driverNameSpace
						)
						and
						(
							(drivenNameSpace=='' and len(driven[i].split(':'))<2) or
							':'.join(driven[i].split(':')[:-1])==drivenNameSpace
						)
						and
						(
							drivers[i].split(':')[-1]==driven[i].split(':')[-1]
						)
					):
						pass
					else:
						matchNames=False
						break
						
			driversHold=drivers
			drivenHold=driven
			drivers=[]
			driven=[]
			
			if len(drivers)<=len(driven):
				r=len(drivers)
			else:
				r=len(driven)
				
			for i in range(0,r):
				if shape(driversHold[i])!='' and shape(drivenHold[i])!='':
					drivers.append(shape(drivers[i]))
					drivers.append(shape(driven[i]))		
	else:
		return
		
	if matchNames: # match names
		
		driverParents=[]
		driverHasSiblings=[]
		driversBN=[]
		for i in range(0,len(drivers)):
			driversBN.append(drivers[i].split('|')[-1].split(':')[-1])
			driverParents.append(mc.listRelatives(drivers[i],p=True)[0].split('|')[-1].split(':')[-1])
			sib=False
			for c in mc.listRelatives(driverParents[-1],c=True,type=mc.nodeType(drivers[i])):
				if  c!=drivers[i] and mc.getAttr(c+'.io')==False:
					sib=True
			driverHasSiblings.append(sib)

		drivenParents=[]
		drivenParentLists=[]
		drivenBN=[]
		for i in range(0,len(driven)):
			#if driven[i].split(':')>1:
			drivenBN.append(driven[i].split('|')[-1].split(':')[-1])
			drivenParentLists.append(iterable(mc.ls(driven[i],l=True)[0].split('|')[:-1]))
			for n in range(0,len(drivenParentLists[-1])):
				drivenParentLists[-1][n]=drivenParentLists[-1][n].split(':')[-1]
			drivenParents.extend(drivenParentLists[-1])
		
		driversHold=drivers
		drivenHold=driven
		driven=[]
		drivers=[]
				
		for i in range(0,len(driversBN)):
			
			matched=False
			
			if (driverParents[i] in drivenParents) and not driverHasSiblings[i]: # match by transform names
				for n in range(0,len(drivenParentLists)):
					if driverParents[i] in drivenParentLists[n]:
						drivers.append(driversHold[i])
						driven.append(drivenHold[n])
			elif driversBN[i] in drivenBN:	# match by shape names
				drivers.append(driversHold[i])
				driven.append(drivenHold[drivenBN.index(driversBN[i])])
						
	for i in range(0,len(drivers)):
							
		driverSh=drivers[i]
		drivenSh=driven[i]
				
		driverTr=mc.listRelatives(driverSh,p=True)[0]
		drivenTr=mc.listRelatives(drivenSh,p=True)[0]

		#drive shape
		if maintainOffset==False:
			shapeMatch=True
		else:
			shapeMatch=False
		
		if shapeMatch and mc.nodeType(driverSh)!=mc.nodeType(drivenSh):
			
			shapeMatch=False
			
		if shapeMatch and mc.nodeType(driverSh)=='nurbsCurve' or mc.nodeType(driverSh)=='nurbsSurface':
			
			if mc.ls(driverSh+'.cv[*]')!=mc.ls(drivenSh+'.cv[*]'):
				shapeMatch=False
				
		if shapeMatch and mc.nodeType(driverSh)=='mesh':
			
			if\
			(
				len(mc.ls(driverSh+'.vtx[*]',fl=True))!=len(mc.ls(drivenSh+'.vtx[*]',fl=True)) or
				len(mc.ls(driverSh+'.f[*]',fl=True))!=len(mc.ls(drivenSh+'.f[*]',fl=True)) or
				len(mc.ls(driverSh+'.e[*]',fl=True))!=len(mc.ls(drivenSh+'.e[*]',fl=True))
			):
				shapeMatch=False
				
		# try to connect with blendShape
			
		if shapeMatch:
			
			try:
				bs=BlendShape(driverSh,drivenSh,w=10,c=False)[0]
				returnVal.append(bs)
			except:
				shapeMatch=False
				
		# connect transforms
		
		mm=mc.createNode('multMatrix')
		dm=mc.createNode('decomposeMatrix')
		
		mc.connectAttr(driverTr+'.wm[0]',mm+'.i[1]')
		mc.connectAttr(drivenTr+'.pim',mm+'.i[0]')
		mc.connectAttr(mm+'.o',dm+'.imat')
		mc.connectAttr(dm+'.os',drivenTr+'.s')
		mc.connectAttr(dm+'.osh',drivenTr+'.sh')
		
		if shapeMatch:
			mc.parentConstraint(driverTr,drivenTr,mo=False)
		else:
			mc.parentConstraint(driverTr,drivenTr,mo=True)
		
		for attr in ['rp','rpt','sp','spt','ra','ro','it','rq']:
			for a in mc.listAttr(driverTr+'.'+attr):
				mc.connectAttr(driverTr+'.'+a,drivenTr+'.'+a,f=True)		
		
		if not shapeMatch: # connect with wrap

			if mc.nodeType(driverSh)=='mesh' and mc.nodeType(drivenSh)=='mesh':
				
				driverArea=mc.polyEvaluate(driverSh,a=True)
				drivenArea=mc.polyEvaluate(drivenSh,a=True)
				areaPercDiff=(driverArea-drivenArea)/drivenArea

			if mc.nodeType(driverSh)=='mesh' and mc.nodeType(drivenSh)=='mesh' and areaPercDiff>.1:			
							
				cpom=mc.createNode('closestPointOnMesh')
				mc.connectAttr(driverSh+'.worldMesh[0]',cpom+'.im')
				
				driverFaces=[]
				drivenFaces=iterable(mc.ls(drivenSh+'.f[*]',fl=True))
								
				mc.progressWindow(st='Analyzing mesh...',title='Working',max=len(drivenFaces)/20,ii=True)
				
				n=0
				for f in drivenFaces:
					
					mc.setAttr(cpom+'.ip',*midPoint(f))
					driverFaces.append(driverSh+'.f['+str(mc.getAttr(cpom+'.f'))+']')
					
					if float(n)/20.0==int(n/20):
						mc.progressWindow(e=True,s=1)
						if mc.progressWindow(q=True,ic=True):
							if mc.objExists(cpom): mc.delete(cpom)
							mc.progressWindow(e=True,ep=True)
							raise Exception('User interupt.')
					n+=1
				
				mc.progressWindow(e=True,ep=True)
								
				driverFaces=removeDuplicates(driverFaces)
				wrap=Wrap(driverFaces,drivenSh)
				if mc.objExists(cpom): mc.delete(cpom)
			else:
				wrap=Wrap(driverSh,drivenSh)
					
			returnVal.append(wrap)

		if hide[0]:
			mc.hide(driverSh)
		if hide[1]:
			mc.hide(drivenSh)

	if (fromFiles or matchByNameSpace) and len(sel)>2:
		
		return geoConnect(o=output,r=recursive,mo=maintainOffset,rv=returnVal,h=(hide[0]+hide[2:]),*(sel[0]+sel[2:]))
		
	elif output!='': # save
		
		if len(output.split('.'))<2:
			output=output+'.'+sel[0].split('.')[-1]
		
		if not os.path.isdir(os.path.dirname(output)):
			output=os.path.dirname(sel[0])+'/'+output
			
		if output.split('.')[-1]=='.ma':
			outputType='mayaAscii'
		else:
			outputType='mayaBinary'
		
		mc.file(rename=output)
		mc.file(f=True,save=True,type=outputType)
		
	else:
		
		return returnVal