示例#1
0
    def installModule(self, mod, moduleName, *args):
        self.disableSelectionScriptJob()

        moduleNamespace = self.currentBlueprintModule + ":" + mod.CLASS_NAME + "_1"

        moduleClass = getattr(mod, mod.CLASS_NAME)

        moduleInstance = moduleClass(moduleNamespace)

        moduleInstance.install()

        cmds.textScrollList(self.UIElements["controlModule_textScrollList"],
                            edit=True,
                            removeItem=moduleName)

        if cmds.textScrollList(self.UIElements["controlModule_textScrollList"],
                               q=True,
                               numberOfItems=True) != 0:
            cmds.textScrollList(
                self.UIElements["controlModule_textScrollList"],
                edit=True,
                selectIndexedItem=1)

        self.UI_controlModuleSelected()

        utils.forceSceneUpdate()

        cmds.select(self.currentBlueprintModule + ":module_container",
                    replace=True)

        self.setupSelectionScriptJob()
	def installModule(self,mod,moduleName,*args):
		self.disableSelectionScriptJob()
		
		moduleNamespace = self.currentBlueprintModule + ':' + mod.CLASS_NAME + '_1'
		
		moduleClass = getattr(mod,mod.CLASS_NAME)
		moduleInstance = moduleClass(moduleNamespace)
		moduleInstance.install()
		
		cmds.textScrollList(self.UIElements['controlModule_textScrolllist'],edit=True,removeItem=moduleName)
		
		if cmds.textScrollList(self.UIElements['controlModule_textScrolllist'],q=True, numberOfItems=True) != 0:
			cmds.textScrollList(self.UIElements['controlModule_textScrolllist'],edit=True,selectIndexedItem=1)
			
		self.UI_controlModuleSelected()
		
		utils.forceSceneUpdate()
		
		cmds.select(self.currentBlueprintModule + ':module_container', replace=True)
		
		
			
		
		
		self.setupSelectionScriptJob()
    def installModule(self, mod, moduleName):
        print "MM Install"

        moduleNamespace = self.currentBlueprintModule[
            'currentMod'] + ":" + mod.CLASS_NAME + "_1"

        moduleClass = getattr(mod, mod.CLASS_NAME)

        moduleInstance = moduleClass(moduleNamespace)

        moduleInstance.install()

        utils.forceSceneUpdate()
	def duplicateSelectedModule(self,*args):
		self.deleteScriptJob()
		
		
		
		result = cmds.confirmDialog(messageAlign='center',title='Duplicate Control Module',message='Duplicate animation as well as controls?',button=['Yes','No','Cancel'],defaultButton='Yes',cancelButton='Cancel',dismissString='Cancel')
		
		if result == 'Cancel':
			self.setupScriptJob()
			return
			
		duplicateWithAnimation = False
		if result == 'Yes':
			duplicateWithAnimation = True
			
		selectedModule = cmds.textScrollList(self.UIElements['animationModule_textScroll'],q=True,selectItem=True)[0]
		
		selectedModuleNamespace = self.selectedBlueprintModule + ':' + selectedModule
		
		moduleNameInfo = utils.findAllModuleNames('/Modules/Animation')
		modules = moduleNameInfo[0]
		moduleNames = moduleNameInfo[1]
		
		selectedModuleName = selectedModule.rpartition('_')[0]
		
		if selectedModuleName in moduleNames:
			moduleIndex = moduleNames.index(selectedModuleName)
			module = modules[moduleIndex]
			
			mod = __import__('Animation.'+module,{},{}, [module])
			reload(mod)
			
			moduleClass = getattr(mod,mod.CLASS_NAME)
			
			moduleInst = moduleClass(selectedModuleNamespace)
			
			selectedIndex = cmds.textScrollList(self.UIElements['animationModule_textScroll'],q=True, selectIndexedItem=True)[0]
			previousSelection = cmds.ls(selection=True)
			
			moduleInst.duplicateControlModule(withAnimation=duplicateWithAnimation)
			
			utils.forceSceneUpdate()
			
			if len(previousSelection) != 0:
				cmds.select(previousSelection, replace=True)
			else:
				cmds.select(clear=True)
			
			self.refreshAnimationModuleList(index= selectedIndex)
			
		self.setupScriptJob()
