예제 #1
0
파일: arcCtrl.py 프로젝트: jonntd/zentools
	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
파일: arcCtrl.py 프로젝트: jonntd/zentools
	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()