Ejemplo n.º 1
0
 	def duplicate_jointchain( self, *_tags, **kwargs ) :
 		# make a deep copy of self
		# loop through bones and replace rigjoint with a new one
		# loop through minorbones and replace minorbone with bone.duplicate	

		# we could duplicate the top joint and then compare with original to find the minorjoints
		# creating each joint individually seems to be more direct though

		try :
			_simple = kwargs[ '_simple' ]
		except :
			_simple = False

		dupjointchain = copy.deepcopy( self )
		dupjointchain.copymother = self
		lastrigjoint = None
		pm.select( None )
		for i, rigjoint in enumerate( dupjointchain.rigjoints ) :
			duprigjointname = utils.name_from_tags( rigjoint, *_tags )
			duprigjoint = rigjoint.duplicate( n=duprigjointname )[0]
			dupjointchain.rigjoints[i] = duprigjoint
			duprigjoint.setParent( lastrigjoint )
			lastrigjoint = duprigjoint

			# _simple copies only major rigjoints
			if( not _simple ) :
				dupjointchain.minorrigjoints[ duprigjoint ] = []
				# duplicate each minorrigjoint, add it to it's duplicated major rigjoint array of minor rigjoints				
				for minorrigjoint in dupjointchain.minorrigjoints[ rigjoint ] :
					dupminorrigjointname = utils.name_from_tags( minorrigjoint, *_tags )
					dupminorrigjoint = minorrigjoint.duplicate( n=dupminorrigjointname )[0]
					dupjointchain.minorrigjoints[ duprigjoint ].append( dupminorrigjoint)
					dupminorrigjoint.setParent( lastrigjoint )
					lastrigjoint = dupminorrigjoint
				# delete the original rigjoint entry in the dict
				del dupjointchain.minorrigjoints[ rigjoint ]
				
		self.duplicates.append( dupjointchain )
		
		# we'll reset the partname here in case the mother jointchain hs had its changed
		dupjointchain.PARTNAME = dupjointchain.__class__.PARTNAME
		return dupjointchain
Ejemplo n.º 2
0
	def create( self ) :
		# distribute the twist along the axis of each major joint
		# amongst the minor joints above it
		super( DistributedTwistAddin, self ).create()
		
		for relevantobject in self._relevant_objects_generator( self.jointchains ) :
			# create a multdiv to temper control's rotation by 1/len(minorjoints)
			multdiv = pm.nodetypes.MultiplyDivide( n=utils.name_from_tags( 
				relevantobject.rigjoint, 'rotateaddin', 'multiplydivide',
				_replacelast=False
			) )
			factor = 1.0 / ( len( relevantobject.minorrigjoints ) + 1 )
			multdiv.input2.set( [factor] * 3 )
			relevantobject.control.attr( self.attribute ) >> multdiv.attr( 'input1' + self.primaryaxis )

			# connect the multdiv to rigjoint and minorjoints
			for joint in [ relevantobject.rigjoint ] + relevantobject.minorrigjoints :
				multdiv.attr( 'output' + self.primaryaxis ) >> joint.attr( self.attribute )
Ejemplo n.º 3
0
	def _preCreateVirtual( cls, shape_type='default', **kwargs ) :
		if 'n' in kwargs :
			name = kwargs.pop( 'n' )
		elif 'name' in kwargs :
			name = kwargs.get( 'name' )
		else :
			name = cls.PARTNAME
		name = utils.name_from_tags( name, 'control', _replacelast=False )
		kwargs[ 'name' ] = name
		
		if 'st' in kwargs :
			shape_type = kwargs.pop( 'st' )
		elif 'shape_type' in kwargs :
			shape_type = kwargs.get( 'shape_type' )		

		kwargs[ 'shape_type' ] = shape_type

		pkwargs = {
			'shape_type' : shape_type
		}

		return kwargs, pkwargs
