Ejemplo n.º 1
0
    def CreateChain(self, objs = None, fwd = 'z+', up='y+',name = None):
        _str_func = 'CreateChain'
        
        objs = cgmMeta.asMeta( mc.ls(sl=True) )
        
        if not objs:
            return log.warning("No objects passed. Unable to createChain")
            
        if name is None:
            name = objs[-1].p_nameBase

        self.targets = self.targets + objs

        fwdAxis = simpleAxis(fwd)
        upAxis = simpleAxis(up)

        crvPositions = []

        for obj in objs:
            crvPositions.append(obj.p_position)

        crvPositions.append( DIST.get_pos_by_axis_dist(objs[-1], fwdAxis.p_string,
                                                       DIST.get_distance_between_points(crvPositions[-1],crvPositions[-2])) )

        crvPositions.insert(0, DIST.get_pos_by_axis_dist(objs[0], fwdAxis.inverse.p_string,
                                                         DIST.get_distance_between_points(crvPositions[0],crvPositions[1])*.5) )

        crv = CORERIG.create_at(create='curve',l_pos= crvPositions, baseName = name)

        # make the dynamic setup
        b_existing = False
        if self.hairSystem != None:
            log.info(cgmGEN.logString_msg(_str_func,'Using existing system: {0}'.format(self.hairSystem)))
            mc.select(self.hairSystem, add=True)
            b_existing = True
            
        mel.eval('makeCurvesDynamic 2 { "0", "0", "1", "1", "0" }')

        # get relevant nodes
        follicle = mc.listRelatives(crv,parent=True)[0]
        mFollicle = cgmMeta.asMeta(follicle)
        mFollicle.rename("{0}_foll".format(name))
        follicle = mFollicle.mNode
        self.ml_follicles.append(mFollicle)
        
        follicleShape = mc.listRelatives(mFollicle.mNode, shapes=True)[0]
        self.hairSystem = mc.listRelatives( mc.listConnections('%s.currentPosition' % follicleShape)[0], shapes=True)[0]
        if not b_existing:
            mHairSys = cgmMeta.asMeta(self.hairSystem)
            mHairSysDag = mHairSys.getTransform(asMeta=1)
            
            mHairSysDag.rename("{0}_hairSys".format(self.baseName))
            self.hairSystem = mHairSys.mNode
            
        outCurve = mc.listConnections('%s.outCurve' % follicle)[0]
        outCurveShape = mc.listRelatives(outCurve, shapes=True)[0]
        self.nucleus = mc.listConnections( '%s.currentState' % self.hairSystem )[0]
        if not b_existing:
            pass
        mc.select( objs[0].getParent() )

        self.follicles.append(follicle)
        self.outCurves.append(outCurve)
        
        # set default properties
        mc.setAttr( '%s.pointLock' % follicleShape, 1 )
        mc.parentConstraint(objs[0].getParent(), follicle, mo=True)

        # create locators on objects
        locators = []
        prs = []

        for i, obj in enumerate(objs):
            loc = LOC.create(obj.getNameLong())
            locators.append(loc)
            
            aimNull = mc.group(em=True)
            aimNull = mc.rename('%s_aim' % obj.getShortName())
            
            poc = mc.createNode('pointOnCurveInfo', name='%s_pos' % loc)
            pocAim = mc.createNode('pointOnCurveInfo', name='%s_aim' % loc)
            pr = CURVES.getUParamOnCurve(loc, outCurve)
            
            mc.connectAttr( '%s.worldSpace[0]' % outCurveShape, '%s.inputCurve' % poc, f=True )
            mc.connectAttr( '%s.worldSpace[0]' % outCurveShape, '%s.inputCurve' % pocAim, f=True )

            mc.setAttr( '%s.parameter' % poc, pr )
            
            if i < len(objs)-1:
                nextpr = CURVES.getUParamOnCurve(objs[i+1], outCurve)
                mc.setAttr('%s.parameter' % pocAim, (nextpr + pr) * .5)
            else:
                mc.setAttr( '%s.parameter' % pocAim, len(objs)+1 )
            
            locParent = mc.group(em=True)
            locParent = mc.rename( '%s_pos' % obj.getShortName() )

            mc.connectAttr( '%s.position' % poc, '%s.translate' % locParent)
            mc.connectAttr( '%s.position' % pocAim, '%s.translate' % aimNull)
            
            aimConstraint = mc.aimConstraint( aimNull, locParent, aimVector=fwdAxis.p_vector, upVector = upAxis.p_vector, worldUpType = "objectrotation", worldUpVector = upAxis.p_vector, worldUpObject = objs[0].getParent() )

            mc.parent(loc, locParent)
