Beispiel #1
0
def setupFkCtls(bndJnts, rigCtls, descriptions, namer):
    """Set up fk controls from bndJnts.

    This will delete the original controls passed in and
    rebuild the control shapes on a duplicate of the bind joints passed in
    Zero nodes will be placed above the controls, so the control matrices will
    equal identiy

    @param bndJnts: the joints to duplicate as fk controls
    @param rigCtls: the controls that will be deleted and have their shapes reparented
    @param descriptions: names for the new controls

    @param namer: a Namer object used to rename the new joints (const)

    @return: list of new joint controls
    """

    if len(bndJnts) != len(rigCtls):
        raise RuntimeError("bind joint length must match rig ctls")
    if len(bndJnts) != len(descriptions):
        raise RuntimeError("bind joint length must match rig descriptions")

    fkCtls = []
    rebuildData = getStorableXformRebuildData(inNodeList = bndJnts)

    substitutions = []
    for i in range(len(rigCtls)):
        #get the position offsets for the new control data
        setEditable(rigCtls[i], True)
        editor = getEditor(rigCtls[i])
        MC.parent(editor, world=1)
        utils.snap(bndJnts[i], rigCtls[i])
        MC.parent(editor, rigCtls[i])
        ctlInfo = getInfo(rigCtls[i])
        rebuildData[bndJnts[i]]['controlArgs'] = ctlInfo

        #get name substituions for the new joints
        newName = namer(descriptions[i], r='fk')
        substitutions.append((bndJnts[i], newName))

        fkCtls.append(newName)

    MC.delete(rigCtls)
    rebuildData = substituteInData(rebuildData, *substitutions)
    makeStorableXformsFromData(rebuildData)

    for ctl in fkCtls:

        att = utils.insertNodeAbove(ctl)
        for node in [ctl, att]:
            MC.setAttr('%s.drawStyle' % node, 2)
    return fkCtls
