Ejemplo n.º 1
0
	def mkControlObjects(self):

		if not mc.objExists(self.handles[-1]):

			self.handles[-1]=mc.createNode('transform',n=uniqueNames(self.name[-1]))
			mc.xform(self.handles[-1],ws=True,a=True,m=mc.xform(self.ArcCtrl.handles[-1],q=True,ws=True,m=True))
			mc.xform(self.handles[-1],ws=True,a=True,piv=mc.xform(self.ArcCtrl.handles[-1],q=True,a=True,ws=True,piv=True)[:3])
			if 'type' not in self.handleOptions[-1]:
				self.handleOptions[-1]['type']=self.handleType[-1]
			if 'radius' not in self.handleOptions[-1]:
				self.handleOptions[-1]['radius']=self.radius
			self.handleShape[-1]=Handle(self.handles[-1],**self.handleOptions[-1])

		if mc.objExists(self.parent[-1]):
			mc.parent(self.handles[-1],self.parent[-1])

		if mc.objExists(self.softParent[-1]):
			self.parentSpace[-1]=ParentSpace(self.handles[-1],self.softParent[-1])
			for bp in getBindPoses(self.jointHierarchy): mc.dagPose(self.parentSpace[-1],a=True,n=bp)

		mc.makeIdentity(self.handles[-1],apply=True,t=True)#,r=True)

		mc.addAttr(self.handles[-1],ln='stretch',at='float',min=0,k=1,dv=self.stretch)
		mc.addAttr(self.handles[-1],ln='squash',at='float',min=0,max=1,k=1,dv=self.squash)
		mc.addAttr(self.handles[-1],ln='arcWeight',at='float',min=0,max=1,k=1,dv=self.arcWeight)
		mc.addAttr(self.handles[-1],ln='width',at='float',min=0.0001,k=1,dv=self.width)
		mc.connectAttr(self.handles[-1]+'.stretch',self.ArcCtrl.handles[-1]+'.stretch',f=True)
		mc.connectAttr(self.handles[-1]+'.squash',self.ArcCtrl.handles[-1]+'.squash',f=True)
		mc.connectAttr(self.handles[-1]+'.arcWeight',self.ArcCtrl.handles[-1]+'.arcWeight',f=True)
		mc.connectAttr(self.handles[-1]+'.width',self.ArcCtrl.handles[0]+'.width',f=True)

		if self.curl:
			mc.addAttr(self.handles[-1],ln='curl',at='doubleAngle',k=1,dv=0)

			for r in removeAll(self.jointHierarchy,self.rivet):

				axis='x'
				longestAxisLen=0

				for a in ['x','y','z']:

					axisLen=abs(mc.getAttr(r+'.t'+a))

					if axisLen>longestAxisLen:
						longestAxisLen=axisLen
						axis=a

				behaviorMirrored=False

				try:
					parentJoint=mc.listRelatives(r,p=True)[0]

					oppositeJoint=removeAll(r,mc.listRelatives(parentJoint,c=True,type='joint'))[0]
					for a in ['x','y','z']:

						if\
						(
							abs(180-abs(abs(mc.getAttr(r+'.jo'+a))-abs(mc.getAttr(oppositeJoint+'.jo'+a))))<5
						):
							behaviorMirrored=True
							break
				except:
					pass

				pcr=mc.listConnections(r+'.rx',type='parentConstraint')[0]

				pcTargets=mc.parentConstraint(pcr,q=True,tl=True)
				pcIDs=[]
				nsc=listNodeConnections(pcr,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)
				pcIDs.sort()
				pcID=pcIDs[-1]

				pma=mc.createNode('plusMinusAverage')

				if mc.getAttr(r+'.uPos')>50:
					mc.setAttr(pma+'.op',2)
					if\
					(
						(behaviorMirrored and parentJoint!=self.jointHierarchy[-1])
					):
						mc.setAttr(pma+'.op',1)
				if mc.getAttr(r+'.uPos')<50:
					mc.setAttr(pma+'.op',1)
					if\
					(
						behaviorMirrored
					):
						mc.setAttr(pma+'.op',2)

				mc.setAttr(pma+'.i1[0]',mc.getAttr(pcr+'.tg['+str(pcID)+'].tor'+axis))
				mc.setAttr(pcr+'.tg['+str(pcID)+'].tor'+axis,lock=False)
				mc.connectAttr(self.handles[-1]+'.curl',pma+'.i1[1]')
				mc.connectAttr(pma+'.o1',pcr+'.tg['+str(pcID)+'].tor'+axis)





		mc.parentConstraint(self.handles[-1],self.ArcCtrl.handles[-1],mo=True)
		mc.scaleConstraint(self.handles[-1],self.ArcCtrl.handles[-1],sk=('x','y'),mo=True)

		for bp in getBindPoses(self.jointHierarchy): mc.dagPose(self.handles[-1],a=True,n=bp)

		mc.setAttr(self.handles[-1]+'.sy',k=False,lock=True)
		mc.setAttr(self.handles[-1]+'.sx',k=False,lock=True)
		if not self.spread:
			mc.setAttr(self.handles[-1]+'.sz',k=False,lock=True)


		mc.setAttr(self.handles[-1]+'.v',k=False,cb=True)

		for bp in getBindPoses(self.jointHierarchy): mc.dagPose(self.handles[-1],a=True,n=bp)