Ejemplo n.º 2
0
def ik_rp(self,
          mStart,
          mEnd,
          ml_ikFrame=None,
          mIKControl=None,
          mIKBaseControl=None,
          mIKHandleDriver=None,
          mRoot=None,
          mIKGroup=None,
          mIKControlEnd=None,
          ml_ikFullChain=None):
    try:
        _str_func = "ik_rp"
        log.debug("|{0}| >> {1}...".format(_str_func, _str_func) + '-' * 60)

        mRigNull = self.mRigNull
        mBlock = self.mBlock

        if not ml_ikFrame:
            ml_ikFrame = self.ml_handleTargetsCulled
        if not mIKControl:
            raise ValueError, "Must have mIKControl"

        if not mIKHandleDriver:
            raise ValueError, "Must have mIKHandleDriver"
        if not mRoot:
            raise ValueError, "Must have mRoot"

        log.debug("|{0}| >> rp setup...".format(_str_func))
        mIKMid = mRigNull.controlIKMid
        str_ikEnd = mBlock.getEnumValueString('ikEnd')
        #Measture ======================================================
        log.debug("|{0}| >> measure... ".format(_str_func) + '-' * 30)

        res_ikScale = self.UTILS.get_blockScale(
            self, '{0}_ikMeasure'.format(self.d_module['partName'], ),
            ml_ikFrame)

        mPlug_masterScale = res_ikScale[0]
        mMasterCurve = res_ikScale[1]
        mMasterCurve.p_parent = mRoot
        self.fnc_connect_toRigGutsVis(mMasterCurve)
        mMasterCurve.dagLock(True)

        #Unparent the children from the end while we set stuff up...
        log.debug("|{0}| >> end unparent ...".format(_str_func) + '-' * 30)

        ml_end_children = mEnd.getChildren(asMeta=True)
        if ml_end_children:
            for mChild in ml_end_children:
                mChild.parent = False

        #Build the IK ---------------------------------------------------------------------
        reload(IK)
        """
        if mIKControlEnd and str_ikEnd in ['tipCombo']:
            mMainIKControl = mIKControlEnd
        else:
            mMainIKControl = mIKControl
        """
        _d_ik = {
            'globalScaleAttr': mPlug_masterScale.
            p_combinedName,  #mPlug_globalScale.p_combinedName,
            'stretch': 'translate',
            'lockMid': True,
            'rpHandle': mIKMid.mNode,
            'nameSuffix': 'ik',
            'baseName': '{0}_ikRP'.format(self.d_module['partName']),
            'controlObject': mIKControl.mNode,
            'moduleInstance': self.mModule.mNode
        }

        d_ikReturn = IK.handle(mStart.mNode, mEnd.mNode, **_d_ik)
        mIKHandle = d_ikReturn['mHandle']
        ml_distHandlesNF = d_ikReturn['ml_distHandles']
        mRPHandleNF = d_ikReturn['mRPHandle']

        #>>>Parent IK handles -----------------------------------------------------------------
        log.debug("|{0}| >> parent IK stuff ...".format(_str_func) + '-' * 30)

        mIKHandle.parent = mIKHandleDriver.mNode  #handle to control
        for mObj in ml_distHandlesNF[:-1]:
            mObj.parent = mRoot
        ml_distHandlesNF[-1].parent = mIKHandleDriver.mNode  #handle to control
        ml_distHandlesNF[1].parent = mIKMid
        ml_distHandlesNF[1].t = 0, 0, 0
        ml_distHandlesNF[1].r = 0, 0, 0

        if mIKBaseControl:
            ml_distHandlesNF[0].parent = mIKBaseControl

        #>>> Fix our ik_handle twist at the end of all of the parenting
        IK.handle_fixTwist(mIKHandle,
                           self.d_orientation['str'][0])  #Fix the twist

        if mIKControlEnd:
            mIKEndDriver = mIKControlEnd
        else:
            mIKEndDriver = mIKControl

        if ml_end_children:
            for mChild in ml_end_children:
                mChild.parent = mEnd

        #mc.scaleConstraint([mIKControl.mNode],
        #                    ml_ikFrame[self.int_handleEndIdx].mNode,
        #                    maintainOffset = True)
        #if mIKBaseControl:
        #ml_ikFrame[0].parent = mRigNull.controlIKBase

        #if mIKBaseControl:
        #mc.pointConstraint(mIKBaseControl.mNode, ml_ikFrame[0].mNode,maintainOffset=True)

        #Make a spin group ===========================================================
        log.debug("|{0}| >> spin group ...".format(_str_func) + '-' * 30)

        mSpinGroup = mStart.doGroup(False, False, asMeta=True)
        mSpinGroup.doCopyNameTagsFromObject(self.mModule.mNode,
                                            ignore=['cgmName', 'cgmType'])
        mSpinGroup.addAttr('cgmName',
                           '{0}NoFlipSpin'.format(self.d_module['partName']))
        mSpinGroup.doName()
        ATTR.set(mSpinGroup.mNode, 'rotateOrder', self.d_orientation['str'])

        mSpinGroup.parent = mIKGroup
        mSpinGroup.doGroup(True, True, typeModifier='zero')
        mSpinGroupAdd = mSpinGroup.doDuplicate()

        mSpinGroupAdd.doStore('cgmTypeModifier', 'addSpin')
        mSpinGroupAdd.doName()
        mSpinGroupAdd.p_parent = mSpinGroup

        if mIKBaseControl:
            mc.pointConstraint(mIKBaseControl.mNode,
                               mSpinGroup.mNode,
                               maintainOffset=True)

        #Setup arg
        #mPlug_spin = cgmMeta.cgmAttr(mIKControl,'spin',attrType='float',keyable=True, defaultValue = 0, hidden = False)
        #mPlug_spin.doConnectOut("%s.r%s"%(mSpinGroup.mNode,_jointOrientation[0]))

        mSpinTarget = mIKControl

        if mBlock.getMayaAttr('ikRPAim'):
            mc.aimConstraint(mSpinTarget.mNode,
                             mSpinGroup.mNode,
                             maintainOffset=False,
                             aimVector=[0, 0, 1],
                             upVector=[0, 1, 0],
                             worldUpType='none')
        else:
            mc.aimConstraint(mSpinTarget.mNode,
                             mSpinGroup.mNode,
                             maintainOffset=False,
                             aimVector=[0, 0, 1],
                             upVector=[0, 1, 0],
                             worldUpObject=mSpinTarget.mNode,
                             worldUpType='objectrotation',
                             worldUpVector=self.v_twistUp)

        mPlug_spinMid = cgmMeta.cgmAttr(mSpinTarget,
                                        'spinMid',
                                        attrType='float',
                                        defaultValue=0,
                                        keyable=True,
                                        lock=False,
                                        hidden=False)

        _direction = self.d_module.get('direction') or 'center'

        if _direction.lower() == 'right':
            str_arg = "{0}.r{1} = -{2}".format(
                mSpinGroupAdd.mNode, self.d_orientation['str'][0].lower(),
                mPlug_spinMid.p_combinedShortName)
            log.debug("|{0}| >> Right knee spin: {1}".format(
                _str_func, str_arg))
            NODEFACTORY.argsToNodes(str_arg).doBuild()
        else:
            mPlug_spinMid.doConnectOut("{0}.r{1}".format(
                mSpinGroupAdd.mNode, self.d_orientation['str'][0]))

        mSpinGroup.dagLock(True)
        mSpinGroupAdd.dagLock(True)

        #>>> mBallRotationControl ==========================================================
        mIKBallRotationControl = mRigNull.getMessageAsMeta(
            'controlBallRotation')
        if mIKBallRotationControl:  # and str_ikEnd not in ['tipCombo']:
            log.debug("|{0}| >> mIKBallRotationControl...".format(_str_func) +
                      '-' * 30)

            mBallOrientGroup = cgmMeta.validateObjArg(
                mIKBallRotationControl.doGroup(True,
                                               False,
                                               asMeta=True,
                                               typeModifier='orient'),
                'cgmObject',
                setClass=True)
            ATTR.set(mBallOrientGroup.mNode, 'rotateOrder',
                     self.d_orientation['str'])

            mLocBase = mIKBallRotationControl.doCreateAt()
            mLocAim = mIKBallRotationControl.doCreateAt()

            mLocAim.doStore('cgmTypeModifier', 'extendedIK')
            mLocBase = mIKBallRotationControl.doCreateAt()

            mLocBase.doName()
            mLocAim.doName()

            mLocAim.p_parent = ml_ikFullChain[-1]
            mLocBase.p_parent = mIKBallRotationControl.masterGroup

            const = mc.orientConstraint([mLocAim.mNode, mLocBase.mNode],
                                        mBallOrientGroup.mNode,
                                        maintainOffset=True)[0]

            d_blendReturn = NODEFACTORY.createSingleBlendNetwork(
                [mIKControl.mNode, 'extendIK'],
                [mIKControl.mNode, 'resRootFollow'],
                [mIKControl.mNode, 'resFullFollow'],
                keyable=True)

            targetWeights = mc.orientConstraint(const,
                                                q=True,
                                                weightAliasList=True,
                                                maintainOffset=True)

            #Connect
            d_blendReturn['d_result1']['mi_plug'].doConnectOut(
                '%s.%s' % (const, targetWeights[0]))
            d_blendReturn['d_result2']['mi_plug'].doConnectOut(
                '%s.%s' % (const, targetWeights[1]))
            d_blendReturn['d_result1']['mi_plug'].p_hidden = True
            d_blendReturn['d_result2']['mi_plug'].p_hidden = True

            mBallOrientGroup.dagLock(True)
            mLocAim.dagLock(True)
            mLocBase.dagLock(True)

            mIKBallRotationControl.p_parent = mBallOrientGroup

            #Joint constraint -------------------------
            mIKBallRotationControl.masterGroup.p_parent = mPivotResultDriver
            mc.orientConstraint([mIKBallRotationControl.mNode],
                                ml_ikFrame[self.int_handleEndIdx].mNode,
                                maintainOffset=True)
            mc.parentConstraint([mPivotResultDriver.mNode],
                                ml_ikFrame[self.int_handleEndIdx + 1].mNode,
                                maintainOffset=True)

            ATTR.set_default(mIKControl.mNode, 'extendIK', 1.0)
            mIKControl.extendIK = 0.0

        elif str_ikEnd == 'bank':
            mc.orientConstraint([mPivotResultDriver.mNode],
                                ml_ikFrame[self.int_handleEndIdx].mNode,
                                maintainOffset=True)
        elif str_ikEnd == 'pad':
            mc.orientConstraint([mPivotResultDriver.mNode],
                                ml_ikFrame[self.int_handleEndIdx].mNode,
                                maintainOffset=True)
        else:
            mc.orientConstraint([mIKEndDriver.mNode],
                                ml_ikFrame[self.int_handleEndIdx].mNode,
                                maintainOffset=True)

        #Mid IK driver -----------------------------------------------------------------------
        log.debug("|{0}| >> mid Ik driver...".format(_str_func) + '-' * 30)

        log.debug("|{0}| >> mid IK driver.".format(_str_func))
        mMidControlDriver = mIKMid.doCreateAt()
        mMidControlDriver.addAttr(
            'cgmName', '{0}_midIK'.format(self.d_module['partName']))
        mMidControlDriver.addAttr('cgmType', 'driver')
        mMidControlDriver.doName()
        mMidControlDriver.addAttr('cgmAlias', 'midDriver')

        if mIKBaseControl:
            l_midDrivers = [mIKBaseControl.mNode]
        else:
            l_midDrivers = [mRoot.mNode]

        if str_ikEnd in ['tipCombo'] and mIKControlEnd:
            log.debug("|{0}| >> mIKControlEnd + tipCombo...".format(_str_func))
            l_midDrivers.append(mIKControl.mNode)
        else:
            l_midDrivers.append(mIKHandleDriver.mNode)

        mc.pointConstraint(l_midDrivers, mMidControlDriver.mNode)
        mMidControlDriver.parent = mSpinGroupAdd  #mIKGroup
        mIKMid.masterGroup.parent = mMidControlDriver
        mMidControlDriver.dagLock(True)

        #Mid IK trace
        log.debug("|{0}| >> midIK track Crv".format(_str_func, mIKMid))
        trackcrv, clusters = CORERIG.create_at(
            [
                mIKMid.mNode, ml_ikFrame[MATH.get_midIndex(
                    len(ml_ikFrame))].mNode
            ],  #ml_handleJoints[1]],
            'linearTrack',
            baseName='{0}_midTrack'.format(self.d_module['partName']))

        mTrackCrv = cgmMeta.asMeta(trackcrv)
        mTrackCrv.p_parent = self.mModule
        mHandleFactory = mBlock.asHandleFactory()
        mHandleFactory.color(mTrackCrv.mNode, controlType='sub')

        for s in mTrackCrv.getShapes(asMeta=True):
            s.overrideEnabled = 1
            s.overrideDisplayType = 2
        mTrackCrv.doConnectIn('visibility', "{0}.v".format(mIKGroup.mNode))

        #Full IK chain -----------------------------------------------------------------------
        if ml_ikFullChain:
            log.debug("|{0}| >> Full IK Chain...".format(_str_func))
            _d_ik = {
                'globalScaleAttr': mPlug_masterScale.
                p_combinedName,  #mPlug_globalScale.p_combinedName,
                'stretch': 'translate',
                'lockMid': False,
                'rpHandle': mIKMid.mNode,
                'baseName':
                '{0}_ikFullChain'.format(self.d_module['partName']),
                'nameSuffix': 'ikFull',
                'controlObject': mIKControl.mNode,
                'moduleInstance': self.mModule.mNode
            }

            d_ikReturn = IK.handle(ml_ikFullChain[0], ml_ikFullChain[-1],
                                   **_d_ik)
            mIKHandle = d_ikReturn['mHandle']
            ml_distHandlesNF = d_ikReturn['ml_distHandles']
            mRPHandleNF = d_ikReturn['mRPHandle']

            mIKHandle.parent = mIKControl.mNode  #handle to control
            for mObj in ml_distHandlesNF[:-1]:
                mObj.parent = mRoot
            ml_distHandlesNF[-1].parent = mIKControl.mNode  #handle to control
            #ml_distHandlesNF[1].parent = mIKMid
            #ml_distHandlesNF[1].t = 0,0,0
            #ml_distHandlesNF[1].r = 0,0,0

            #>>> Fix our ik_handle twist at the end of all of the parenting
            IK.handle_fixTwist(mIKHandle,
                               self.d_orientation['str'][0])  #Fix the twist

            #mIKControl.masterGroup.p_parent = ml_ikFullChain[-2]

        ######mc.parentConstraint([mIKControl.mNode], ml_ikFrame[-1].mNode, maintainOffset = True)

        if mIKBaseControl:
            ml_ikFrame[0].parent = mIKBaseControl
        #if mIKBaseControl:
        #mc.pointConstraint(mIKBaseControl.mNode, ml_ikFrame[0].mNode,maintainOffset=True)

    except Exception, err:
        cgmGEN.cgmExceptCB(Exception, err, localDat=vars())