Beispiel #2
0
	def __init__(self, fitNode=None, rigNode=None):

		if fitNode is None and rigNode is None:
			raise Exception('No data specified.')

		elif fitNode is None:
			self.rigNode = rigNode
			# Put any attributes needed for initialized rigs here

		else:
			try:
				# Initialize rigNode
				# Error Check:
				
				# Convert string input to PyNode if neccessary
				if isinstance(fitNode, str):
					fitNode = ls(fitNode)[0]

				if fitNode.rigType.get() != 'bezierIK':
					raise Exception('Incorrect rig type: %s' % fitNode.rigType.get())

				self.crvs = []

				buildRig.rig.__init__(self, fitNode)



				# fitNode attributes
				doFK = False
				doOffsetFK = False # end joint orient failure
				doParametric = True
				doSplineIK = False
				# 
				doStretchLimit = False
				# 
				doVolume = False

				doStretchLimit = self.fitNode.stretchLimits.get()

				style = self.fitNode.style.get(asString=True)
				if style == 'FK Only':
					doSplineIK = False
					doParametric = False
				elif style == 'IK Only':
					doFK = False
					if doStretchLimit:
						doSplineIK = True
				elif style == 'IK to FK' or style == ' IK to FK':
					doFK = True
					doOffsetFK = True
					if doStretchLimit:
						doSplineIK = True
				else:
					doFK=True
					doSplineIK = True
					doParametric = True

				# if doFK:
				# 	raise Exception(style)


				if not all([doParametric, doSplineIK]):
					doStretchLimit = False
				if not doFK:
					doOffsetFK = False

				jointsList = 	self.fitNode.jointsList.get()
				numJoints = 	self.fitNode.resultPoints.get()+1
				pointInput = 	self.fitNode.outputJoints.inputs()[:self.fitNode.resultPoints.get()+2]

				fkShapes = 		self.fitNode.fkShapes.get()
				ikShapes = 		[self.fitNode.startShape.get(), self.fitNode.endShape.get()]

				tan1 =			self.fitNode.tangent1.get()
				tan2 =			self.fitNode.tangent2.get()

				orientation = self.fitNode.orientation.get(asString=True)

				bindEnd = False

				doBind = 		self.fitNode.bind.get()

				if not doBind:
					bindEnd = False


				# Mirroring
				if self.fitNode.side.get() == 2:
					mirror=True
				else:
					mirror=False

				if self.fitNode.mirror.get() is False:
					mirror=False

				# Move rigGroup
				xform(self.rigGroup, ws=1, m=xform(jointsList[0], q=1, ws=1, m=1))

				# Naming
				self.globalName = self.fitNode.globalName.get()
				self.subNames = []
				subAttrs = listAttr(self.fitNode, st='subName*')
				for subAttr in subAttrs:
					self.subNames.append(self.fitNode.attr(subAttr).get())

				# NAMING
				self.naming(0)
				self.names = utils.constructNames(self.namesDict)



				# ========================= RigNode Attributes =========================
				self.rigNode.rigType.set('bezier', l=1)

				
				utils.cbSep(self.rigNode)

				if doFK and not doOffsetFK:
					addAttr(self.rigNode, ct='publish', k=1, dv=0, min=0, max=1, ln='fkIk', nn='FK/IK')
					utils.cbSep(self.rigNode, ct='publish')
					addAttr(self.rigNode, ct='publish', ln='autoVis', nn='FK/IK Auto Vis', at='short', min=0, max=1, dv=1)
					setAttr(self.rigNode.autoVis, keyable=False, channelBox=True)
				if doFK:
					addAttr(self.rigNode, ct='publish', ln='fkVis', nn='FK Vis', at='short', min=0, max=1, dv=1)
					setAttr(self.rigNode.fkVis, keyable=False, channelBox=True)
				
				addAttr(self.rigNode, ct='publish', ln='ikVis', nn='IK Vis', at='short', min=0, max=1, dv=1)
				setAttr(self.rigNode.ikVis, keyable=False, channelBox=True)
				

			
				if doParametric or doSplineIK:
					addAttr(self.rigNode, ct='publish', ln='offsetCtrlsVis', at='short', min=0, max=1, dv=0, k=1)
					setAttr(self.rigNode.offsetCtrlsVis, keyable=False, channelBox=True)

				utils.cbSep(self.rigNode, ct='publish')
				# addAttr(self.rigNode, ln='bendCtrlsVis', nn='Bend Ctrl Vis', at='short', min=0, max=1, dv=1, k=1)
				# setAttr(self.rigNode.bendCtrlsVis, k=0, cb=1)

				addAttr(self.rigNode, ct='publish', ln='tangentCtrlsVis', min=0, max=1, dv=0, at='short', k=1)
				setAttr(self.rigNode.tangentCtrlsVis, k=0, cb=1)

				addAttr(self.rigNode, ln='tangentsDistanceScaling', softMinValue=0, softMaxValue=1, dv=0.5, k=1)
				
				# addAttr(self.rigNode, ln='neutralizeAll', min=0, max=1, dv=1, k=1)

				if doStretchLimit:
					utils.cbSep(self.rigNode, ct='publish')
					addAttr(self.rigNode, ct='publish', ln='stretch', softMinValue=0, softMaxValue=1, dv=1, k=1)
					addAttr(self.rigNode, ct='publish', ln='squash', softMinValue=0, softMaxValue=1, dv=1, k=1)
					addAttr(self.rigNode, ct='publish', ln='restLength', min=0.01, dv=1, k=1)
					# addAttr(self.rigNode, ln='currentNormalizedLength', dv=0)
					# self.rigNode.currentNormalizedLength.set(k=0, cb=1)
				if doVolume:
					utils.cbSep(self.rigNode, ct='publish')
					addAttr(self.rigNode, ct='publish', ln='volume', min=0, max=1, dv=0.5, keyable=True)
				
				if not hasAttr(self.rigNode, 'upAxis'):
					utils.cbSep(self.rigNode)
					addAttr(self.rigNode,ln='upAxis', at='enum', enumName='Y=1:Z=2', dv=1, k=1)

				# ========================= Vis Mults =========================
				# allVis Mults
				ikVisMult = createNode('multDoubleLinear', n=self.names.get('ikVisMult', 'rnm_ikVisMult'))
				self.rigNode.allVis >> ikVisMult.i1
				self.rigNode.ikVis >> ikVisMult.i2
				self.step(ikVisMult, 'ikVisMult')
				self.ikVis = ikVisMult.o

				if doFK:
					fkVisMult = createNode('multDoubleLinear', n=self.names.get('fkVisMult', 'rnm_fkVisMult'))
					self.rigNode.allVis >> fkVisMult.i1
					self.rigNode.fkVis >> fkVisMult.i2
					self.step(fkVisMult, 'fkVisMult')
					self.fkVis = fkVisMult.o

				debugVisMult = createNode('multDoubleLinear', n=self.names.get('debugVisMult', 'rnm_debugVisMult'))
				self.debugVis = debugVisMult.o
				self.rigNode.allVis >> debugVisMult.i1
				self.rigNode.debugVis >> debugVisMult.i2
				self.step(debugVisMult, 'debugVisMult')

				if doFK and not doOffsetFK:
					#=================== FK/IK Autovis Setup =========================
					self.sectionTag = 'fkIkAutoVis'

					fkIkAutoMult = createNode('multDoubleLinear', n=self.names.get('fkIkAutoMult', 'rnm_fkIkAutoMult'))
					self.rigNode.allVis >> fkIkAutoMult.i1
					self.rigNode.autoVis >> fkIkAutoMult.i2
					self.step(fkIkAutoMult, 'fkIkAutoMult')

					fkCond = createNode('condition', n=self.names.get('fkCond', 'rnm_fkCond'))
					fkCond.operation.set(4)
					fkCond.secondTerm.set(0.9)
					fkCond.colorIfTrue.set(1,1,1)
					fkCond.colorIfFalse.set(0,0,0)
					connectAttr(self.rigNode.fkIk, fkCond.firstTerm)
					self.step(fkCond, 'fkCond')

					ikCond = createNode('condition', n=self.names.get('ikCond', 'rnm_ikCond'))
					fkCond.operation.set(4)
					fkCond.secondTerm.set(0.9)
					fkCond.colorIfTrue.set(1,1,1)
					fkCond.colorIfFalse.set(0,0,0)
					connectAttr(self.rigNode.fkIk, ikCond.firstTerm)
					self.step(ikCond, 'ikCond')

					fkAutoCond = createNode('condition', n=self.names.get('fkAutoCond', 'rnm_fkAutoCond'))
					self.fkVis = fkAutoCond.outColorR
					fkAutoCond.operation.set(0)
					fkAutoCond.secondTerm.set(1)
					connectAttr(fkIkAutoMult.o, fkAutoCond.firstTerm)
					connectAttr(fkCond.outColorR, fkAutoCond.colorIfTrueR)
					connectAttr(fkVisMult.o, fkAutoCond.colorIfFalseR)
					connectAttr(fkVisMult.o, fkAutoCond.colorIfFalseG)
					self.step(fkAutoCond, 'fkAutoCond')

					ikAutoCond = createNode('condition', n=self.names.get('ikAutoCond', 'rnm_ikAutoCond'))
					self.ikVis = ikAutoCond.outColorR
					ikAutoCond.operation.set(0)
					ikAutoCond.secondTerm.set(1)
					connectAttr(fkIkAutoMult.o, ikAutoCond.firstTerm)
					connectAttr(ikCond.outColorR, ikAutoCond.colorIfTrueR)
					connectAttr(ikVisMult.o, ikAutoCond.colorIfFalseR)
					connectAttr(ikVisMult.o, ikAutoCond.colorIfFalseG)
					self.step(ikAutoCond, 'ikAutoCond')

				# ========================= World Group =========================
				worldGroup = createNode('transform', n=self.names.get('worldGroup', 'rnm_worldGroup'), p=self.rigGroup)
				self.worldGroup = worldGroup
				self.ikVis.connect(self.worldGroup.v)

				self.step(worldGroup, 'worldGroup')
				worldGroup.inheritsTransform.set(0)
				xform(worldGroup, rp=[0,0,0], ro=[0,0,0], ws=1)


				#=========================== FK Setup =================================
				# if doFK:
				# 	fkGroup = self.buildFkSetup(shapes=[fkShapes[0]], transforms=[jointsList[0]], mirror=mirror)
					# for fkCtrl in self.fkCtrls:
					# 	fkCtrl.message.connect(self.rigNode.fkCtrl)

				#==========================================================================
				#=========================== Bezier Setup =================================
				bezierTransforms = []
				if str(orientation) == 'world':
					for trans in range(2):
						bezierTransforms.append(createNode('transform', p=[jointsList[0], jointsList[-1]][trans]))
						xform(bezierTransforms[trans], ro=[0,0,0], ws=1)

				twistAxisChoice = 0 # Get from fitNode
				if self.fitNode.orientation.get(asString=1) == 'world':
					twistAxisChoice = self.fitNode.orientChoice.get() # Get from fitNode
				
				bezierRigGroup = self.buildBezierSetup(
					transforms=[jointsList[0], jointsList[-1]],
					ctrlTransforms=bezierTransforms if bezierTransforms else None,
					defaultTangents=[[None, tan1], [tan2, None]],
					shapes=ikShapes,
					follow=False,
					twist=True,
					bias=False,
					twistAxisChoice=twistAxisChoice,
					mirror=mirror,
					# doStrength=True
					)
				self.ikVis.connect(bezierRigGroup.v)
				bezierRigGroup.controlsVis.set(1)

				if str(orientation) == 'world':
					delete(bezierTransforms)
				
				# Chest orientation
				endOriCtrlSS = buildRig.spaceSwitch(
					constraintType='orient',
					controller = self.bendCtrls[1],
					constrained= self.bendCtrls[1].const.get(),
					prefix = self.names.get('endOriCtrlSS', 'rnm_endOriCtrlSS'),
					p=self.rigGroup,
					# p=self.ssGroup,
					targets=[self.rigsGroup, self.bendCtrls[1].buf.get()],
					labels=['World', 'Parent'],
					offsets=True,
					)
				endOriCtrlSS.setDefaultBlend(1)


				self.rigNode.tangentsDistanceScaling.connect(bezierRigGroup.tangentsDistanceScaling)
				# if doFK:
				# 	self.matrixConstraint(self.fkCtrls[-1], bezierRigGroup, r=1, s=1)

				displaySmoothness(self.crvs[0], pointsWire=16)
				
				if doParametric:
					# Motion path groups
					crvPathRig = self.buildCurvePartitionsSetup(
						self.crvs[0], 
						nameVars='0',
						partitionParams=[0, 1],
						numJointsList=[numJoints],
						mirror=mirror,
						createOffsetControls=(False if doStretchLimit else True),
						rotationStyle=(None if doStretchLimit else 'aim'),
						twist=(False if doStretchLimit else True),
						bindEnd=True
					)
					results = crvPathRig.results.get()


				if doSplineIK:
					ikSplineRig = self.buildIKSplineSetup(
						crv=self.crvs[0], 
						points=pointInput, 
						mirror=mirror, 
						selectionPriority=2,
					)
					results = ikSplineRig.results.get()

				

				# # =========================== Twist ===========================
				# #### Bend ctrls
				if doParametric and not doStretchLimit:
					self.bendCtrls[0].twist.connect(				self.twistAdds[0].input2D[0].getChildren()[0])
					self.socket(self.bendCtrls[0]).twist.connect(	self.twistAdds[0].input2D[1].getChildren()[0])

					self.bendCtrls[1].twist.connect(				self.twistAdds[0].input2D[0].getChildren()[1])
					self.socket(self.bendCtrls[1]).twist.connect(	self.twistAdds[0].input2D[1].getChildren()[1])

				if doSplineIK:
					self.bendCtrls[0].twist.connect(				self.twistAdds[0].input2D[0].getChildren()[0])
					self.socket(self.bendCtrls[0]).twist.connect(	self.twistAdds[0].input2D[1].getChildren()[0])

					self.bendCtrls[1].twist.connect(				self.twistAdds[0].input2D[0].getChildren()[1])
					self.socket(self.bendCtrls[1]).twist.connect(	self.twistAdds[0].input2D[1].getChildren()[1])


				# Squash and stretch limits
				if doStretchLimit:

					staticLocatorsGroup = createNode('transform', n=self.names.get('staticLocatorsGroup', 'rnm_staticLocatorsGroup'), p=ikSplineRig)
					self.step(staticLocatorsGroup, 'staticLocatorsGroup')

					bezLocs = []
					staticBezLocs = []
					i=0
					print '\n'
					print crvPathRig.results.get()
					print ikSplineRig.results.get()
					
					for bezPoint, ikJnt in zip(crvPathRig.results.get(), ikSplineRig.results.get()):
						
						# if i==4:
						# 	raise Exception('4')

						bezLoc2 = createNode('locator', n='%s_dist_LOC' % bezPoint, p=bezPoint)
						self.step(bezLoc2, 'bezLoc')
						bezLoc2.hide()
						bezLocs.append(bezLoc2)

						# 

						staticBezPoint = createNode('transform', n=self.names.get('staticBezPoint', 'rnm_staticBezPoint'), p=staticLocatorsGroup)
						self.step(staticBezPoint, 'staticBezPoint')
						utils.snap(bezPoint, staticBezPoint)

						staticBezLoc2 = createNode('locator', n='%s_dist_LOC' % staticBezPoint, p=staticBezPoint)
						self.step(staticBezLoc2, 'staticBezLoc')
						staticBezLoc2.hide()
						staticBezLocs.append(staticBezLoc2)

						if not i==0: # Skip 0
							# Distance
							bezLoc1 = bezLocs[i-1]
							staticBezLoc1 = staticBezLocs[i-1]

							bezDist = createNode('distanceBetween', n=self.names.get('bezDist', 'rnm_bezDist'))
							self.step(bezDist, 'bezDist')

							bezLoc1.worldPosition.connect(bezDist.point1)
							bezLoc2.worldPosition.connect(bezDist.point2)

							# Static distance
							staticBezDist = createNode('distanceBetween', n=self.names.get('staticBezDist', 'rnm_staticBezDist'))
							self.step(staticBezDist, 'staticBezDist')

							staticBezLoc1.worldPosition.connect(staticBezDist.point1)
							staticBezLoc2.worldPosition.connect(staticBezDist.point2)

							# # Mult static by rig input
							staticBezDistMult = createNode('multDoubleLinear', n=self.names.get('staticBezDistMult', 'rnm_staticBezDistMult'))
							self.step(staticBezDistMult, 'staticBezDistMult')
							staticBezDist.distance.connect(staticBezDistMult.i1)
							self.rigNode.restLength.connect(staticBezDistMult.i2)

							# Normalize
							normalizeDiv = createNode('multiplyDivide', n=self.names.get('normalizeDiv', 'rnm_normalizeDiv'))
							self.step(normalizeDiv, 'normalizeDiv')
							normalizeDiv.operation.set(2)

							bezDist.distance.connect(normalizeDiv.input1X)
							staticBezDistMult.output.connect(normalizeDiv.input2X)



							# Stretch
							stretchBlend = createNode( 'blendTwoAttr', n=self.names.get('stretchBlend', 'rnm_stretchBlend') )
							self.step(stretchBlend, 'stretchBlend')
							stretchBlend.i[0].set(1)
							normalizeDiv.outputX.connect(stretchBlend.i[1])
							self.rigNode.stretch.connect(stretchBlend.ab)


							# Squash
							squashBlend = createNode( 'blendTwoAttr', n=self.names.get('squashBlend', 'rnm_squashBlend') )
							self.step(squashBlend, 'squashBlend')
							squashBlend.i[0].set(1)
							normalizeDiv.outputX.connect(squashBlend.i[1])
							self.rigNode.squash.connect(squashBlend.ab)

	
							# Squash/Stretch combiner
							squashStretchCond = createNode( 'condition', n=self.names.get('stretchBlend', 'rnm_stretchBlend') )
							self.step(squashStretchCond, 'squashStretchCond')
							squashStretchCond.operation.set(2) # Greater Than
							normalizeDiv.outputX.connect(squashStretchCond.firstTerm)

							squashStretchCond.secondTerm.set(1)

							stretchBlend.o.connect(squashStretchCond.colorIfTrueR)
							squashBlend.o.connect(squashStretchCond.colorIfFalseR)


							restLengthMult = createNode('multDoubleLinear', n=self.names.get('restLengthMult', 'rnm_restLengthMult'))
							self.step(restLengthMult, 'restLengthMult')
							squashStretchCond.outColorR.connect(restLengthMult.i1)
							self.rigNode.restLength.connect(restLengthMult.i2)


							denormalizeMult = createNode('multDoubleLinear', n=self.names.get('denormalizeMult', 'rnm_denormalizeMult'))
							self.step(denormalizeMult, 'denormalizeMult')
							denormalizeMult.i1.set(bezDist.distance.get())
							restLengthMult.o.connect(denormalizeMult.i2)
							

							denormalizeMult.o.connect(ikJnt.tx)

							

						i=i+1

					results = ikSplineRig.results.get()


				if doFK:

					fkGroup = self.buildFkSetup(shapes=fkShapes, transforms=results, mirror=mirror)
					self.fkVis.connect(fkGroup.v)

					# FK Offset Option
					if doOffsetFK:
						boneIndic = utils.boneIndic(self.fkCtrls[-1], results[-1], blackGrey=1)[0]
						self.debugVis.connect(boneIndic.v)


						# Create an external result chain with edits (for bend control)
						# Regular ik spline won't allow changes to orientation within heirarchy, but heirarchy still needs to be preserved to allow
						# edits to fk offset controls (no constraints)
						splineHierarchy = []
						for i, point in enumerate(results):
							self.naming(n=i)
							self.names = utils.constructNames(self.namesDict)

							splineRetarget = createNode( 'transform', n=self.names.get('splineRetarget', 'rnm_splineRetarget'), p=splineHierarchy[i-1] if i else ikSplineRig )
							print splineRetarget
							self.step(splineRetarget, 'splineRetarget')
							splineHierarchy.append(splineRetarget)

							if i==0:
								self.matrixConstraint(point, splineRetarget, t=1, s=1, offset=False)
								self.matrixConstraint(self.bendCtrls[0], splineRetarget, t=0, r=1, offset=False)
								splineRetarget.t.connect(self.fkCtrls[i].buf.get().t)
								splineRetarget.r.connect(self.fkCtrls[i].buf.get().r)
								splineRetarget.s.connect(self.fkCtrls[i].buf.get().s)


							elif point == results[-1] :
								self.matrixConstraint(point, splineRetarget, t=1, s=1, offset=False)
								self.matrixConstraint(self.bendCtrls[-1], splineRetarget, t=0, r=1, offset=False)
								# endSS = buildRig.simpleSpaceSwitch(
								# 	constraintType='orient',
								# 	controller=self.fkCtrls[i],
								# 	constrained=self.fkCtrls[i],
								# 	prefix = self.names.get('endSS', 'rnm_endSS'),
								# 	targets=[point, self.bendCtrls[-1]],
								# 	labels=['Default', 'IK'],
								# 	offsets=True,
								# )
								splineRetarget.t.connect(self.fkCtrls[i].buf.get().t)
								splineRetarget.r.connect(self.fkCtrls[i].buf.get().r)
								splineRetarget.s.connect(self.fkCtrls[i].buf.get().s)
							else:
								self.matrixConstraint(point, splineRetarget, t=1, r=1, s=1, offset=False)


								# FK chain driven by IK rig
								splineRetarget.t.connect(self.fkCtrls[i].buf.get().t)
								splineRetarget.r.connect(self.fkCtrls[i].buf.get().r)
								splineRetarget.s.connect(self.fkCtrls[i].buf.get().s)

						results = self.fkCtrls



					# FK/IK Switch Option
					else:
						fkIkGroup =  createNode('transform', n=self.names.get('fkIkGroup', 'rnm_fkIkGroup'), p=self.rigGroup)
						self.step(fkIkGroup, 'fkIkGroup')
					
						switchGroup = createNode('transform', n=self.names.get('switchGroup','rnm_switchGroup'), p=fkIkGroup)
						self.step(switchGroup, 'switchGroup')
						self.publishList.append(switchGroup)
						# ENTRANCE
						fkEntrance = createNode('transform', n=self.names.get('fkEntrance', 'rnm_fkEntrance'), p=fkIkGroup)
						self.step(fkEntrance, 'fkEntrance')
						utils.snap(self.fkCtrls[0], fkEntrance)
						self.matrixConstraint(self.fkCtrls[0], fkEntrance, t=1, r=0, s=0)

						ikEntrance = createNode('transform', n=self.names.get('ikEntrance', 'rnm_ikEntrance'), p=fkIkGroup)
						self.step(ikEntrance, 'ikEntrance')
						utils.snap(results[0], ikEntrance)
						self.matrixConstraint(results[0], ikEntrance, t=1, r=0, s=0)
						self.matrixConstraint(self.bendCtrls[0], ikEntrance, t=0, r=1, s=1, offset=True)

						rigEntrance = createNode('transform', n=self.names.get('rigEntrance', 'rnm_rigEntrance'), p=fkIkGroup)
						self.step(rigEntrance, 'rigEntrance')
						utils.snap(results[0], rigEntrance)

						rigEntranceScaleBlend = createNode('blendColors', n=self.names.get('rigEntranceScaleBlend', 'rnm_rigEntranceScaleBlend'))
						self.step(rigEntranceScaleBlend, 'rigEntranceScaleBlend')
						fkEntrance.scale.connect(rigEntranceScaleBlend.color1)
						ikEntrance.scale.connect(rigEntranceScaleBlend.color2)
						self.rigNode.fkIk.connect(rigEntranceScaleBlend.blender)
						rigEntranceScaleBlend.output.connect(rigEntrance.scale)
						
						fkIkStartSS = buildRig.simpleSpaceSwitch(
							constraintType='parent',
							constrained= rigEntrance,
							prefix = self.names.get('fkIkStartSS', 'rnm_fkIkStartSS'),
							targets=[fkEntrance, ikEntrance],
							labels=['FK', 'IK'],
							offsets=True,
						)
						self.rigNode.fkIk.connect(fkIkStartSS.blendAttr)

						self.matrixConstraint(ikEntrance, rigEntrance, t=0, r=0, s=1)

						# EXIT
						fkExit = createNode('transform', n=self.names.get('fkExit', 'rnm_fkExit'), p=fkIkGroup)
						self.step(fkExit, 'fkExit')
						utils.snap(self.fkCtrls[-1], fkExit)
						self.matrixConstraint(self.fkCtrls[-1], fkExit, t=1, r=1, s=0)

						ikExit = createNode('transform', n=self.names.get('ikExit', 'rnm_ikExit'), p=fkIkGroup)
						self.step(ikExit, 'ikExit')
						utils.snap(results[-1], ikExit)
						self.matrixConstraint(results[-1], ikExit, t=1, r=0, s=0)
						self.matrixConstraint(self.bendCtrls[-1], ikExit, t=0, r=1, s=1, offset=True)

						rigExit = createNode('transform', n=self.names.get('rigExit', 'rnm_rigExit'), p=fkIkGroup)
						self.step(rigExit, 'rigExit')
						utils.snap(results[0], rigExit)

						fkIkEndSS = buildRig.simpleSpaceSwitch(
							constraintType='parent',
							constrained= rigExit,
							prefix = self.names.get('fkIkEndSS', 'rnm_fkIkEndSS'),
							targets=[fkExit, ikExit],
							labels=['FK', 'IK'],
							offsets=True,
						)
						self.rigNode.fkIk.connect(fkIkEndSS.blendAttr)


						rigExitScaleBlend = createNode('blendColors', n=self.names.get('rigExitScaleBlend', 'rnm_rigExitScaleBlend'))
						self.step(rigExitScaleBlend, 'rigExitScaleBlend')
						fkExit.scale.connect(rigExitScaleBlend.color1)
						ikExit.scale.connect(rigExitScaleBlend.color2)
						self.rigNode.fkIk.connect(rigExitScaleBlend.blender)
						rigExitScaleBlend.output.connect(rigExit.scale)


						# Points
						switches = []
						for i, point in enumerate(results):
							self.naming(n=i)
							self.names = utils.constructNames(self.namesDict)
							# result transforms
							switch = createNode('transform', n=self.names.get('switch', 'rnm_switch'), p=switchGroup)
							utils.snap(point, switch)
							self.step(switch, 'switch')
							switches.append(switch)

							fkIkSwitchSS = buildRig.simpleSpaceSwitch(
								constrained= switch,
								controller=self.rigNode.fkIk,
								targets=[self.fkCtrls[i], results[i]],
								labels=['FK', 'IK'],
								prefix = self.names.get('fkIkSwitchSS', 'rnm_fkIkSwitchSS'),
								constraintType='parent',
								offsets=True,
							)
							# self.rigNode.fkIk.connect(fkIkSwitchSS.rigNode.parentSpaceBlend)
				

					offsetResults = []
					# Offset controls
					for i, point in enumerate(results):
						ctrlParent = None
						if doOffsetFK:
							ctrlParent = self.fkCtrls[i]
						else:
							ctrlParent = offsetResults[i-1] if i else switchGroup

						self.naming(n=i)
						self.names = utils.constructNames(self.namesDict)
						par = self.fkCtrls[i] if doOffsetFK else switches[i]
						offsetCtrl = self.createControlHeirarchy(
							name=self.names.get('offsetCtrl', 'rnm_offsetCtrl'), 
							transformSnap=self.fkCtrls[i],
							selectionPriority=2,
							ctrlParent=ctrlParent,
							outlinerColor = (0,0,0),
							par=par)

						offsetResults.append(offsetCtrl)
						self.rigNode.offsetCtrlsVis.connect(offsetCtrl.buf.get().v)

					results = offsetResults



				results = self.buildScaleLengthSetup(scaleInputs=self.bendCtrls, distanceInputs=[results[0], results[1]], nodes=results, settingsNode=self.rigNode)

				rigEntranceBuf = createNode('transform', n=self.names.get('rigEntranceBuf', 'rnm_rigEntranceBuf'), p=self.rigGroup)
				self.step(rigEntranceBuf, 'rigEntranceBuf')
				utils.snap(results[0], rigEntranceBuf)
				# if style == 'IK Only' or style == 'IK to FK':
				if style == 'IK Only':
					self.matrixConstraint(self.bendCtrls[0], rigEntranceBuf, t=0, r=1, s=0, offset=False)
					self.matrixConstraint(results[0].getParent(), rigEntranceBuf, t=1, r=0, s=1, offset=False)
				else:
					self.matrixConstraint(results[0].getParent(), rigEntranceBuf, t=1, r=1, s=1, offset=False)

				rigEntrance = createNode('transform', n=self.names.get('rigEntrance', 'rnm_rigEntrance'), p=rigEntranceBuf)
				self.step(rigEntrance, 'rigEntrance')
				self.bendCtrls[0].twist.connect(rigEntrance.rx)

				rigExitBuf = createNode('transform', n=self.names.get('rigExitBuf', 'rnm_rigExitBuf'), p=self.rigGroup)
				self.step(rigExitBuf, 'rigExitBuf')
				utils.snap(results[0], rigExitBuf)

				if style == 'IK Only':
					self.matrixConstraint(self.bendCtrls[-1], rigExitBuf, t=0, r=1, s=0, offset=False)
					self.matrixConstraint(results[-1].getParent(), rigExitBuf, t=1, r=0, s=1, offset=False)
				else:
					self.matrixConstraint(results[-1].getParent(), rigExitBuf, t=1, r=1, s=1, offset=False)

				rigExit = createNode('transform', n=self.names.get('rigExit', 'rnm_rigExit'), p=rigExitBuf)
				self.step(rigExit, 'rigExit')
				self.bendCtrls[-1].twist.connect(rigExit.rx)

				results.insert(0, rigEntrance)
				results.append(rigExit)

				# results = []
				print 'Results:'
				print results
				for i, point in enumerate(results):

					self.naming(n=i)
					self.names = utils.constructNames(self.namesDict)


					if mirror:
						point = self.socket(point)
					# 	ctrl.rotateY.set(-180)
					# 	ctrl.scaleX.set(-1)

					point.message.connect(self.rigNode.socketList, na=1)
					# self.socketList.append(point)
					if doBind:
						bind = createNode('joint', n=self.names.get('bind', 'rnm_bind'), p=point)
						self.bindList.append(bind)
						self.step(bind, 'bind')
						bind.hide()

				# rigExit = createNode('transform', n=self.names.get('rigExit', 'rnm_rigExit'), p=self.rigGroup)
				# self.step(rigExit, 'rigExit')
				# self.socket(rigExit).message.connect(self.rigNode.socketList, na=1)
				# utils.snap(point, rigExit)
				# self.matrixConstraint(point, rigExit, t=1, r=1, s=1, offset=True)

				# if bindEnd:
				# 	# # rig exit bind
				# 	rigExitBind = createNode( 'joint', n=self.names.get( 'rigExitBind', 'rnm_rigExitBind'), p=rigExit )
				# 	self.step(rigExitBind, 'rigExitBind')
				# 	self.bindList.append(rigExitBind)
				# 	rigExitBind.hide()


				#=========================== Finalize =================================

			except:
				raise

			finally:
				# try:
				# 	for bendCtrl in self.bendCtrls:
				# 		attrs = bendCtrl.s.getChildren()
				# 		for a in attrs:
				# 			a.set(l=1, k=0)
				# except:
				# 	pass
				# try:
				# 	self.setController(fkGroup, self.rigGroup)
				# 	self.setController(bezierRigGroup, self.rigGroup)
				# except:
				# 	pass
				try:
					self.constructSelectionList(selectionName='bendCtrls', selectionList=self.bendCtrls)
					self.constructSelectionList(selectionName='tangentCtrls', selectionList=self.tangentCtrls)
					self.constructSelectionList(selectionName='offsetCtrls', selectionList=self.offsetCtrls)
					self.constructSelectionList(selectionName='frozenNodes', selectionList=self.freezeList)
				except:
					pass

				self.finalize()