Ejemplo n.º 2
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.radius=1
		self.arcWeight=.75
		self.handles=['ArcIKCtrl#']
		self.parent=['|']
		self.handleType=['doubleEllipse']
		self.handleOptions=[{}]
		self.softParent=['']
		self.name=''
		self.squash=20
		self.stretch=20
		self.width=1
		self.allowScale=False # not functional
		self.minWidth=0
		self.maxWidth=5
		self.spread=False #requires ribs
		self.curl=False #requires ribs
		self.wrap=False

		self.shortNames=\
		{
			'n':'name',
			'ht':'handleType',
			'ho':'handleOptions',
			'sp':'softParent',
			'p':'parent',
			'spr':'spread',
			'c':'curl'
		}

		# attributes
		self.handleShape=['']
		self.parentSpace=['']

		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]')

		self.handles=iterable(self.handles)
		self.parent=iterable(self.parent)
		self.handleType=iterable(self.handleType)
		self.softParent=iterable(self.softParent)
		self.name=iterable(self.name)
		if isinstance(self.handleOptions,dict):
			self.handleOptions=[self.handleOptions]

		# parse arguments
		if len(args)==0: args=mc.ls(sl=True,fl=True)

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

		self.jointHierarchy=hierarchyBetween([sel[0],sel[-1]],type='joint')

		if ('radius' not in keywords) and ('r' not in keywords):
			hDist=distanceBetween(self.jointHierarchy[0],self.jointHierarchy[-1])
			self.radius=hDist/3

		self.ArcCtrl=ArcCtrl\
		(
			self.jointHierarchy,
			p=[self.jointHierarchy[0],'.'],
			stretch=self.stretch,
			squash=self.squash,
			arcWeight=self.arcWeight,
			createSurface=True,
			scaleLength=True
		)

		self.constrainJoints()
		self.mkControlObjects()

		self[:]=self.handles