示例#5
0
 def duplicateSelectedModule(self, *args):
     self.deleteScriptJob()
     
     result = cmds.confirmDialog(messageAlign="center", title="Duplicate Control Module", message="Duplicate animation as well as controls?", button=["Yes", "No", "Cancel"], defaultButton="Yes", cancelButton="Cancel", dismissString="Cancel")
     
     if result == "Cancel":
         self.setupScriptJob()
         return
     
     duplicateWithAnimation = False
     if result == "Yes":
         duplicateWithAnimation = True
         
         
     selectedModule = cmds.textScrollList(self.UIElements["animationModule_textScroll"], q=True, selectItem=True)[0]
     selectedModuleNamespace = self.selectedBlueprintModule + ":" + selectedModule
     
     moduleNameInfo = utils.findAllModuleNames("/Modules/Animation")
     modules = moduleNameInfo[0]
     moduleNames = moduleNameInfo[1]
     
     selectedModuleName = selectedModule.rpartition("_")[0]
     
     if selectedModuleName in moduleNames:
         moduleIndex = moduleNames.index(selectedModuleName)
         module = modules[moduleIndex]
         
         mod = __import__("Animation."+module, {}, {}, [module])
         reload(mod)
         
         moduleClass = getattr(mod, mod.CLASS_NAME)
         
         moduleInst = moduleClass(selectedModuleNamespace)
         
         selectedIndex = cmds.textScrollList(self.UIElements["animationModule_textScroll"], q=True, selectIndexedItem=True)
         previousSelection = cmds.ls(sl=True)
         
         moduleInst.duplicateControlModule(withAnimation=duplicateWithAnimation)
         # Refresh animation module list
         utils.forceSceneUpdate()
         
         if len(previousSelection) != 0:
             cmds.select(previousSelection, replace=True)
         else:
             cmds.select(clear=True)
                    
         self.refreshAnimationModuleList(index = selectedIndex)
         
     self.setupScriptJob()
    def installModule(self, mod, moduleName):
        print "MM Install"
        
        moduleNamespace = self.currentBlueprintModule['currentMod'] + ":" + mod.CLASS_NAME+"_1"

        moduleClass = getattr(mod, mod.CLASS_NAME)

        moduleInstance = moduleClass(moduleNamespace)

        moduleInstance.install()
    
        utils.forceSceneUpdate()
        
        #cmds.select(self.currentBlueprintModule['currentMod'] + ":module_container", replace=True)
                   