Beispiel #3
0
    def __init__(self, fitNode=None, rigNode=None):

        if fitNode is None and rigNode is None:
            raise Exception('No data specified.')

        elif fitNode is None:
            self.rigNode = rigNode
            # Put any attributes needed for initialized rigs here

        else:
            try:
                jointsList = fitNode.jointsList.get()
                # Initialize rigNode
                # Error Check:

                # Convert string input to PyNode if neccessary
                if isinstance(fitNode, str):
                    fitNode = ls(fitNode)[0]

                if fitNode.rigType.get() != 'aimIK':
                    raise Exception('Incorrect rig type: %s' %
                                    fitNode.rigType.get())

                if fitNode.hasAttr('inbetweenJoints'):
                    inbetweenJoints = fitNode.inbetweenJoints.get()
                else:
                    inbetweenJoints = 0

                self.crvs = []

                buildRig.rig.__init__(self, fitNode)

                jointsList = fitNode.jointsList.get()
                orientControlsList = [
                    fitNode.startOriCtrl.get(),
                    fitNode.endOriCtrl.get()
                ]
                # Move rigGroup
                xform(self.rigGroup,
                      ws=1,
                      m=xform(jointsList[0], q=1, ws=1, m=1))
                # fitNode attributes

                bindEnd = self.fitNode.bindEnd.get()
                doFK = self.fitNode.fkEnable.get()
                ikEndInherit = self.fitNode.ikEndInherit.get()
                doStretch = self.fitNode.doStretch.get()
                doTwist = self.fitNode.doTwist.get()
                doVolume = self.fitNode.doVolume.get()
                doScaling = self.fitNode.doScaling.get()
                twistAxis = 0

                if doFK:
                    fkShape = (self.fitNode.fkShape.get()
                               if self.fitNode.fkVis.get() else None)
                else:
                    fkShape = None

                ikShapes = [(self.fitNode.startShape.get()
                             if self.fitNode.ikVisStart.get() else None),
                            self.fitNode.endShape.get()
                            if self.fitNode.ikVisEnd.get() else None]

                doIkStartCtrl = self.fitNode.ikVisStart.get()
                doIkEndCtrl = self.fitNode.ikVisEnd.get()

                twistAxisChoice = 0
                # up = None:
                up = self.fitNode.up.get()

                # Mirroring
                if self.fitNode.side.get() == 2:
                    mirror = True
                else:
                    mirror = False

                # Naming
                self.globalName = self.fitNode.globalName.get()
                self.subNames = []
                subAttrs = listAttr(self.fitNode, st='subName*')
                for subAttr in subAttrs:
                    self.subNames.append(self.fitNode.attr(subAttr).get())
                # print 'subnames:'
                # print self.subNames

                self.naming()
                self.names = utils.constructNames(self.namesDict)
                # ========================= RigNode Attributes =========================
                self.rigNode.rigType.set('aimIK', l=1)

                utils.cbSep(self.rigNode)
                if doFK:
                    addAttr(self.rigNode,
                            ct='publish',
                            ln='fkVis',
                            nn='FK Vis',
                            at='short',
                            min=0,
                            max=1,
                            dv=1)
                    setAttr(self.rigNode.fkVis, keyable=False, channelBox=True)

                addAttr(self.rigNode,
                        ct='publish',
                        ln='ikVis',
                        nn='IK Vis',
                        at='short',
                        min=0,
                        max=1,
                        dv=1)
                setAttr(self.rigNode.ikVis, keyable=False, channelBox=True)

                addAttr(self.rigNode,
                        ct='publish',
                        ln='offsetCtrlsVis',
                        min=0,
                        max=1,
                        dv=0,
                        keyable=1)
                self.rigNode.offsetCtrlsVis.set(k=0, cb=1)

                if doStretch:
                    addAttr(self.rigNode,
                            ct='publish',
                            ln='squash',
                            min=0,
                            max=1,
                            dv=1,
                            keyable=1)
                    addAttr(self.rigNode,
                            ct='publish',
                            ln='stretch',
                            min=0,
                            max=1,
                            dv=1,
                            keyable=1)

                    utils.cbSep(self.rigNode, ct='publish')
                    addAttr(self.rigNode,
                            ct='publish',
                            ln='restLength',
                            min=0.01,
                            dv=1,
                            keyable=1)
                    addAttr(self.rigNode,
                            ct='publish',
                            ln='currentNormalizedLength',
                            min=0,
                            dv=1,
                            keyable=1)

                utils.cbSep(self.rigNode, ct='publish')
                addAttr(self.rigNode,
                        ln='upAxis',
                        at='enum',
                        enumName='Y=1:Z=2',
                        dv=2,
                        k=1)

                addAttr(self.rigNode,
                        ln='iKCtrlStart',
                        nn='IK Ctrl Start',
                        at='message')
                addAttr(self.rigNode,
                        ln='iKCtrlEnd',
                        nn='IK Ctrl End',
                        at='message')
                addAttr(self.rigNode,
                        ln='fkCtrl',
                        nn='FK Ctrl Start',
                        at='message')

                # ========================= Vis Mults =========================
                # allVis Mults
                if doFK:
                    fkVisMult = createNode('multDoubleLinear',
                                           n=self.names.get(
                                               'fkVisMult', 'rnm_fkVisMult'))
                    self.rigNode.allVis >> fkVisMult.i1
                    self.rigNode.fkVis >> fkVisMult.i2
                    self.step(fkVisMult, 'fkVisMult')
                    self.fkVis = fkVisMult.o

                ikVisMult = createNode('multDoubleLinear',
                                       n=self.names.get(
                                           'ikVisMult', 'rnm_ikVisMult'))
                self.rigNode.allVis >> ikVisMult.i1
                self.rigNode.ikVis >> ikVisMult.i2
                self.step(ikVisMult, 'ikVisMult')
                self.ikVis = ikVisMult.o

                # offsetVisMult = createNode('multDoubleLinear', n=self.names.get('offsetVisMult', 'rnm_offsetVisMult'))
                # self.rigNode.allVis >> offsetVisMult.i1
                # self.rigNode.ikVis >> offsetVisMult.i2
                # self.step(offsetVisMult, 'offsetVisMult')
                # self.offsetVis = offsetVisMult.o

                debugVisMult = createNode('multDoubleLinear',
                                          n=self.names.get(
                                              'debugVisMult',
                                              'rnm_debugVisMult'))
                self.debugVis = debugVisMult.o
                self.rigNode.allVis >> debugVisMult.i1
                self.rigNode.debugVis >> debugVisMult.i2
                self.step(debugVisMult, 'debugVisMult')

                # ========================= World Group =========================
                # worldGroup = createNode('transform', n=self.names.get('worldGroup', 'rnm_worldGroup'), p=self.rigGroup)
                # self.worldGroup = worldGroup
                # self.step(worldGroup, 'worldGroup')
                # worldGroup.inheritsTransform.set(0)
                # xform(worldGroup, rp=[0,0,0], ro=[0,0,0], ws=1)
                #

                self.ssGroup = createNode('transform',
                                          n=self.names.get(
                                              'ssGroup', 'rnm_ssGroup'),
                                          p=self.rigGroup)
                self.step(self.ssGroup, 'ssGroup')

                # =========================== FK Setup =================================

                if doFK:
                    fkGroup = self.buildFkSetup(shapes=[fkShape],
                                                transforms=[jointsList[0]],
                                                mirror=mirror)
                    self.fkVis.connect(fkGroup.v)
                    for fkCtrl in self.fkCtrls:

                        if self.dev:
                            print '\n\n'
                            print '%s' % self.rigsGroup
                            print '%s' % fkCtrl.buf.get()
                        fkCtrl.message.connect(self.rigNode.fkCtrl)
                        fkOriCtrlSS = buildRig.spaceSwitch(
                            constraintType='orient',
                            controller=fkCtrl,
                            constrained=fkCtrl.const.get(),
                            prefix=self.names.get('fkOriCtrlSS',
                                                  'rnm_fkOriCtrlSS'),
                            # p=self.rigGroup,
                            p=self.ssGroup,
                            targets=[self.rigsGroup,
                                     fkCtrl.buf.get()],
                            labels=['World', 'Parent'],
                            offsets=True,
                        )
                        fkOriCtrlSS.setDefaultBlend(1)

                # =========================== Aim Ik Setup =================================

                aimIKGroup = self.buildAimIkSetup(
                    source=orientControlsList[0],
                    dest=orientControlsList[1],
                    worldUpLocation=up,
                    inbetweenJoints=inbetweenJoints,
                    controller=self.rigNode,
                    sourceShape=ikShapes[0],
                    destShape=ikShapes[1],
                    registerControls=[bool(doIkStartCtrl),
                                      bool(doIkEndCtrl)],
                    stretch=doStretch,
                    twist=doTwist,
                    volume=doVolume,
                    scaling=doScaling,
                    twistAxisChoice=twistAxisChoice)
                self.ikVis.connect(aimIKGroup.v)

                aimIKGroup.results.get()[0].message.connect(
                    self.rigNode.socketList, na=1)
                aimIKGroup.results.get()[1].message.connect(
                    self.rigNode.socketList, na=1)

                # if doIkStartCtrl:
                # 	startOriCtrlSS = buildRig.spaceSwitch(
                # 		constraintType='orient',
                # 		controller = self.aimCtrls[0],
                # 		constrained= self.aimCtrls[0].const.get(),
                # 		prefix = self.names.get('startOriCtrlSS', 'rnm_startOriCtrlSS'),
                # 		p=self.ssGroup,
                # 		targets=[self.rigsGroup, self.aimCtrls[0].buf.get()],
                # 		labels=['World', 'Parent'],
                # 		offsets=True,
                # 	)
                # 	startOriCtrlSS.setDefaultBlend(1)

                # if doIkEndCtrl:
                # 	endOriCtrlSS = buildRig.spaceSwitch(
                # 		constraintType='orient',
                # 		controller = self.aimCtrls[1],
                # 		constrained= self.aimCtrls[1].const.get(),
                # 		prefix = self.names.get('endOriCtrlSS', 'rnm_endOriCtrlSS'),
                # 		p=self.ssGroup,
                # 		# p=self.ssGroup,
                # 		targets=[self.rigsGroup, self.aimCtrls[1].buf.get()],
                # 		labels=['World', 'Parent'],
                # 		offsets=True,
                # 	)
                # 	endOriCtrlSS.setDefaultBlend(1)

                self.aimCtrls[0].message.connect(self.rigNode.iKCtrlStart)
                self.aimCtrls[1].message.connect(self.rigNode.iKCtrlEnd)

                if doFK:
                    self.matrixConstraint(self.socket(fkCtrl),
                                          aimIKGroup,
                                          r=1,
                                          s=1,
                                          offset=False)

                for i, trans in enumerate(aimIKGroup.results.get()):
                    # If end is not being bound, skip last
                    if not bindEnd:
                        if trans is aimIKGroup.results.get()[-1]:
                            break

                    # Create a bind joint for each result transform (special naming for midJoints)
                    if inbetweenJoints:
                        n = i
                    else:
                        n = 0
                    self.naming(i=i, n=n)
                    self.names = utils.constructNames(self.namesDict)

                    bind = createNode('joint',
                                      n=self.names.get('bind', 'rnm_bind'),
                                      p=trans)
                    self.step(bind, 'bind')
                    xform(bind, ws=1, ro=xform(jointsList[0], q=1, ws=1, ro=1))
                    self.bindList.append(bind)
                    bind.hide()

                # Create an exit node
                self.rigExit = createNode('transform',
                                          n=self.names.get(
                                              'rigExit', 'rnm_rigExit'),
                                          p=self.rigGroup)

                # End result for translation, end control for rotation and scale
                # T
                self.matrixConstraint(self.socket(
                    aimIKGroup.results.get()[-1]),
                                      self.rigExit,
                                      t=1,
                                      offset=False)
                # R (snap offset from jointsList)
                utils.snap(jointsList[-1], self.socket(self.aimCtrls[1]))
                self.matrixConstraint(self.socket(self.aimCtrls[1]),
                                      self.rigExit,
                                      t=0,
                                      r=1,
                                      s=1,
                                      offset=False)
                self.step(self.rigExit, 'rigExit')

                self.rigExit.message.connect(self.rigNode.socketList, na=1)

                self.naming(i=2)
                self.names = utils.constructNames(self.namesDict)

                doFootRoll = False
                if hasAttr(self.fitNode, 'subNode'):
                    if self.fitNode.subNode.get():
                        if self.fitNode.subNode.get().rigType.get(
                        ) == 'footRoll':
                            if self.fitNode.subNode.get().build.get():
                                if self.dev:
                                    print 'FOOTROLL:'
                                    print self.fitNode.subNode.get()
                                doFootRoll = True

                if not doFootRoll:
                    if bindEnd:
                        # No need for exit bind if there's a rigExtension (expand to include hand rig when it's done)
                        rigExitBind = createNode('joint',
                                                 n=self.names.get(
                                                     'rigExitBind',
                                                     'rnm_rigExitBind'),
                                                 p=self.rigExit)
                        self.step(rigExitBind, 'rigExitBind')
                        self.bindList.append(rigExitBind)
                        rigExitBind.hide()

                else:
                    # self.buildFootRollSetup(self.fitNode.subNode.get()) AIMIK
                    pass

            #=========================== Finalize =================================
            finally:
                try:
                    if doFK:
                        for fkCtrl in self.fkCtrls:
                            self.socket(fkCtrl).message.connect(
                                self.rigNode.socketList, na=1)
                except:
                    pass
                try:
                    if doFK:
                        self.setController(fkRigGroup, self.rigGroup)
                    self.setController(aimIKGroup, self.rigGroup)
                except:
                    pass

                try:
                    if doFK:
                        self.constructSelectionList(selectionName='fkCtrls',
                                                    selectionList=self.fkCtrls)

                    self.constructSelectionList(selectionName='aimCtrls',
                                                selectionList=self.aimCtrls)
                    self.constructSelectionList(selectionName='frozenNodes',
                                                selectionList=self.freezeList)
                except:
                    pass

                self.finalize()
