def get_planeIntersect(planeSource=None,
                       target=None,
                       planeAxis='z+',
                       objAxis='z+',
                       mark=False):
    _str_func = 'get_planeIntersect'

    if target:
        mTarget = cgmMeta.asMeta(target)
    else:
        mTarget = cgmMeta.asMeta(mc.ls(sl=1))
        if not mTarget:
            return log.error(cgmGEN.logString_msg(_str_func, 'No Target'))
        mTarget = mTarget[0]

    mObj = cgmMeta.asMeta(planeSource)

    planePoint = VALID.euclidVector3Arg(mObj.p_position)
    planeNormal = VALID.euclidVector3Arg(mObj.getAxisVector(planeAxis))

    rayPoint = VALID.euclidVector3Arg(mTarget.p_position)
    rayDirection = VALID.euclidVector3Arg(mTarget.getAxisVector(objAxis))

    plane = EUCLID.Plane(
        EUCLID.Point3(planePoint.x, planePoint.y, planePoint.z),
        EUCLID.Point3(planeNormal.x, planeNormal.y, planeNormal.z))
    pos = plane.intersect(
        EUCLID.Line3(
            EUCLID.Point3(rayPoint.x, rayPoint.y, rayPoint.z),
            EUCLID.Vector3(rayDirection.x, rayDirection.y, rayDirection.z)))

    if mark:
        LOC.create(position=pos, name='pewpew_planeIntersect')

    return pos
Exemple #2
0
    def update(self, deltaTime=.04):
        #log.info("Updating")

        self.dir = self._bakedLoc.getTransformDirection(
            self.aimFwd.p_vector) * self.objectScale

        wantedTargetPos = (
            (VALID.euclidVector3Arg(self.obj.p_position) + self.dir) - self.obj
            .p_position).normalized() * self.objectScale + self.obj.p_position
        wantedUp = self._bakedLoc.getTransformDirection(
            self.aimUp.p_vector) * self.objectScale

        self.positionForce = self.positionForce + (
            (wantedTargetPos - self.aimTargetPos) * self.springForce)
        self.positionForce = self.positionForce * (1.0 - self.damp)

        self.angularForce = self.angularForce + (
            (wantedUp - self.upTargetPos) * self.angularSpringForce)
        self.angularForce = self.angularForce * (1.0 - self.angularDamp)

        self.aimTargetPos = self.aimTargetPos + (self.positionForce *
                                                 deltaTime)
        self.upTargetPos = self.upTargetPos + (self.angularForce * deltaTime)

        SNAP.aim_atPoint(obj=self.obj.mNode,
                         mode='matrix',
                         position=self.aimTargetPos,
                         aimAxis=self.aimFwd.p_string,
                         upAxis=self.aimUp.p_string,
                         vectorUp=self.upTargetPos.normalized())

        if self.debug:
            if not self._debugLoc:
                self._debugLoc = cgmMeta.asMeta(LOC.create(name='debug_loc'))
            self._debugLoc.p_position = self.aimTargetPos
            mc.setKeyframe(self._debugLoc.mNode, at='translate')

            if not self._wantedUpLoc:
                self._wantedUpLoc = cgmMeta.asMeta(
                    LOC.create(name='wanted_up_loc'))
            self._wantedUpLoc.p_position = self.obj.p_position + self.upTargetPos
            mc.setKeyframe(self._wantedUpLoc.mNode, at='translate')

            if not self._wantedPosLoc:
                self._wantedPosLoc = cgmMeta.asMeta(
                    LOC.create(name='wanted_pos_loc'))
            self._wantedPosLoc.p_position = wantedTargetPos
            mc.setKeyframe(self._wantedPosLoc.mNode, at='translate')
    def bakeTempLocator(self, startTime=None, endTime=None):
        _str_func = 'PostBake.bakeTempLocator'

        if startTime is None:
            startTime = self.startTime
        if endTime is None:
            endTime = self.endTime

        ct = mc.currentTime(q=True)

        self._bakedLoc = cgmMeta.asMeta(LOC.create(name='bakeLoc'))
        self._bakedLoc.rotateOrder = self.obj.rotateOrder

        SNAP.matchTarget_set(self._bakedLoc.mNode, self.obj.mNode)

        _len = endTime - startTime
        _progressBar = cgmUI.doStartMayaProgressBar(_len, "Processing...")

        _obj = VALID.objString(self._bakedLoc.mNode, noneValid=False)
        _target = VALID.objString(
            self.obj.mNode, noneValid=False
        )  #ATTR.get_message(_obj, 'cgmMatchTarget','cgmMatchDat',0)

        ak = mc.autoKeyframe(q=True, state=True)
        mc.autoKeyframe(state=False)
        mc.refresh(su=True)

        completed = True

        for i in range(startTime, endTime + 1):
            mc.currentTime(i)
            SNAP.go(_obj, _target, True, True, pivot='rp')
            mc.setKeyframe(_obj, at=['translate', 'rotate'])

            if _progressBar:
                if mc.progressBar(_progressBar, query=True, isCancelled=True):
                    log.warning('Bake cancelled!')
                    completed = False
                    break

                mc.progressBar(_progressBar,
                               edit=True,
                               status=("{0} On frame {1}".format(_str_func,
                                                                 i)),
                               step=1,
                               maxValue=_len)

        mc.refresh(su=False)
        mc.autoKeyframe(state=ak)

        cgmUI.doEndMayaProgressBar(_progressBar)

        mc.currentTime(ct)

        return completed