Ejemplo n.º 3
0
    def chain_create(self, objs = None,
                     fwd = None, up=None,
                     name = None,
                     upSetup = "guess",
                     extendStart = None,
                     extendEnd = True,
                     mNucleus=None,
                     upControl = None,
                     aimUpMode = None,
                     **kws):
        
        _str_func = 'chain_create'
        
        if not objs:
            _sel = mc.ls(sl=1)
            if _sel:objs = _sel
        
        ml = cgmMeta.asMeta( objs, noneValid = True )
        ml_baseTargets = copy.copy(ml)
        
        if not ml:
            return log.warning("No objects passed. Unable to chain_create")
            
        if not name:
            name = ml[-1].p_nameBase
                    
        _idx = self.get_nextIdx()
        

        #Make our sub group...
        mGrp = self.doCreateAt(setClass=1)
        mGrp.p_parent = self
        mGrp.rename("chain_{0}_grp".format(name))
        mGrp.dagLock()
        self.connectChildNode(mGrp.mNode,'chain_{0}'.format(_idx),'owner')
        
        
        #holders and dat...
        ml_targets = []
        ml_posLocs = []
        ml_aim_locs = []
        
        fwd = fwd or self.fwd
        up = up or self.up
        upSetup = upSetup or self.upSetup
        extendStart = extendStart or self.extendStart
        extendEnd = extendEnd or self.extendEnd
        upControl = upControl or self.upControl
        aimUpMode = aimUpMode or self.aimUpMode
        
        #fwdAxis = simpleAxis(fwd)
        #upAxis = simpleAxis(up)

        fwdAxis = TRANS.closestAxisTowardObj_get(ml[0], ml[1])
        upAxis = TRANS.crossAxis_get(fwdAxis)

        mGrp.doStore('fwd', fwdAxis.p_string)
        mGrp.doStore('up', upAxis.p_string)

        #Curve positions...
        l_pos = []
        
        if upSetup == 'manual':
            if len(ml) < 2:
                log.debug(cgmGEN.logString_msg(_str_func, 'Single count. Adding extra handle.'))
                mLoc = ml[0].doLoc()
                mLoc.rename("chain_{0}_end_loc".format(name))
                _size = DIST.get_bb_size(ml[0],True,'max')
                mLoc.p_position = ml[0].getPositionByAxisDistance(fwdAxis.p_string,_size)
                ml.append(mLoc)
                mLoc.p_parent = mGrp
            
            for obj in ml:
                l_pos.append(obj.p_position)
                
                
            _v_baseDist = DIST.get_distance_between_points(l_pos[-1],l_pos[-2])
            _v_baseDist = MATHUTILS.Clamp(_v_baseDist, .5,None)

            _p_baseExtend = DIST.get_pos_by_axis_dist(ml[-1],
                                                      fwdAxis.p_string,
                                                      _v_baseDist)
            
            
            if extendEnd:
                log.debug(cgmGEN.logString_msg(_str_func, 'extendEnd...'))
                
                extendEnd = VALID.valueArg(extendEnd)
                
                if issubclass(type(extendEnd),bool):#VALID.boolArg(extendEnd):
                    log.debug(cgmGEN.logString_msg(_str_func, 'extendEnd | guess'))
                    l_pos.append(_p_baseExtend)
                elif extendEnd:
                    log.debug(cgmGEN.logString_msg(_str_func, 'extendEnd | {0}'.format(extendEnd)))
                    
                    l_pos.append( DIST.get_pos_by_axis_dist(ml[-1],
                                                            fwdAxis.p_string,
                                                            extendEnd ))                            
            else:
                l_pos.append( _p_baseExtend)
        
            if extendStart:
                f_extendStart = VALID.valueArg(extendStart)
                if f_extendStart:
                    l_pos.insert(0, DIST.get_pos_by_axis_dist(ml[0],
                                                              fwdAxis.inverse.p_string,
                                                              f_extendStart ))
                    
        else:
            log.debug(cgmGEN.logString_msg(_str_func, 'Resolving aim'))
            if len(ml) < 2:
                return log.error(cgmGEN.logString_msg(_str_func, 'Single count. Must use manual upSetup and aim/up args'))
            
            for obj in ml:
                l_pos.append(obj.p_position)
            
            _vecEnd = MATHUTILS.get_vector_of_two_points(l_pos[-2],l_pos[-1])
            if extendEnd:
                log.debug(cgmGEN.logString_msg(_str_func, 'extendEnd...'))
                
                extendEnd = VALID.valueArg(extendEnd)
                
                if issubclass(type(extendEnd),bool):#VALID.boolArg(extendEnd):
                    log.debug(cgmGEN.logString_msg(_str_func, 'extendEnd | guess'))
                    
                    l_pos.append( DIST.get_pos_by_vec_dist(l_pos[-1], _vecEnd,
                                                           (DIST.get_distance_between_points(l_pos[-2],l_pos[-1])/2)))
                elif extendEnd:
                    log.debug(cgmGEN.logString_msg(_str_func, 'extendStart | {0}'.format(extendEnd)))
                    
                    l_pos.append( DIST.get_pos_by_vec_dist(l_pos[-1], _vecEnd,
                                                           extendEnd))
            
            if extendStart:
                f_extendStart = VALID.valueArg(extendStart)
                if f_extendStart:
                    log.debug(cgmGEN.logString_msg(_str_func, 'extendStart...'))
                    
                    _vecStart = MATHUTILS.get_vector_of_two_points(l_pos[1],l_pos[0])
                    
                    l_pos.insert(0, DIST.get_pos_by_vec_dist(l_pos[0],
                                                             _vecStart,
                                                             f_extendStart))

        #pprint.pprint(l_pos)
        
        #for i,p in enumerate(l_pos):
        #    LOC.create(position=p,name='p_{0}'.format(i))
            
        crv = CORERIG.create_at(create='curve',l_pos= l_pos, baseName = name)
        mInCrv = cgmMeta.asMeta(crv)
        mInCrv.rename("{0}_inCrv".format(name))
        mGrp.connectChildNode(mInCrv.mNode,'mInCrv')
        mc.select(cl=1)

        # make the dynamic setup
        log.debug(cgmGEN.logString_sub(_str_func,'dyn setup'))
        b_existing = False
        b_existing_nucleus = False
        
        mHairSys = self.getMessageAsMeta('mHairSysShape')
        if mHairSys:
            mHairSysDag = mHairSys.getTransform(asMeta=1)
            log.info(cgmGEN.logString_msg(_str_func,'Using existing system: {0}'.format(mHairSys.mNode)))
            mc.select(mHairSysDag.mNode, add=True)
            b_existing = True
            
        if self.useExistingNucleus or mNucleus:
            mNucleus = self.get_nucleus(mNucleus)
            if mNucleus:
                #mc.select(mNucleus.mNode,add=1)
                b_existing_nucleus = True
                log.info(cgmGEN.logString_msg(_str_func,'Using existing nucleus: {0}'.format(mNucleus.mNode)))
                self.connectChildNode(mNucleus.mNode,'mNucleus')
        
        mc.select(mInCrv.mNode,add=True)
        mel.eval('makeCurvesDynamic 2 { "0", "0", "1", "1", "0" }')

        # get relevant nodes
        follicle = mc.listRelatives(mInCrv.mNode,parent=True)[0]
        mFollicle = cgmMeta.asMeta(follicle)
        mFollicle.rename("{0}_foll".format(name))
        parent = mFollicle.getParent(asMeta=1)
        mFollicle.p_parent = mGrp
        mFollicleShape = mFollicle.getShapes(1)[0]
        mc.delete(parent.mNode)
        
        _follicle = mFollicle.mNode
        mGrp.connectChildNode(mFollicle.mNode,'mFollicle','group')
        
        follicleShape = mFollicleShape.mNode#mc.listRelatives(mFollicle.mNode, shapes=True)[0]
        _hairSystem = mc.listRelatives( mc.listConnections('%s.currentPosition' % follicleShape)[0],
                                        shapes=True)[0]
        if not b_existing:
            mHairSys = cgmMeta.asMeta(_hairSystem)
            mHairSysDag = mHairSys.getTransform(asMeta=1)
            
            mHairSysDag.rename("{0}_hairSys".format(self.baseName))
            self.connectChildNode(mHairSysDag.mNode,'mHairSysDag','owner')
            self.connectChildNode(mHairSys.mNode,'mHairSysShape','owner')
            
            mHairSysDag.p_parent = self
            _hairSystem = mHairSys.mNode
            
        outCurve = mc.listConnections('%s.outCurve' % _follicle)[0]
        mCrv = cgmMeta.asMeta(outCurve)
        parent = mCrv.getParent(asMeta=1)

        outCurveShape = mc.listRelatives(mCrv.mNode, shapes=True)[0]
        mCrv.p_parent = mGrp.mNode
        
        mc.delete(parent.mNode)
        _nucleus = mc.listConnections( '%s.currentState' % mHairSys.mNode )[0]
        
        if not b_existing_nucleus:
            mNucleus = cgmMeta.asMeta(_nucleus)
            mNucleus.rename("cgmDynFK_nucleus")            
            #self.connectChildNode(mNucleus.mNode,'mNucleus','owner')
            self.connectChildNode(mNucleus.mNode,'mNucleus')
            
            if self.startFrame is not None:
                mNucleus.startFrame = self.startFrame
        else:
            #Because maya is crappy we gotta manually wire the existing nucleus
            ##startFrame out to startFrame in
            ##outputObjects[x] - nextState
            ##shape.currentState>inputActive[x]
            ##shape.startState>inputActiveStart[x]
            if cgmMeta.asMeta(_nucleus).mNode != mNucleus.mNode:
                mc.delete(_nucleus)

            _useNucleus = mNucleus.mNode

            """
            _useIdx = ATTR.get_nextCompoundIndex(mNucleus.mNode,'outputObjects')
            log.info("useIdx: {0}".format(_useIdx))
            ATTR.connect('{0}.outputObjects[{1}]'.format(_useNucleus,_useIdx),'{0}.nextState'.format(_hairSystem))
            ATTR.connect('{0}.currentState'.format(_hairSystem),'{0}.inputActive[{1}]'.format(_useNucleus,_useIdx))
            ATTR.connect('{0}.startState'.format(_hairSystem),'{0}.inputActiveStart[{1}]'.format(_useNucleus,_useIdx))"""            
            
            
        mParent = ml[0].getParent(asMeta=1)
        if not mParent:
            mParent = ml[0].doGroup(1,1,
                                    asMeta=True,
                                    typeModifier = 'dynFKParent',
                                    setClass='cgmObject')
        #else:
            #mParent.getParent(asMeta=1)
        
        mGrp.connectChildNode(mCrv.mNode,'mOutCrv','group')

        #self.follicles.append(follicle)
        #self.outCurves.append(outCurve)
        
        # set default properties
        mFollicleShape.pointLock = 1
        #mc.setAttr( '%s.pointLock' % follicleShape, 1 )
        mc.parentConstraint(ml[0].getParent(), _follicle, mo=True)
        
        # create locators on objects
        locators = []
        prs = []
        
        ml_locs = []
        ml_aims = []
        ml_prts = []
        
        _upVector = None
        if upSetup == 'guess':
            log.debug(cgmGEN.logString_msg(_str_func, 'Resolving up/aim'))
            poci_base = CURVES.create_pointOnInfoNode(mInCrv.mNode,1)
            mPoci_base = cgmMeta.asMeta(poci_base)
            
            _upVector = mPoci_base.normalizedNormal
            log.debug(cgmGEN.logString_msg(_str_func, "upVector: {0}".format(_upVector)))        
        
        
        #Let's make an up object as the parent of the root isn't good enough
        mUp = ml[0].doCreateAt(setClass=1)
        mUp.rename("chain_{0}_up".format(name))
        mUp.p_parent = mGrp
        
        if _upVector:
            SNAP.aim_atPoint(mUp.mNode,
                             DIST.get_pos_by_vec_dist(mUp.p_position,
                                                      _upVector,
                                                      10),aimAxis='y+',upAxis='z+')
        
        if upControl:
            log.debug(cgmGEN.logString_msg(_str_func,'upControl'))
            if len(ml_baseTargets)>1:
                sizeControl = DIST.get_distance_between_targets([mObj.mNode for mObj in ml_baseTargets],True)
            else:
                sizeControl = DIST.get_bb_size(ml[0],True,'max')
                
            crv = CURVES.create_controlCurve(mUp.mNode,'arrowSingle', size= sizeControl, direction = 'y+')
            CORERIG.shapeParent_in_place(mUp.mNode, crv, False)
            mUpGroup = mUp.doGroup(True,True,
                                   asMeta=True,
                                   typeModifier = 'master',
                                   setClass='cgmObject')
            
            mc.parentConstraint(ml[0].getParent(), mUpGroup.mNode, mo=True)
            
            
        else:
            mc.parentConstraint(ml[0].getParent(), mUp.mNode, mo=True)
            
        
        # create control joint chain
        mc.select(cl=True)
        chain = []
        for obj in ml:
            if len(chain) > 0:
                mc.select(chain[-1])
            jnt = mc.joint(name='%s_%s_jnt' % (name, obj.p_nameBase))
            SNAP.matchTarget_set(jnt, obj.mNode)
            mObj = cgmMeta.asMeta(jnt)
            mObj.doSnapTo(mObj.getMessageAsMeta('cgmMatchTarget'))

            chain.append(jnt)

        mc.parent(chain[0], _follicle)
        mInCrv.p_parent = mGrp

        mc.bindSkin(mInCrv.mNode, chain[0], ts=True)


        log.debug(cgmGEN.logString_msg(_str_func,'aimUpMode: {0}'.format(aimUpMode)))
        
        
        for i, mObj in enumerate(ml):
            if not i:
                mUpUse = mUp
            else:
                mUpUse = ml_locs[-1]
                
            mLoc = cgmMeta.asMeta( LOC.create(mObj.getNameLong()) )
            loc = mLoc.mNode
            ml_locs.append(mLoc)
            #loc = LOC.create(mObj.getNameLong())
            
            mAim = mLoc.doGroup(False,False,
                                 asMeta=True,
                                 typeModifier = 'aim',
                                 setClass='cgmObject')
            ml_aims.append(mAim)
            #aimNull = mc.group(em=True)
            #aimNull = mc.rename('%s_aim' % mObj.getShortName())
            
            poc = CURVES.create_pointOnInfoNode(outCurveShape)