Beispiel #4
0
def makeControl(name, xformType=None, **kwargs):
    """
    Create a control object
    @param name: the control name
    @param xformType: if creating a new xform, use this node type.  Defaults
    to transform
    @keyword t: offset the position of the handle shape.
    @keyword r: offset the rotation of the handle shape.
    @keyword s: offset the scale of the handle shape.
    @note: offsets are applied in the control xform's local space
    @raise RuntimeError: if the control exists, and xformType is supplied but does
    not match the current node's xform type
    """

    #see if the object exists, and create it if not
    editor = None
    if MC.objExists(name):
        if xformType and xformType != MC.objectType(name):
            raise RuntimeError('control exists and is not of type %s' % xformType)
        editor = getEditor(name)
        if editor:
            setEditable(name, False)
    else:
        if not xformType:
            xformType = 'transform'

        name = MC.createNode(xformType, name=name, parent=None)

    xform = name

    #delete any shapes that exist
    for shape in MC.listRelatives(xform, type='geometryShape', pa=1) or []:
        MC.delete(shape)


    #create an attribute to store handle info
    handleData = _argHandleData(**kwargs)

    #snap the tmp shape to the xform
    tmpXform = _importShape(handleData['shape'])

    utils.snap(xform, tmpXform, scale=True)

    #apply transformations
    MC.parent(tmpXform, xform)
    MC.setAttr('%s.t' % tmpXform, *handleData['t'], type='double3')
    MC.setAttr('%s.r' % tmpXform, *handleData['r'], type='double3')
    MC.setAttr('%s.s' % tmpXform, *handleData['s'], type='double3')
    MC.parent(tmpXform, world=True)

    utils.parentShape(xform, tmpXform)
    if handleData.get('type') != 'surface':
        _setColor(xform, handleData['color'])

    #set the handle info
    _logger.debug("handle data: %r" % handleData)
    setInfo(xform, handleData)

    if editor:
        setEditable(xform, True)

    return xform