def get_planeIntersect(self,
                       target=None,
                       planeAxis='z+',
                       objAxis='z+',
                       mark=True):
    _short = self.mNode
    _str_func = '[{0}] get_planeIntersect'.format(_short)

    if target:
        mTarget = cgmMeta.asMeta(target)
    else:
        mTarget = cgmMeta.asMeta(mc.ls(sl=1))
        if not mTarget:
            return log.error(cgmGEN.logString_msg(_str_func, 'No Target'))
        mTarget = mTarget[0]

    if not self.atUtils('is_rigged'):
        mObj = self
    else:
        mObj = self.moduleTarget.eyeLook

    planePoint = VALID.euclidVector3Arg(mObj.p_position)
    planeNormal = VALID.euclidVector3Arg(mObj.getAxisVector(planeAxis))

    rayPoint = VALID.euclidVector3Arg(mTarget.p_position)
    rayDirection = VALID.euclidVector3Arg(mTarget.getAxisVector(objAxis))

    plane = EUCLID.Plane(
        EUCLID.Point3(planePoint.x, planePoint.y, planePoint.z),
        EUCLID.Point3(planeNormal.x, planeNormal.y, planeNormal.z))
    pos = plane.intersect(
        EUCLID.Line3(
            EUCLID.Point3(rayPoint.x, rayPoint.y, rayPoint.z),
            EUCLID.Vector3(rayDirection.x, rayDirection.y, rayDirection.z)))

    if mark:
        LOC.create(position=pos, name='pewpew')

    return pos
Exemple #5
0
    def bakeLoc(self, obj=None):
        if obj is None:
            obj = self.obj

        self._bakedLoc = cgmMeta.asMeta(
            LOC.create(name='{0}_bakeLoc'.format(self.obj.mNode)))
        SNAP.matchTarget_set(self._bakedLoc.mNode, obj.mNode)

        ct = mc.currentTime(q=True)

        SNAP.matchTarget_snap(self._bakedLoc.mNode)

        mc.currentTime(ct)
    def update(self, deltaTime=.04):
        #dir = self.obj.getTransformDirection(self.aimFwd.p_vector)

        self.dir = self._bakedLoc.getTransformDirection(
            self.aimFwd.p_vector) * self.objectScale

        if self.translate:
            self.obj.p_position = MATH.Vector3.Lerp(
                VALID.euclidVector3Arg(self.previousPosition),
                VALID.euclidVector3Arg(self._bakedLoc.p_position),
                deltaTime * self.damp)

        if self.rotate:
            wantedTargetPos = (
                (VALID.euclidVector3Arg(self.obj.p_position) + self.dir) -
                self.obj.p_position
            ).normalized() * self.objectScale + self.obj.p_position

            self.lastUp = MATH.Vector3.Lerp(
                self.lastUp,
                self._bakedLoc.getTransformDirection(self.aimUp.p_vector),
                min(deltaTime * self.damp, 1.0)).normalized()

            self.aimTargetPos = (
                MATH.Vector3.Lerp(self.aimTargetPos, wantedTargetPos,
                                  deltaTime * self.damp) - self.obj.p_position
            ).normalized() * self.objectScale + self.obj.p_position
            self.upTargetPos = (
                MATH.Vector3.Lerp(self.aimTargetPos, wantedTargetPos,
                                  deltaTime * self.damp) - self.obj.p_position
            ).normalized() * self.objectScale + self.obj.p_position

            self.lastFwd = MATH.Vector3.Lerp(
                self.lastFwd,
                self._bakedLoc.getTransformDirection(self.aimFwd.p_vector),
                min(deltaTime * self.damp, 1.0)).normalized()

            SNAP.aim_atPoint(obj=self.obj.mNode,
                             mode='matrix',
                             position=self.aimTargetPos,
                             aimAxis=self.aimFwd.p_string,
                             upAxis=self.aimUp.p_string,
                             vectorUp=self.lastUp)

        if self.debug:
            if not self._debugLoc:
                self._debugLoc = cgmMeta.asMeta(LOC.create(name='debug_loc'))
            self._debugLoc.p_position = self.aimTargetPos
            mc.setKeyframe(self._debugLoc.mNode, at='translate')