#mc.createNode('pointOnCurveInfo', name='%s_pos' % loc)
            mPoci_obj = cgmMeta.asMeta(poc)
            mPoci_obj.rename('%s_pos' % loc)
            pocAim = CURVES.create_pointOnInfoNode(outCurveShape)
            #mc.createNode('pointOnCurveInfo', name='%s_aim' % loc)
            
            pr = CURVES.getUParamOnCurve(loc, outCurve)
            mPoci_obj.parameter = pr
            
            #mc.connectAttr( '%s.worldSpace[0]' % outCurveShape, '%s.inputCurve' % poc, f=True )
            #mc.connectAttr( '%s.worldSpace[0]' % outCurveShape, '%s.inputCurve' % pocAim, f=True )

            #mc.setAttr( '%s.parameter' % poc, pr )
            
            if i < len(ml)-1:
                nextpr = CURVES.getUParamOnCurve(ml[i+1], outCurve)
                mc.setAttr('%s.parameter' % pocAim, (nextpr))# + pr))# * .5)
            else:
                if extendStart:
                    mc.setAttr( '%s.parameter' % pocAim, len(ml)+1 )                    
                else:
                    mc.setAttr( '%s.parameter' % pocAim, len(ml) )
                    
                    
            
            mLocParent = mLoc.doGroup(False,False,
                                      asMeta=True,
                                      typeModifier = 'pos',
                                      setClass='cgmObject')
            ml_prts.append(mLocParent)
            #locParent = mc.group(em=True)
            #locParent = mc.rename( '%s_pos' % mObj.getShortName() )

            mc.connectAttr( '%s.position' % mPoci_obj.mNode, '%s.translate' % mLocParent.mNode)
            mc.connectAttr( '%s.position' % pocAim, '%s.translate' % mAim.mNode)
            
            
            
            if aimUpMode == 'master':
                aimConstraint = mc.aimConstraint( mAim.mNode,
                                                  mLocParent.mNode,
                                                  aimVector=fwdAxis.p_vector,
                                                  upVector = upAxis.p_vector,
                                                  worldUpType = "objectrotation",
                                                  worldUpVector = upAxis.p_vector,
                                                  worldUpObject = mUp.mNode )
            elif aimUpMode == 'orientToMaster':
                mc.orientConstraint( mUp.mNode,
                                     mLocParent.mNode,
                                     maintainOffset = 1)
                
            elif aimUpMode == 'sequential':
                aimConstraint = mc.aimConstraint( mAim.mNode,
                                                  mLocParent.mNode,
                                                  aimVector=fwdAxis.p_vector,
                                                  upVector = upAxis.p_vector,
                                                  worldUpType = "objectrotation",
                                                  worldUpVector = upAxis.p_vector,
                                                  worldUpObject = mUpUse.mNode )                
            elif aimUpMode == 'joint':
                aimConstraint = mc.aimConstraint( mAim.mNode,
                                                  mLocParent.mNode,
                                                  aimVector=fwdAxis.p_vector,
                                                  upVector = upAxis.p_vector,
                                                  worldUpType = "objectrotation",
                                                  worldUpVector = upAxis.p_vector,
                                                  worldUpObject = chain[i] )  
            elif aimUpMode == 'curveNormal':
                mUpLoc = mLoc.doGroup(False,False,
                                      asMeta=True,
                                      typeModifier = 'up',
                                      setClass='cgmObject')
                mUpLoc.p_parent = mLocParent
                
                aimConstraint = mc.aimConstraint( mAim.mNode,
                                                  mLocParent.mNode,
                                                  aimVector=fwdAxis.p_vector,
                                                  upVector = upAxis.p_vector,
                                                  worldUpType = "object")
                
                mPlusMinusAverage = cgmMeta.cgmNode(name="{0}_pma".format(mObj.p_nameBase),
                                                    nodeType = 'plusMinusAverage')
                mPlusMinusAverage.operation = 3
                
                mPoci_obj.doConnectOut('position','{0}.input3D[0]'.format(mPlusMinusAverage.mNode))
                mPoci_obj.doConnectOut('normalizedNormal','{0}.input3D[1]'.format(mPlusMinusAverage.mNode))
                mUpLoc.doConnectIn('translate','{0}.output3D'.format(mPlusMinusAverage.mNode))

            
            
            mLoc.p_parent = mLocParent
            mAim.p_parent = mGrp
            mLocParent.p_parent = mGrp
            
            #mc.parent(loc, locParent)
        
        mCrv.rename("{0}_outCrv".format(name))
        mCrvParent = mCrv.getParent(asMeta=1)
        mCrvParent.p_parent = mGrp
        
        mGrp.msgList_connect('mLocs',ml_locs)
        mGrp.msgList_connect('mAims',ml_aims)
        mGrp.msgList_connect('mParents',ml_prts)
        mGrp.msgList_connect('mTargets',ml)
        mGrp.msgList_connect('mBaseTargets',ml_baseTargets)
        mGrp.msgList_connect('mObjJointChain',chain)
        mGrp.doStore('cgmName', name)

        mNucleus.doConnectOut('startFrame',"{0}.startFrame".format(mHairSys.mNode))