Ejemplo n.º 4
0
	def connect_rigs( self, _blendcontrol=None ) :

		# get the object the blend attr should be added to
		blendcontrol = _blendcontrol
		if( not blendcontrol ) :
			blendcontrolname = utils.name_from_tags( settings.staticcontrols[ 'ikfkblend' ], 'control' )
			blendcontrol = pm.PyNode( blendcontrolname )

		try :
			# create the blend attr
			blendattrname = utils.name_from_tags( self.tree_root().name, 'blend' )
			self.blendattr = utils.add_set_attr( blendcontrol, blendattrname, 0.0 )
		except :
			utils.err( 'Could not create blend attribute on %s' % ( blendcontrol ) )
			return False

		# blend between rigs onto blendjointchain

		jointchains = self.tree_children( 'jointchain' )
		if( len( jointchains ) != 1 ) :
			utils.err( '%s does not have ONE jointchain in it\'s children. Not sure which to use as the blend chain.' % ( self ) )
			return False
		blendjoints = jointchains[0].all_joints()
		rigs = self.tree_children( '.*Rig' )
		multdivdict = {}

		# set min/max values for blendattr
		self.blendattr.setMin( 0 )
		self.blendattr.setMax( len( self.tree_children( '.*Rig' ) ) - 1 )

		for i, rig in enumerate( rigs ) :	
			for jointchain in rig.tree_children( 'jointchain' ) :
				rigjoints = jointchain.all_joints()
				if( len( rigjoints ) != len( blendjoints ) ) :
					utils.wrn( '%s has a different number of joints to %s. Skipping...' % ( jointchain, jointchains[0] ) )
					continue

				# create a triangle curve with float time offset by j
				# by overlapping each triangle, n number of rigs can be blended
				# _/\____     
				# __/\___   this is how 3 rigs would blend together
				# ___/\__

				animcurve = pm.nodetypes.AnimCurveUL()
				animcurve.rename( utils.name_from_tags( self.tree_root().name, 'blend', rig.PARTNAME, 'animcurveUL' ) )

				offset = i
				pm.setKeyframe( animcurve, f=-1 + offset, v=0 )
				pm.setKeyframe( animcurve, f=0 	+ offset, v=1 )
				pm.setKeyframe( animcurve, f=1 	+ offset, v=0 )
				
				self.blendattr >> animcurve.input

				multdivdict[ rig ] = []

				for rigjoint in rigjoints :
					# vary input of joints rotation by animcurve output
					multdiv = pm.nodetypes.MultiplyDivide()
					multdiv.rename( utils.name_from_tags( rigjoint, 'blend', rig.PARTNAME, 'multiplydivide' ) )
					multdivdict[ rig ].append( multdiv )
					# connect animcurev and rotate to multdiv
					animcurve.output 	>> multdiv.input1X
					animcurve.output 	>> multdiv.input1Y
					animcurve.output 	>> multdiv.input1Z
					rigjoint.rotate		>> multdiv.input2

				for j, blendjoint in enumerate( blendjoints ) :
					# use a PMA node to blend between the rigs
					pma = pm.nodetypes.PlusMinusAverage()
					pma.rename( utils.name_from_tags( blendjoint, 'blend', rig.PARTNAME, 'plusminusaverage' ) )
					pma.operation.set( 1 )

					# connect everything up
					k = 0
					for rig, multdivlist in multdivdict.iteritems() :
						multdivlist[j].output >> pma.input3D[k]
						k += 1

					pma.output3D >> blendjoint.rotate
Ejemplo n.º 5
0
	def create( self, _jointchain=None ) :		
		super( SplineIkRig, self ).create( _jointchain )
		
		jointchain = self.tree_children( 'jointchain' )[0]

		# get start and end joints
		rigjoints = jointchain.rigjoints		
		
		# # create controls and store start/end controls/rigjoints
		controlsdriverslist = []
		for i, rigjoint in enumerate( [ rigjoints[0], rigjoints[-1] ] ) :		

			# create control
			control = RigControl( n=rigjoint.name() )
			control.setRotationOrder(
				utils.aim_axis_to_rotate_order( settings.rotationorder ),
				False
			)
			control.position_to_object( rigjoint )
			self.add_child( control )

			# create driver joint and store it with it's corresponding control
			driverrigjoint = rigjoint.duplicate(
				n=utils.name_from_tags( rigjoint, 'spline', 'driver' )
			)[0]
			self.add_child( driverrigjoint )
			controlsdriverslist.append( ( control, driverrigjoint ) )

		startjoint = jointchain.rigjoints[0]
		startdriver = controlsdriverslist[0][1]
		endjoint = jointchain.rigjoints[-1]
		enddriver = controlsdriverslist[-1][1]

		# create ik spline between them
		ikhandlename = utils.name_from_tags( startjoint, 'ikhandle' )
		ikhandle, ikeffector, ikcurve = pm.ikHandle( 
			startJoint=startjoint, 
			endEffector=endjoint,
			solver='ikSplineSolver',
			numSpans=len( jointchain.rigjoints ) - 1,
			name=ikhandlename
		)
		ikeffector.rename( utils.name_from_tags( endjoint, 'ikeffector' ) )
		ikcurve.rename( utils.name_from_tags( startjoint, 'curve' ) )
		self.add_child( ikhandle )
		self.add_child( ikcurve )

		# bind curve to driver joints
		tobind = [ ikcurve ] + [ i[1] for i in controlsdriverslist ]
		pm.skinCluster( 
			tobind,
			bindMethod=0,
			maximumInfluences=len( tobind ) - 1,
		)

		# set twist control
		ikhandle.dTwistControlEnable.set( True )
		ikhandle.dWorldUpType.set( 4 )
		startdriver.worldMatrix[0] >> ikhandle.dWorldUpMatrix
		enddriver.worldMatrix[0] >> ikhandle.dWorldUpMatrixEnd

		# parent drivers to controls
		for control, driver in controlsdriverslist :
			pm.parentConstraint(
				[ control, driver ],
				mo=False
			)