Ejemplo n.º 3
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.')
Ejemplo n.º 4
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])
Ejemplo n.º 5
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()
Ejemplo n.º 6
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()
Ejemplo n.º 7
0
	def __init__(self,*args,**keywords):
		
		#check to make sure unique names are used in scene
		uniqueNames(iterable(mc.ls(type='dagNode')),re=True)
		
		self.tol=.001
		
		for k in keywords:
			if k in self.__dict__:
				if type(eval('self.'+k)).__name__==type(keywords[k]).__name__:
					exec('self.'+k+'=keywords[k]')
		
		sel=[]
		for a in args:
			if isIterable(a):
				sel.extend(a)
			else:
				sel.append(a)
				
		sel=removeDuplicates(mc.ls(sel)+mc.ls(sl=True,o=True))
		
		if len(sel)<2: raise Exception("Procedure requires two polygon meshes, nurbs surfaces, or nurbs curves.")
		else: sel=sel[:2]			
		
		oo=Decimal('Infinity')
		self[:]=[[oo,oo,oo],[oo,oo,oo]]
		
		noo=Decimal('-Infinity')
		self.antipodes=[[noo,noo,noo],[noo,noo,noo]]  
		
		self.uvs=[(-1,-1),(-1,-1)]
		self.closestFaces=['','']
		self.closestFaceIDs=[-1,-1]
		self.closestVertexIDs=[-1,-1]
		self.antipodeFaces=['','']
		self.antipodeFaceIDs=[-1,-1]
		self.antipodeUVs=[(-1,-1),(-1,-1)]
		self.antipodeVertexIDs=[-1,-1]

		self.trs,self.types,self.shapes,self.shAttr,self.knots,self.roughAPIDs,self.roughCPIDs,self.uv=[],[],[],[],[],[],[],[]
		density,maxDensity,cpID,searchID,i=0,0,0,0,0
		ci,si='',''
				
		for s in sel: # find shapes and node types and determine which is denser
			
			if len(s.split('.'))>1:
				sha=s
				nt=mc.getAttr(sha,type=True)
				if nt=='nurbsCurve' or nt=='nurbsSurface' or nt=='mesh':
					self.shapes.append('')
					self.trs.append('')
					self.shAttr.append(sha)
					self.types.append(nt)
				else:
					raise Exception("Arguments must be polygon meshes, nurbs surfaces, or nurbs curves.")
			
			elif  len(mc.ls(s,tr=True))>0:
				
				sh=[]
				for c in \
				(
					mc.listRelatives(s,c=True,s=True,ni=True,type='nurbsCurve'),
					mc.listRelatives(s,c=True,s=True,ni=True,type='nurbsSurface'),
					mc.listRelatives(s,c=True,s=True,ni=True,type='mesh')
				):
					if isIterable(c) and len(c)>0: sh=c[0]				
				
				if isinstance(sh,basestring) and mc.objExists(sh):
					nt=mc.nodeType(sh)
					self.shapes.append(sh)
					self.trs.append(s)
					self.types.append(nt)
					if nt=='mesh': sha=s+'.outMesh'
					if nt=='nurbsSurface' or nt=='nurbsCurve': sha=s+'.local'
					self.shAttr.append(sha)
					
			elif mc.objExists(s):
								
				nt=mc.nodeType(s)
				
				if nt=='nurbsCurve' or nt=='nurbsSurface' or nt=='mesh':
					self.shapes.append(s)
					self.trs.append(mc.listRelatives(s,p=True)[0])
					self.types.append(nt)
					if nt=='mesh': sha=s+'.worldMesh[0]'
					if nt=='nurbsSurface' or nt=='nurbsCurve': sha=s+'.local'
					self.shAttr.append(sha)
					
				else:
					raise Exception("Arguments must be polygon meshes, nurbs surfaces, or nurbs curves.")
					
			else:
				raise Exception("Arguments must be polygon meshes, nurbs surfaces, or nurbs curves.")
							
			if nt=='mesh':
				self.knots.append({})
				density=len(mc.ls(sh+'.vtx[*]',fl=True))
			elif nt=='nurbsCurve':
				if not mc.objExists(ci): ci=mc.createNode('curveInfo')
				mc.connectAttr(sha,ci+'.ic',f=True)
				ku=[]
				kuq=removeDuplicates(mc.getAttr(ci+'.knots')[0])
				for u in kuq:
					if u>=0: ku.append(float(u))
					else: kuq.pop()
				k={'u':tuple(ku)}
				self.knots.append(k)
				density=len(k['u'])
			elif nt=='nurbsSurface':
				if not mc.objExists(si): si=mc.createNode('surfaceInfo')
				mc.connectAttr(sha,si+'.is',f=True)
				ku=[]
				kuq=removeDuplicates(mc.getAttr(ci+'.knotsU')[0])
				for u in kuq:
					if u>=0: ku.append(float(u))
					else: kuq.pop()
				kv=[]
				kvq=removeDuplicates(mc.getAttr(ci+'.knotsV')[0])
				for v in kvq:
					if v>=0: kv.append(float(v))
					else: kvq.pop()
				k={'u':tuple(ku),'v':tuple(kv)}
				self.knots.append(k)
				density=len(k['u'])*len(k['v'])
				
			self.uv.append([-1.0,-1.0])
			self.roughAPIDs.append([-1.0,-1.0])
			self.roughCPIDs.append([-1.0,-1.0])
							
			if density>maxDensity:
				maxDensity=density
				cpID=i
			else:
				searchID=i
			i+=1
			
		if self.types[searchID]=='mesh' and self.types[cpID]!='mesh':
			temp=cpID
			cpID=searchID
			searchID=temp
			
		if mc.objExists(ci): mc.delete(ci)
		if mc.objExists(si): mc.delete(si)
					
		self.lookup(cpID)