Beispiel #5
0
    def __init__(self, fitNode=None, rigNode=None):

        if fitNode is None and rigNode is None:
            raise Exception('No data specified.')

        elif fitNode is None:
            self.rigNode = rigNode
            # Put any attributes needed for initialized rigs here

        else:
            try:
                # Initialize rigNode
                # Error Check:

                # Convert string input to PyNode if neccessary
                if isinstance(fitNode, str):
                    fitNode = ls(fitNode)[0]

                if fitNode.rigType.get() != 'chain':
                    raise Exception('Incorrect rig type: %s' %
                                    fitNode.rigType.get())

                self.offsetCtrls = []
                # self.crvs = []

                buildRig.rig.__init__(self, fitNode)

                # fitNode attributes

                jointsList = self.fitNode.jointsList.get()
                fkShapes = self.fitNode.fkShapes.get()
                ikShapes = self.fitNode.ikShapes.get()
                doIK = self.fitNode.offsets.get()

                multiChain = 0
                if hasAttr(self.fitNode, 'multiChain'):
                    multiChain = self.fitNode.multiChain.get()

                doHierarchy = True
                if hasAttr(self.fitNode, 'doHierarchy'):
                    doHierarchy = self.fitNode.doHierarchy.get()

                # if doHierarchy:
                # organize jointsList
                # Move rigGroup
                xform(self.rigGroup,
                      ws=1,
                      m=xform(jointsList[0], q=1, ws=1, m=1))

                # Mirroring
                if self.fitNode.side.get() == 2:
                    mirror = True
                else:
                    mirror = False

                # Per joint mirroring
                mirrorList = []
                for jnt in jointsList:
                    if jnt.autoMirror.get() is False:
                        mirrorList.append(False)
                    elif jnt.side.get() == 2:
                        mirrorList.append(True)
                    else:
                        mirrorList.append(False)
                if self.dev:
                    print 'mirrorList:'
                    print mirrorList

                if hasAttr(self.fitNode, 'bind'):
                    doBind = self.fitNode.bind.get()
                else:
                    doBind = True

                if hasAttr(self.fitNode, 'doFK'):
                    doFK = self.fitNode.doFK.get()
                else:
                    doFK = True

                # Make sure one of the options are on by default
                if not doFK and not doIK:
                    doFK = True

                if hasAttr(self.fitNode, 'doEntranceBind'):
                    doEntranceBind = bool(self.fitNode.doEntranceBind.get())
                else:
                    doEntranceBind = True

                # raise Exception('end test.')
                # Naming
                self.globalName = self.fitNode.globalName.get()
                self.subNames = []
                subAttrs = listAttr(self.fitNode, st='subName*')
                for subAttr in subAttrs:
                    self.subNames.append(self.fitNode.attr(subAttr).get())
                # print 'subnames:'
                # print self.subNames

                self.naming()
                self.names = utils.constructNames(self.namesDict)

                # ========================= RigNode Attributes =========================
                self.rigNode.rigType.set('chain', l=1)
                if doFK or doIK:
                    utils.cbSep(self.rigNode)
                if doFK:
                    addAttr(self.rigNode,
                            ct='publish',
                            ln='fkVis',
                            nn='FK Vis',
                            at='short',
                            min=0,
                            max=1,
                            dv=1)
                    setAttr(self.rigNode.fkVis, keyable=False, channelBox=True)
                if doIK:
                    addAttr(self.rigNode,
                            ct='publish',
                            ln='ikVis',
                            nn='IK Vis',
                            at='short',
                            min=0,
                            max=1,
                            dv=1)
                    setAttr(self.rigNode.ikVis, keyable=False, channelBox=True)

                # ========================= Vis Mults =========================
                # allVis Mults
                if doFK:
                    fkVisMult = createNode('multDoubleLinear',
                                           n=self.names.get(
                                               'fkVisMult', 'rnm_fkVisMult'))
                    self.rigNode.allVis >> fkVisMult.i1
                    self.rigNode.fkVis >> fkVisMult.i2
                    self.step(fkVisMult, 'fkVisMult')

                if doIK:
                    ikVisMult = createNode('multDoubleLinear',
                                           n=self.names.get(
                                               'ikVisMult', 'rnm_ikVisMult'))
                    self.rigNode.allVis >> ikVisMult.i1
                    self.rigNode.ikVis >> ikVisMult.i2
                    self.ikVis = ikVisMult.o
                    self.step(ikVisMult, 'ikVisMult')

                # debugVisMult = createNode('multDoubleLinear', n=self.names.get('debugVisMult', 'rnm_debugVisMult'))
                # self.debugVis = debugVisMult.o
                # self.rigNode.allVis >> debugVisMult.i1
                # self.rigNode.debugVis >> debugVisMult.i2
                # self.step(debugVisMult, 'debugVisMult')

                # ========================= World Group =========================
                # worldGroup = createNode('transform', n=self.names.get('worldGroup', 'rnm_worldGroup'), p=self.rigGroup)
                # self.worldGroup = worldGroup
                # self.step(worldGroup, 'worldGroup')
                # worldGroup.inheritsTransform.set(0)
                # xform(worldGroup, rp=[0,0,0], ro=[0,0,0], ws=1)

                #=========================== FK Setup =================================

                if doHierarchy:
                    print '\nJointsList:'
                    print jointsList
                    # We're going to form a hierarchy of controls based on a 'clump' of joints input as a list

                    # Reorder joints list so that we create controls top-down
                    heirScore = {}
                    for item in jointsList:
                        heirScore[item] = (len(item.getAllParents()))

                    import operator
                    sortedHeir = sorted(heirScore.items(),
                                        key=operator.itemgetter(1))

                    jointsList2 = []
                    for s in sortedHeir:
                        jointsList2.append(s[0])

                    print '\nJointsList2:'
                    print jointsList2

                    # Map controls to each joint
                    ctrlMapping = {}
                    for i, jnt in enumerate(jointsList2):

                        ind = jointsList.index(jnt)
                        self.naming(i=ind)
                        self.names = utils.constructNames(self.namesDict)

                        # Reach upward into each joint's parentage.  If no fit joints in list up to top, it's a root joint. otherwise, use first parent found
                        jntParent = jnt.getParent()
                        while not jntParent in jointsList2:
                            if jntParent is None:
                                break
                            jntParent = jntParent.getParent()

                        # If it found anything, get the control for that joint
                        if jntParent:
                            ctrlParent = ctrlMapping[jntParent]
                        else:
                            ctrlParent = None

                        if ctrlParent:
                            ctrl = self.createControlHeirarchy(
                                selectionPriority=0,
                                transformSnap=jnt,
                                mirrorStart=mirrorList[ind],
                                mirror=mirrorList[ind],
                                name=self.names.get('fkCtrl', 'rnm_fkCtrl'),
                                shape=fkShapes[ind],
                                par=ctrlParent,
                                ctrlParent=ctrlParent,
                                jntBuf=True)
                            # ctrl = createNode('transform', name=self.names.get('fkCtrl', 'rnm_fkCtrl'), p=ctrlParent)
                        else:
                            ctrl = self.createControlHeirarchy(
                                selectionPriority=0,
                                transformSnap=jnt,
                                mirrorStart=mirrorList[ind],
                                mirror=mirrorList[ind],
                                name=self.names.get('fkCtrl', 'rnm_fkCtrl'),
                                shape=fkShapes[ind],
                                par=self.rigGroup,
                                ctrlParent=self.rigGroup,
                                jntBuf=True)
                            # ctrl = createNode('transform', name=self.names.get('fkCtrl', 'rnm_fkCtrl'), p=self.rigGroup)

                        ctrlMapping[jnt] = ctrl

                        try:
                            self.fkCtrls.append(ctrl)
                        except AttributeError:
                            self.fkCtrls = []
                            self.fkCtrls.append(ctrl)

                        if ctrl.getShapes():
                            fkVisMult.o.connect(ctrl.getShapes()[0].v)
                        self.socket(ctrl).message.connect(
                            self.rigNode.socketList, na=1)

                    if self.dev:
                        print '\nctrlMapping:'
                        print ctrlMapping
                        for item, key in ctrlMapping.items():
                            print '%s\t-\t%s' % (item, key)

                else:
                    if doFK:
                        fkGroup = self.buildFkSetup(shapes=fkShapes,
                                                    transforms=jointsList,
                                                    mirror=mirror)
                        fkVisMult.o.connect(fkGroup.v)

                        if not doIK:
                            for fkCtrl in self.fkCtrls:
                                self.socket(fkCtrl).message.connect(
                                    self.rigNode.socketList, na=1)

                #=========================== Offset Setup =================================
                # Whether or not fk is created
                if doIK:
                    for i, jnt in enumerate(jointsList):
                        self.naming(i=i)
                        self.names = utils.constructNames(self.namesDict)

                        # If fk ctrls were created, parent them there
                        if doFK:
                            offsetCtrl = self.createControlHeirarchy(
                                selectionPriority=0,
                                mirror=mirror,
                                name=self.names.get('offsetCtrl',
                                                    'rnm_offsetCtrl'),
                                shape=ikShapes[i],
                                par=self.fkCtrls[i],
                                ctrlParent=self.fkCtrls[i],
                                jntBuf=False,
                                outlinerColor=(0, 0, 0))

                        # Else create offset controls on their own
                        else:
                            offsetCtrl = self.createControlHeirarchy(
                                selectionPriority=0,
                                mirror=mirror,
                                name=self.names.get('offsetCtrl',
                                                    'rnm_offsetCtrl'),
                                shape=ikShapes[i],
                                par=self.rigGroup,
                                ctrlParent=self.rigGroup,
                                jntBuf=False,
                                transformSnap=jnt)

                        self.offsetCtrls.append(offsetCtrl)
                        self.ctrlsList.append(offsetCtrl)

                        self.ikVis.connect(offsetCtrl.buf.get().v)

                        try:
                            self.ikCtrls.append(offsetCtrl)
                        except AttributeError:
                            self.ikCtrls = []
                            self.ikCtrls.append(offsetCtrl)

                        self.socket(offsetCtrl).message.connect(
                            self.rigNode.socketList, na=1)

                if doBind:
                    if doEntranceBind:
                        # Transform to handle distribution of mesh with root moved without rotation
                        rigEntranceGrp = createNode('transform',
                                                    n=self.names.get(
                                                        'rigEntranceGrp',
                                                        'rnm_rigEntranceGrp'),
                                                    p=self.rigGroup)
                        self.step(rigEntranceGrp, 'rigEntranceGrp')

                        # point constrain to start node
                        utils.snap(jointsList[0], rigEntranceGrp)
                        self.matrixConstraint(
                            self.ikCtrls[0] if doIK else self.fkCtrls[0],
                            rigEntranceGrp,
                            t=1)

                        rigEntrance = createNode('joint',
                                                 n=self.names.get(
                                                     'rigEntrance',
                                                     'rnm_rigEntrance'),
                                                 p=rigEntranceGrp)
                        self.step(rigEntrance, 'rigEntrance')
                        self.bindList.append(rigEntrance)
                        rigEntrance.hide()

                    for i, ctrl in enumerate(
                            self.ikCtrls if doIK else self.fkCtrls):
                        self.naming(i=i)
                        self.names = utils.constructNames(self.namesDict)

                        if mirror:
                            ctrl = self.socket(ctrl)
                        # 	ctrl.rotateY.set(-180)
                        # 	ctrl.scaleX.set(-1)

                        bind = createNode('joint',
                                          n=self.names.get('bind', 'rnm_bind'),
                                          p=ctrl)
                        self.bindList.append(bind)
                        self.step(bind, 'bind')
                        bind.hide()

            finally:

                #=========================== Finalize =================================

                try:
                    self.setController(fkRigGroup, self.rigGroup)
                except:
                    pass

                try:
                    self.constructSelectionList(selectionName='fkCtrls',
                                                selectionList=self.fkCtrls)
                    if doIK:
                        self.constructSelectionList(
                            selectionName='offsetCtrls',
                            selectionList=self.offsetCtrls)
                    self.constructSelectionList(selectionName='frozenNodes',
                                                selectionList=self.freezeList)
                except:
                    pass

                self.finalize()