Ejemplo n.º 6
0
	def create( self, _jointchain=None ) :
		super( IkRig, self ).create( _jointchain )

		jointchains = self.tree_children( 'jointchain' )
		if( len( jointchains ) != 1 ) :
			utils.err( 'IkRig children includes more than ONE jointchain. Not sure which to use. Skipping...' )
			return False		

		jointchain = jointchains[0]

		# create a simple joint chain
		simplejointchain = jointchain.duplicate_jointchain( self.PARTNAME, 'driver', _simple=True )
		self.add_child( simplejointchain )
		
		pm.PyNode( 'leftUpperArm_1_IKJ_DRIVER' ).hide()
		pm.PyNode( 'leftUpperArm_1_j' ).hide()

		for i in range( len( simplejointchain.rigjoints ) - 1 ) :
			# create a curve between each pair of simple rigjoints
			rigjoint1 = simplejointchain.rigjoints[i]
			rigjoint2 = simplejointchain.rigjoints[i+1]

			v1 = pm.datatypes.Vector( rigjoint1.getTranslation( space='world' ) )
			v2 = pm.datatypes.Vector( rigjoint2.getTranslation( space='world' ) )
			curvelength = float( v1.distanceTo( v2 ) )

			dirvector = [ a * b for a, b in zip( 
				( curvelength, curvelength, curvelength ),
				utils.aim_axis_to_vectors( settings.rotationorder )[0]
			) ]

			curve = pm.curve( degree=1, point=[
				( 0, 0, 0 ),
				dirvector
				# v1, v2
			], name=utils.name_from_tags( rigjoint1, 'curve' ) )

			# rebuild with numspan 2 and 3 degree
			pm.rebuildCurve( curve, degree=3, spans=2 )

			# move vtx[1] and vtx[-2] to respective ends of curve		
			curve.cv[1].setPosition( curve.cv[0].getPosition( space='world' ), space='world' )
			curve.cv[-2].setPosition( curve.cv[-1].getPosition( space='world' ), space='world' )

			ribbonlength = 0.2

			ribbon = pm.extrude(
				curve,
				polygon=0,
				useProfileNormal=1,
				extrudeType=0,
				length=ribbonlength,
				ch=False,
				name=utils.name_from_tags( rigjoint1, 'nurbs' )
			)[0]

			ribbon.setTranslation( ( 0, 0, -(ribbonlength)/2 ) )
			ribbon.setPivots( ( 0, 0, 0 ), worldSpace=True )
			pm.makeIdentity( ribbon, apply=True )
			pm.delete( ribbon, ch=True )
			pm.delete( curve )

			utils.create_zero_sdk_groups( ribbon, _replacelast=False )

			startcluster = pm.cluster( 	ribbon.cv[0:1][0:1], name=utils.name_from_tags( rigjoint1, 'start', 'cluster') )[1]
			midcluster = pm.cluster( 	ribbon.cv[2][0:1], name=utils.name_from_tags( rigjoint1, 'mid', 'cluster' ) )[1]
			endcluster = pm.cluster( 	ribbon.cv[-2:][0:1], name=utils.name_from_tags( rigjoint1, 'end', 'cluster' ) )[1]

			# parent clusters to respective rigjoints
			pm.parentConstraint( [ rigjoint1, startcluster ], mo=False )
			pm.parentConstraint( [ rigjoint2, endcluster ], mo=False )

			# group then point/parent constrain middle cluster to end clusters
			sdkgroup, zerogroup = utils.create_zero_sdk_groups( midcluster, _replacelast=False )
			zerogroup.setRotation( rigjoint1.getRotation( space='world' ), space='world' )
			pm.pointConstraint( [ rigjoint1, rigjoint2, zerogroup ], mo=False )
			pm.orientConstraint( [ rigjoint1, zerogroup ], mo=False )

			jointsToAttachToCurve = [ jointchain.rigjoints[i] ]
			jointsToAttachToCurve += jointchain.minorrigjoints[ jointsToAttachToCurve[0] ]
			jointsToAttachToCurve += [ jointchain.rigjoints[i+1] ]

	
			for rigjoint in jointsToAttachToCurve :

				p = rigjoint.getTranslation( space='world' )
				posi = pm.nodetypes.ClosestPointOnSurface()
				ribbon.worldSpace >> posi.inputSurface
				posi.inPosition.set( p )
				u = min( max( posi.u.get(), 0.001 ), 0.999 )
				v = min( max( posi.v.get(), 0.001 ), 0.999 )

				pm.delete( posi )

				follicleshape = pm.nodetypes.Follicle()
				ribbon.local >> follicleshape.inputSurface
				ribbon.worldMatrix[0] >> follicleshape.inputWorldMatrix
				follicleshape.parameterU.set( u )
				follicleshape.parameterV.set( v )
				
				follicle = follicleshape.getParent()
				follicle.rename( utils.name_from_tags( rigjoint, 'follicle' ) )
				follicleshape.rename( follicle.name() + 'Shape' )

				follicleshape.outRotate >> follicle.rotate
				follicleshape.outTranslate >> follicle.translate

				# remove any constraints already on the joint
				pm.delete( rigjoint.getChildren( type='constraint' ) )

				pm.parentConstraint( [ follicle, rigjoint ], mo=True )
				

		return True