Exemple #7
0
    def saveKeys(self, attrs, replaceStored=True, removeOld=True):
        if self.hasSavedKeys and replaceStored:
            mc.delete(self._animStoreLoc)

        func = mc.copyKey
        if removeOld:
            func = mc.cutKey
        self.hasSavedKeys = func(
            self.obj.mNode,
            at=attrs,
            time=(mc.currentTime(q=True),
                  mc.findKeyframe(self.obj.mNode, which='last') + 1))
        if self.hasSavedKeys:
            self._animStoreLoc = LOC.create(name='animStoreLoc')
            mc.pasteKey(self._animStoreLoc, at=attrs, o='replaceCompletely')
Exemple #8
0
    def onPress(self, clickDict):
        LiveRecord.onPress(self, clickDict)

        self.validateData()

        if self._mb == 1:
            self.offset = MOUSE.Point()
            mp = MOUSE.getMousePosition()
            self.offset.x = int(clickDict['anchorPoint'][0]) - mp['x']
            self.offset.y = int(clickDict['anchorPoint'][1]) - mp['y']

            self._velocity = MATHUTILS.Vector3.zero()

            if not self._useCache:
                self.cacheData()

            if self.plane != 'custom':
                projectedPlanePos = self.projectOntoPlane(clickDict['vector'])
                for recordable in self.recordableObjs:
                    recordable.dataDict['objOffset'] = VALID.euclidVector3Arg(
                        recordable.obj.p_position) - projectedPlanePos
            else:
                for recordable in self.recordableObjs:
                    recordable.dataDict['objOffset'] = MATHUTILS.Vector3.zero()

            if self.debug:
                self._debugLoc = cgmMeta.asMeta(LOC.create(name='Debug_Loc'))

            self._debugPlane = makePlaneCurve()

            if self.clickAction.modifier != 'ctrl':
                ct = mc.currentTime(q=True)
                for recordable in self.recordableObjs:
                    mc.cutKey(recordable.obj.mNode,
                              at=self.keyableAttrs,
                              time=(ct,
                                    mc.findKeyframe(recordable.obj.mNode,
                                                    which='last') + 1))

            self.recordableObjs[0].restoreBakedLocFromData(
                mc.currentTime(q=True))

            self.record()

        else:
            self.cacheData()
Exemple #9
0
                        log.debug("Max distance exceeded. Using alternative")
                        hit = DIST.get_pos_by_axis_dist(
                            mi_loc.mNode, aimAxis, maxDistance)

                #d_castReturn = RayCast.findMeshIntersectionFromObjectAxis(mesh, mi_loc.mNode, axis=aimAxis, #maxDistance = maxDistance, firstHit=False) or {}
            # d_hitReturnFromValue[rotateValue] = d_castReturn
            #if closestInRange:
            #hit = d_castReturn.get('near') or False
            #else:
            #hit = d_castReturn.get('far') or False
            #if not hit:log.info("{0} -- {1}".format(rotateValue,d_castReturn))
                l_hits.append(hit)
                d_processedHitFromValue[rotateValue] = hit
                l_pos.append(hit)
                if markHits:
                    LOC.create(position=hit,
                               name="cast_rot{0}_loc".format(rotateValue))

                d_rawHitFromValue[rotateValue] = hit

            except Exception, err:
                cgmGEN.cgmException(Exception, err)

        mc.delete(mi_loc.getParents()[-1])  #delete top group
        log.debug("pos list: %s" % l_pos)
        #guiFactory.doCloseProgressWindow()

    except Exception, error:
        pprint.pprint(vars())
        raise ValueError, "Cast fail | {0}".format(error)
    try:
        if not l_pos:
    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)
    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))