示例#7
0
    def mirrorModules(self):
        # Make a progress bar to inform the user how long the mirror process is taking.
        mirrorModulesProgress_UI = cmds.progressWindow(
            title="Mirror Module(s)",
            status="This may take a few minutes...",
            isInterruptable=False)
        mirrorModulesProgress = 0

        mirrorModulesProgress_stage1_proportion = 15
        mirrorModulesProgress_stage2_proportion = 70
        mirrorModulesProgress_stage3_proportion = 10

        moduleNameInfo = utils.findAllModuleNames("/Modules/Blueprint")
        validModules = moduleNameInfo[0]
        validModuleNames = moduleNameInfo[1]

        for module in self.moduleInfo:
            moduleName = module[0].partition("__")[0]

            if moduleName in validModuleNames:
                index = validModuleNames.index(moduleName)
                module.append(validModules[index])
        #077
        mirrorModulesProgress_progressIncrement = mirrorModulesProgress_stage1_proportion / len(
            self.moduleInfo)
        for module in self.moduleInfo:
            userSpecifiedName = module[0].partition("__")[2]
            mod = __import__("Blueprint." + module[5], {}, {}, [module[5]])
            reload(mod)

            moduleClass = getattr(mod, mod.CLASS_NAME)
            moduleInst = moduleClass(userSpecifiedName, None)

            hookObject = moduleInst.findHookObject()

            newHookObject = None

            hookModule = utils.stripLeadingNamespace(hookObject)[0]

            hookFound = False
            for m in self.moduleInfo:
                if hookModule == m[0]:
                    hookFound = True

                    if m == module:
                        continue

                    hookObjectName = utils.stripLeadingNamespace(hookObject)[1]
                    newHookObject = m[1] + ":" + hookObjectName

            if not hookFound:
                newHookObject = hookObject

            module.append(newHookObject)

            hookConstrained = moduleInst.isRootConstrained()
            module.append(hookConstrained)

            mirrorModulesProgress += mirrorModulesProgress_progressIncrement
            cmds.progressWindow(mirrorModulesProgress_UI,
                                edit=True,
                                pr=mirrorModulesProgress)
        #078
        mirrorModulesProgress_progressIncrement = mirrorModulesProgress_stage2_proportion / len(
            self.moduleInfo)
        for module in self.moduleInfo:
            newUserSpecifiedName = module[1].partition("__")[2]

            mod = __import__("Blueprint." + module[5], {}, {}, [module[5]])
            reload(mod)
            # Create all the modules the re-hook
            moduleClass = getattr(mod, mod.CLASS_NAME)
            moduleInst = moduleClass(newUserSpecifiedName, None)

            moduleInst.mirror(module[0], module[2], module[3], module[4])

            mirrorModulesProgress += mirrorModulesProgress_progressIncrement
            cmds.progressWindow(mirrorModulesProgress_UI,
                                edit=True,
                                pr=mirrorModulesProgress)
        # 083
        # Mirror hooking
        mirrorModulesProgress_progressIncrement = mirrorModulesProgress_stage3_proportion / len(
            self.moduleInfo)
        for module in self.moduleInfo:
            newUserSpecifiedName = module[1].partition("__")[2]

            mod = __import__("Blueprint." + module[5], {}, {}, [module[5]])
            reload(mod)

            moduleClass = getattr(mod, mod.CLASS_NAME)
            moduleInst = moduleClass(newUserSpecifiedName, None)

            moduleInst.rehook(module[6])

            hookConstrained = module[7]
            if hookConstrained:
                moduleInst.constrainRootToHook()

            mirrorModulesProgress += mirrorModulesProgress_progressIncrement
            cmds.progressWindow(mirrorModulesProgress_UI,
                                edit=True,
                                pr=mirrorModulesProgress)
        #084
        # Mirror Groups
        if self.group != None:
            cmds.lockNode("Group_container", lock=False, lockUnpublished=False)

            groupParent = cmds.listRelatives(self.group, parent=True)

            if groupParent != None:
                groupParent = groupParent[0]
            # Recursive method
            self.processGroup(self.group, groupParent)

            cmds.lockNode("Group_container", lock=True, lockUnpublished=True)

            cmds.select(clear=True)

        cmds.progressWindow(mirrorModulesProgress_UI,
                            edit=True,
                            endProgress=True)

        utils.forceSceneUpdate()
 def install_custom(self, joints, moduleGrp, moduleContainer, createHandleControl=True, poleVectorAtRoot=True):
     rootJoint = joints[1]
     hingeJoint = joints[2]
     endJoint = joints[3]
     
     containedNodes = []
     
     twistRotationAimer = cmds.group(empty=True, n=rootJoint+"_twistRotationAimer")
     containedNodes.append(twistRotationAimer)
     
     containedNodes.append(cmds.pointConstraint(rootJoint, twistRotationAimer, maintainOffset=False, n=twistRotationAimer+"_pointConstraint")[0])
     cmds.pointConstraint(endJoint, twistRotationAimer, maintainOffset=False)
     
     upVectorTarget = cmds.group(empty=True, n=rootJoint+"_twistRotationAimer_upVectorTarget")
     containedNodes.append(upVectorTarget)
     
     cmds.parent(upVectorTarget, hingeJoint, relative=True)
     cmds.setAttr(upVectorTarget+".translateZ", cmds.getAttr(hingeJoint+".translateX"))
     
     containedNodes.append(cmds.aimConstraint(endJoint, twistRotationAimer, maintainOffset=False, n=twistRotationAimer+"_aimConstraint", aimVector=[0.0, 0.0, 1.0], upVector=[1.0, 0.0, 0.0], worldUpType="object", worldUpObject=upVectorTarget)[0])
     
     tempLocator = cmds.spaceLocator()[0]
     cmds.parent(tempLocator, twistRotationAimer, relative=True)
     cmds.setAttr(tempLocator+".translateY", 10)
     
     twistRotationAimerPos = cmds.xform(twistRotationAimer, q=True, worldSpace=True, translation=True)
     tempLocatorPos = cmds.xform(tempLocator, q=True, worldSpace=True, translation=True)
     
     offsetVector = [tempLocatorPos[0] - twistRotationAimerPos[0], tempLocatorPos[1] - twistRotationAimerPos[1], tempLocatorPos[2] - twistRotationAimerPos[2]]
     
     cmds.delete(tempLocator)
     
     ikNodes = utils.basic_stretchy_IK(rootJoint, endJoint, container=moduleContainer, scaleCorrectionAttribute=self.blueprintNamespace+":module_grp.hierarchicalScale")
     ikHandle = ikNodes["ikHandle"]
     rootPosLocator = ikNodes["rootLocator"]
     endPosLocator = ikNodes["endLocator"]
     poleVectorLocator = ikNodes["poleVectorObject"]
     stretchinessAttribute = ikNodes["stretchinessAttribute"]
     
     for node in [ikHandle, rootPosLocator, endPosLocator, poleVectorLocator]:
         cmds.parent(node, moduleGrp, absolute=True)
         
     if poleVectorAtRoot:
         poleVectorPos = cmds.xform(rootJoint, q=True, worldSpace=True, translation=True)
     else:
         poleVectorPos = cmds.xform(endJoint, q=True, worldSpace=True, translation=True)
         
     poleVectorPos[0] += offsetVector[0]
     poleVectorPos[1] += offsetVector[1]
     poleVectorPos[2] += offsetVector[2]
     cmds.xform(poleVectorLocator, worldSpace=True, absolute=True, translation=poleVectorPos)
     
     if createHandleControl:
         name = "ikHandleControl"
         
         controlObjectInstance = controlObject.ControlObject()
         handleControlInfo = controlObjectInstance.create(name, "cubeLocator.ma", self, lod=1, translation=True, rotation=True, globalScale=False, spaceSwitching=True)
         handleControl = handleControlInfo[0]
         handleRootParent = handleControlInfo[1]
         
         cmds.parent(handleRootParent, moduleGrp, relative=True)
         cmds.xform(handleControl, worldSpace=True, absolute=True, translation=cmds.xform(endPosLocator, q=True, worldSpace=True, translation=True))
         
         pointConstraint = cmds.pointConstraint(handleControl, endPosLocator, maintainOffset=False, n=endPosLocator+"_pointConstraint")[0]
         containedNodes.append(pointConstraint)
         
         cmds.select(handleControl)
         cmds.addAttr(at="float", minValue=0.0, maxValue=1.0, defaultValue=1.0, keyable=True, longName="stretchiness")
         cmds.connectAttr(handleControl+".stretchiness", stretchinessAttribute)
         
         self.publishNameToModuleContainer(handleControl+".stretchiness", "stretchiness", publishToOuterContainers=True)
         
     rotationCancellation = cmds.group(empty=True, n=self.blueprintNamespace+":"+self.moduleNamespace+":twistRotationCancellation")
     containedNodes.append(rotationCancellation)
     
     cmds.parent(rotationCancellation, twistRotationAimer, relative=True)
     
     twistControlOffset = cmds.group(empty=True, n=self.blueprintNamespace + ":" + self.moduleNamespace + ":twistControlOffset")
     containedNodes.append(twistControlOffset)
     
     cmds.parent(twistControlOffset, rotationCancellation, relative=True)
     
     twistControlObjectInstance = controlObject.ControlObject()
     twistControlInfo = twistControlObjectInstance.create("twistControl", "zAxisCircle.ma", self, lod=2, translation=False, rotation=[False, False, True], globalScale=False, spaceSwitching=True)
     twistControl = twistControlInfo[0]
     
     cmds.parent(twistControl, twistControlOffset, relative=True)
     cmds.connectAttr(twistControl+".rotateZ", ikHandle+".twist")
     
     pivotMultNode = cmds.shadingNode("multiplyDivide", asUtility=True, n=twistControl+"_invertOffset")
     containedNodes.append(pivotMultNode)
     
     cmds.connectAttr(twistControlOffset+".translateX", pivotMultNode+".input1X")
     cmds.setAttr(pivotMultNode+".input2X", -1)
     cmds.connectAttr(pivotMultNode+".output", twistControl+".rotatePivot")
     
     multNode = cmds.shadingNode("multiplyDivide", asUtility=True, n=rotationCancellation+"_invertRotateZ")
     containedNodes.append(multNode)
     
     cmds.connectAttr(twistControl+".rotateZ", multNode+".input1X")
     cmds.setAttr(multNode+".input2X", -1)
     cmds.connectAttr(multNode+".outputX", rotationCancellation+".rotateZ")
     
     cmds.parent(twistRotationAimer, moduleGrp, absolute=True)
     
     ikJoints = [joints[1], joints[2], joints[3]]
     
     jointName = utils.stripAllNamespaces(joints[1])[1]
     creationPoseRoot = self.blueprintNamespace+":creationPose_"+jointName
     creationPoseJoints = utils.findJointChain(creationPoseRoot)
     
     targetJoints = [creationPoseJoints[0], creationPoseJoints[1], creationPoseJoints[2]]
     
     utils.matchTwistAngle(twistControl+".rotateZ", ikJoints, targetJoints)
     
     offsetNode = cmds.shadingNode("plusMinusAverage", asUtility=True, n=twistControl+"_twistOffset")
     containedNodes.append(offsetNode)
     
     cmds.setAttr(offsetNode+".input1D[0]", cmds.getAttr(twistControl+".rotateZ"))
     cmds.connectAttr(twistControl+".rotateZ", offsetNode+".input1D[1]")
     cmds.connectAttr(offsetNode+".output1D", ikHandle+".twist", force=True)
     
     utils.forceSceneUpdate()
     cmds.setAttr(twistControl+".rotateZ", 0)
     
     utils.addNodeToContainer(moduleContainer, containedNodes)
     
     self.publishNameToModuleContainer(twistControlOffset+".translateX", "twistControlOffset", publishToOuterContainers=True)
     
     cmds.setAttr(moduleGrp+".lod", 2)
     
     return(ikNodes)
	def install(self):
		cmds.namespace(setNamespace=":")
		cmds.namespace(add=self.moduleNamespace)
		
		self.jointsGrp = cmds.group(empty=True, name=(self.moduleNamespace + ':joints_grp'))
		self.hierarchyRepresentationGrp = cmds.group(empty=True, name=(self.moduleNamespace + ':hierarchyRepresentation_grp'))
		self.orientationControlsGrp = cmds.group(empty=True, name=(self.moduleNamespace + ':orientationControls_grp'))
		self.preferredAngleRepresentationGrp = cmds.group(empty=True, name=self.moduleNamespace + ':preferredAngleRepresentation_grp')
		self.moduleGrp = cmds.group([self.jointsGrp, self.hierarchyRepresentationGrp,self.orientationControlsGrp,self.preferredAngleRepresentationGrp], name=(self.moduleNamespace + ':module_grp'))
		
		
		
		cmds.container(name=self.containerName, addNode=self.moduleGrp, ihb=True)
		
		cmds.select(clear=True)
		
		index = 0
		joints = []
		
		for joint in self.jointInfo:
			jointName = joint[0]
			jointPos = joint[1]
			
			parentJoint = ''
			if index>0:
				parentjoint = (self.moduleNamespace+ ':' + self.jointInfo[index -1][0])			
				cmds.select(parentjoint, replace=True)
					
			jointName_full = cmds.joint(name=(self.moduleNamespace + ':' + jointName), p=jointPos)
			joints.append(jointName_full)
			
			cmds.setAttr((jointName_full + '.visibility'),0)
			
			utils.addNodeToContainer(self.containerName, jointName_full)
			
			cmds.container(self.containerName, edit=True, publishAndBind=[(jointName_full + '.rotate'),(jointName + '_R')])
			cmds.container(self.containerName, edit=True, publishAndBind=[(jointName_full + '.rotateOrder'),(jointName + '_rotateOrder')])
			
			if index > 0:
				parentJoint = (self.moduleNamespace+ ':' + self.jointInfo[index -1][0])
				cmds.joint(parentJoint, edit=True, orientJoint='xyz' , sao='yup')
				
			index += 1
			
		if self.mirrored:
			mirrorXY = False
			mirrorYZ = False
			mirrorXZ = False
			if self.mirrorPlane == 'XY':
				mirrorXY = True
			if self.mirrorPlane == 'YZ':
				mirrorYZ = True
			if self.mirrorPlane == 'XZ':
				mirrorXZ = True
				
			mirrorBehavior = False
			if self.rotationFunction == 'behaviour':
				mirrorBehavior = True
				
			mirroredNodes = cmds.mirrorJoint(joints[0],mirrorXY=mirrorXY,mirrorYZ=mirrorYZ,mirrorXZ=mirrorXZ,mirrorBehavior=mirrorBehavior)
			
			cmds.delete(joints)
			
			mirroredJoints = []
			for node in mirroredNodes:
				if cmds.objectType(node,isType='joint'):
					mirroredJoints.append(node)
				else:
					cmds.delete(node)
					
			index = 0
			for joint in mirroredJoints:
				jointName = self.jointInfo[index][0]
				newJointName = cmds.rename(joint, self.moduleNamespace + ':' + jointName)
				
				self.jointInfo[index][1] = cmds.xform(newJointName, q=True, worldSpace=True, translation=True)
				
				index += 1
				
				
			
		cmds.parent(joints[0],self.jointsGrp, absolute=True)
		
		self.initialiseModuleTransform(self.jointInfo[0][1])
		
		translationControls = []
		for joint in joints:
			translationControls.append(self.createTranslationControlAtJoint(joint))
		
		rootJoint_pointConstraint = cmds.pointConstraint(translationControls[0], joints[0], maintainOffset=False, name=(joints[0] + '_pointConstraint'))
		utils.addNodeToContainer(self.containerName, rootJoint_pointConstraint)
		
		self.initialiseHook(translationControls[0])
		
		#setup Stretchy joint segments
		for index in range(len(joints) -1):
			self.setupStretchyJointSegment(joints[index],joints[index+1])
			
			
		self.install_custom(joints)
		
			
		utils.forceSceneUpdate()
		
		cmds.lockNode(self.containerName, lock=True, lockUnpublished=True)
    def install_custom(self,
                       joints,
                       moduleGrp,
                       moduleContainer,
                       createHandleControl=True,
                       poleVectorAtRoot=True):
        rootJoint = joints[1]
        hingeJoint = joints[2]
        endJoint = joints[3]

        containedNodes = []

        twistRotationAimer = cmds.group(empty=True,
                                        n=rootJoint + "_twistRotationAimer")
        containedNodes.append(twistRotationAimer)

        containedNodes.append(
            cmds.pointConstraint(rootJoint,
                                 twistRotationAimer,
                                 maintainOffset=False,
                                 n=twistRotationAimer + "_pointConstraint")[0])
        cmds.pointConstraint(endJoint,
                             twistRotationAimer,
                             maintainOffset=False)

        upVectorTarget = cmds.group(empty=True,
                                    n=rootJoint +
                                    "_twistRotationAimer_upVectorTarget")
        containedNodes.append(upVectorTarget)

        cmds.parent(upVectorTarget, hingeJoint, relative=True)
        cmds.setAttr(upVectorTarget + ".translateZ",
                     cmds.getAttr(hingeJoint + ".translateX"))

        containedNodes.append(
            cmds.aimConstraint(endJoint,
                               twistRotationAimer,
                               maintainOffset=False,
                               n=twistRotationAimer + "_aimConstraint",
                               aimVector=[0.0, 0.0, 1.0],
                               upVector=[1.0, 0.0, 0.0],
                               worldUpType="object",
                               worldUpObject=upVectorTarget)[0])

        tempLocator = cmds.spaceLocator()[0]
        cmds.parent(tempLocator, twistRotationAimer, relative=True)
        cmds.setAttr(tempLocator + ".translateY", 10)

        twistRotationAimerPos = cmds.xform(twistRotationAimer,
                                           q=True,
                                           worldSpace=True,
                                           translation=True)
        tempLocatorPos = cmds.xform(tempLocator,
                                    q=True,
                                    worldSpace=True,
                                    translation=True)

        offsetVector = [
            tempLocatorPos[0] - twistRotationAimerPos[0],
            tempLocatorPos[1] - twistRotationAimerPos[1],
            tempLocatorPos[2] - twistRotationAimerPos[2]
        ]

        cmds.delete(tempLocator)

        ikNodes = utils.basic_stretchy_IK(
            rootJoint,
            endJoint,
            container=moduleContainer,
            scaleCorrectionAttribute=self.blueprintNamespace +
            ":module_grp.hierarchicalScale")
        ikHandle = ikNodes["ikHandle"]
        rootPosLocator = ikNodes["rootLocator"]
        endPosLocator = ikNodes["endLocator"]
        poleVectorLocator = ikNodes["poleVectorObject"]
        stretchinessAttribute = ikNodes["stretchinessAttribute"]

        for node in [
                ikHandle, rootPosLocator, endPosLocator, poleVectorLocator
        ]:
            cmds.parent(node, moduleGrp, absolute=True)

        if poleVectorAtRoot:
            poleVectorPos = cmds.xform(rootJoint,
                                       q=True,
                                       worldSpace=True,
                                       translation=True)
        else:
            poleVectorPos = cmds.xform(endJoint,
                                       q=True,
                                       worldSpace=True,
                                       translation=True)

        poleVectorPos[0] += offsetVector[0]
        poleVectorPos[1] += offsetVector[1]
        poleVectorPos[2] += offsetVector[2]
        cmds.xform(poleVectorLocator,
                   worldSpace=True,
                   absolute=True,
                   translation=poleVectorPos)

        if createHandleControl:
            name = "ikHandleControl"

            controlObjectInstance = controlObject.ControlObject()
            handleControlInfo = controlObjectInstance.create(
                name,
                "cubeLocator.ma",
                self,
                lod=1,
                translation=True,
                rotation=True,
                globalScale=False,
                spaceSwitching=True)
            handleControl = handleControlInfo[0]
            handleRootParent = handleControlInfo[1]

            cmds.parent(handleRootParent, moduleGrp, relative=True)
            cmds.xform(handleControl,
                       worldSpace=True,
                       absolute=True,
                       translation=cmds.xform(endPosLocator,
                                              q=True,
                                              worldSpace=True,
                                              translation=True))

            pointConstraint = cmds.pointConstraint(handleControl,
                                                   endPosLocator,
                                                   maintainOffset=False,
                                                   n=endPosLocator +
                                                   "_pointConstraint")[0]
            containedNodes.append(pointConstraint)

            cmds.select(handleControl)
            cmds.addAttr(at="float",
                         minValue=0.0,
                         maxValue=1.0,
                         defaultValue=1.0,
                         keyable=True,
                         longName="stretchiness")
            cmds.connectAttr(handleControl + ".stretchiness",
                             stretchinessAttribute)

            self.publishNameToModuleContainer(handleControl + ".stretchiness",
                                              "stretchiness",
                                              publishToOuterContainers=True)

        rotationCancellation = cmds.group(empty=True,
                                          n=self.blueprintNamespace + ":" +
                                          self.moduleNamespace +
                                          ":twistRotationCancellation")
        containedNodes.append(rotationCancellation)

        cmds.parent(rotationCancellation, twistRotationAimer, relative=True)

        twistControlOffset = cmds.group(empty=True,
                                        n=self.blueprintNamespace + ":" +
                                        self.moduleNamespace +
                                        ":twistControlOffset")
        containedNodes.append(twistControlOffset)

        cmds.parent(twistControlOffset, rotationCancellation, relative=True)

        twistControlObjectInstance = controlObject.ControlObject()
        twistControlInfo = twistControlObjectInstance.create(
            "twistControl",
            "zAxisCircle.ma",
            self,
            lod=2,
            translation=False,
            rotation=[False, False, True],
            globalScale=False,
            spaceSwitching=True)
        twistControl = twistControlInfo[0]

        cmds.parent(twistControl, twistControlOffset, relative=True)
        cmds.connectAttr(twistControl + ".rotateZ", ikHandle + ".twist")

        pivotMultNode = cmds.shadingNode("multiplyDivide",
                                         asUtility=True,
                                         n=twistControl + "_invertOffset")
        containedNodes.append(pivotMultNode)

        cmds.connectAttr(twistControlOffset + ".translateX",
                         pivotMultNode + ".input1X")
        cmds.setAttr(pivotMultNode + ".input2X", -1)
        cmds.connectAttr(pivotMultNode + ".output",
                         twistControl + ".rotatePivot")

        multNode = cmds.shadingNode("multiplyDivide",
                                    asUtility=True,
                                    n=rotationCancellation + "_invertRotateZ")
        containedNodes.append(multNode)

        cmds.connectAttr(twistControl + ".rotateZ", multNode + ".input1X")
        cmds.setAttr(multNode + ".input2X", -1)
        cmds.connectAttr(multNode + ".outputX",
                         rotationCancellation + ".rotateZ")

        cmds.parent(twistRotationAimer, moduleGrp, absolute=True)

        ikJoints = [joints[1], joints[2], joints[3]]

        jointName = utils.stripAllNamespaces(joints[1])[1]
        creationPoseRoot = self.blueprintNamespace + ":creationPose_" + jointName
        creationPoseJoints = utils.findJointChain(creationPoseRoot)

        targetJoints = [
            creationPoseJoints[0], creationPoseJoints[1], creationPoseJoints[2]
        ]

        utils.matchTwistAngle(twistControl + ".rotateZ", ikJoints,
                              targetJoints)

        offsetNode = cmds.shadingNode("plusMinusAverage",
                                      asUtility=True,
                                      n=twistControl + "_twistOffset")
        containedNodes.append(offsetNode)

        cmds.setAttr(offsetNode + ".input1D[0]",
                     cmds.getAttr(twistControl + ".rotateZ"))
        cmds.connectAttr(twistControl + ".rotateZ", offsetNode + ".input1D[1]")
        cmds.connectAttr(offsetNode + ".output1D",
                         ikHandle + ".twist",
                         force=True)

        utils.forceSceneUpdate()
        cmds.setAttr(twistControl + ".rotateZ", 0)

        utils.addNodeToContainer(moduleContainer, containedNodes)

        self.publishNameToModuleContainer(twistControlOffset + ".translateX",
                                          "twistControlOffset",
                                          publishToOuterContainers=True)

        cmds.setAttr(moduleGrp + ".lod", 2)

        return (ikNodes)
	def install_custom(self,joints,moduleGrp,moduleContainer, createHandleControl=True, poleVectorAtRoot=True):
		rootJoint = joints[1]
		hingeJoint = joints[2]
		endJoint = joints[3]
		
		containedNodes = []
		
		twistRotationAimer = cmds.group(empty=True,n=rootJoint+'_twistRotationAimer')
		containedNodes.append(twistRotationAimer)
		
		containedNodes.append(cmds.pointConstraint(rootJoint,twistRotationAimer,maintainOffset=False, n=twistRotationAimer+'_pointConstraint')[0])
		cmds.pointConstraint(endJoint,twistRotationAimer,maintainOffset=False)
		
		upVectorTarget = cmds.group(empty=True, n=rootJoint+'_twistRotationAimer_upVectorTarget')
		containedNodes.append(upVectorTarget)
		
		cmds.parent(upVectorTarget, hingeJoint,relative=True)
		cmds.setAttr(upVectorTarget+'.translateZ',cmds.getAttr(hingeJoint+'.translateX'))
		
		containedNodes.append(cmds.aimConstraint(endJoint, twistRotationAimer, maintainOffset=False, n=twistRotationAimer+'_aimConstraint', aimVector=[0.0,0.0,1.0],upVector=[1.0,0.0,0.0],worldUpType='object',worldUpObject=upVectorTarget)[0])
		
		tempLocator = cmds.spaceLocator()[0]
		cmds.parent(tempLocator, twistRotationAimer,relative=True)
		cmds.setAttr(tempLocator+'.translateY',10)
		
		twistRotationAimerPos = cmds.xform(twistRotationAimer,q=True, worldSpace=True, translation=True)
		tempLocatorPos = cmds.xform(tempLocator,q=True, worldSpace=True, translation=True)
		
		offsetVector = [tempLocatorPos[0] - twistRotationAimerPos[0],tempLocatorPos[1] - twistRotationAimerPos[1],tempLocatorPos[2] - twistRotationAimerPos[2]]
		
		cmds.delete(tempLocator)
		
		ikNodes = utils.basic_stretchy_IK(rootJoint,endJoint,container=moduleContainer,scaleCorrectionAttribute=self.blueprintNamespace+':module_grp.hierarchicalScale')
		ikHandle = ikNodes['ikHandle']
		rootPosLocator = ikNodes['rootLocator']
		endPosLocator = ikNodes['endLocator']
		poleVectorLocator = ikNodes['poleVectorObject']
		stretchinessAttribute = ikNodes['stretchinessAttribute']
		
		for node in [ikHandle,rootPosLocator,endPosLocator,poleVectorLocator]:
			cmds.parent(node,moduleGrp,absolute=True)
			
		

		if poleVectorAtRoot:
			poleVectorPos = cmds.xform(rootJoint,q=True,worldSpace=True,translation=True)
		else:
			poleVectorPos = cmds.xform(endJoint,q=True,worldSpace=True,translation=True)
			
		poleVectorPos[0] += offsetVector[0]
		poleVectorPos[1] += offsetVector[1]
		poleVectorPos[2] += offsetVector[2]
		cmds.xform(poleVectorLocator,worldSpace=True,absolute=True,translation=poleVectorPos)
		
		if createHandleControl:
			name = 'ikHandleControl'
			
			controlObjectInstance = controlObject.ControlObject()
			handleControlInfo = controlObjectInstance.create(name,'cubeLocator.ma',self,lod=1,translation=True,rotation=False,globalScale=False,spaceSwitching=True)
			handleControl = handleControlInfo[0]
			handleRootParent = handleControlInfo[1]
			
			cmds.parent(handleRootParent,moduleGrp,relative=True)
			
			cmds.xform(handleControl,worldSpace=True,absolute=True,translation=cmds.xform(endPosLocator,q=True,worldSpace=True,translation=True))
			
			pointConstraint = cmds.pointConstraint(handleControl,endPosLocator, maintainOffset=False,n=endPosLocator+'_pointConstraint')[0]
			containedNodes.append(pointConstraint)
			
			cmds.select(handleControl)
			cmds.addAttr(at='float',minValue=0.0, maxValue=1.0, defaultValue=1.0,keyable=True,longName='stretchiness')
			cmds.connectAttr(handleControl+'.stretchiness',stretchinessAttribute)
			
			self.publishNameToModuleContainer(handleControl+'.stretchiness', 'stretchiness',publishToOuterContainers=True)
			
		rotationCancellation = cmds.group(empty=True,n=self.blueprintNamespace+':'+self.moduleNamespace+':twistRotationCancellation')
		containedNodes.append(rotationCancellation)
			
		cmds.parent(rotationCancellation, twistRotationAimer,relative=True)
			
		twistControlOffset = cmds.group(empty=True,n=self.blueprintNamespace + ':' + self.moduleNamespace + ':twistControlOffset')
		containedNodes.append(twistControlOffset)
			
		cmds.parent(twistControlOffset, rotationCancellation, relative=True)
			
		twistControlObjectInstance = controlObject.ControlObject()
		twistControlInfo = twistControlObjectInstance.create('twistControl','zAxisCircle.ma',self, lod=2,translation=False,rotation=[False,False,True],globalScale=False, spaceSwitching=False)
		twistControl = twistControlInfo[0]
			
		cmds.parent(twistControl,twistControlOffset,relative=True)
		cmds.connectAttr(twistControl+'.rotateZ',ikHandle+'.twist')
			
		pivotMultNode = cmds.shadingNode('multiplyDivide',asUtility=True,n=twistControl+'_invertOffset')
		containedNodes.append(pivotMultNode)
			
		cmds.connectAttr(twistControlOffset+'.translateX',pivotMultNode+'.input1X')
		cmds.setAttr(pivotMultNode+'.input2X',-1)
		cmds.connectAttr(pivotMultNode+'.output', twistControl+'.rotatePivot')
			
		multNode = cmds.shadingNode('multiplyDivide', asUtility=True, n=rotationCancellation+'_invertRotateZ')
		containedNodes.append(multNode)
			
		cmds.connectAttr(twistControl+'.rotateZ',multNode+'.input1X')
		cmds.setAttr(multNode+'.input2X',-1)
		cmds.connectAttr(multNode+'.outputX',rotationCancellation+'.rotateZ')
			
		cmds.parent(twistRotationAimer,moduleGrp, absolute=True)
			
		ikJoints = [joints[1],joints[2],joints[3]]
			
		jointName = utils.stripAllNamespaces(joints[1])[1]
		creationPoseRoot = self.blueprintNamespace+':creationPose_'+jointName
		creationPoseJoints = utils.findJointChain(creationPoseRoot)
			
		targetJoints = [creationPoseJoints[0],creationPoseJoints[1],creationPoseJoints[2]]
			
		utils.matchTwistAngle(twistControl+'.rotateZ',ikJoints,targetJoints)
			
		offsetNode = cmds.shadingNode('plusMinusAverage',asUtility=True,n=twistControl+'_twistOffset')
		containedNodes.append(offsetNode)
			
		cmds.setAttr(offsetNode+'.input1D[0]',cmds.getAttr(twistControl+'.rotateZ'))
		cmds.connectAttr(twistControl+'.rotateZ',offsetNode+'.input1D[1]')
		cmds.connectAttr(offsetNode+'.output1D',ikHandle+'.twist',force=True)
			
		utils.forceSceneUpdate()
		cmds.setAttr(twistControl+'.rotateZ',0)
			
		utils.addNodeToContainer(moduleContainer,containedNodes)
			
		self.publishNameToModuleContainer(twistControlOffset+'.translateX','twistControlOffset',publishToOuterContainers=True)
			
		cmds.setAttr(moduleGrp+'.lod',2)
			

			
		return (ikNodes)