Scale selected objects based on distance from a locator

/*
scaleObjfromLocator.mel v1.0                                               
                                                                       
Author: Nathan Lang                                                   
web: natelang3d.com

Install: Copy this file into your maya scripts folder

------Copy below code into a mel shelf button------

scaleFromLocator();

------------------------------------------------------
                                                        
Use: 
Select all objects you wish to be effected by scale tool.
This will make a real time tool used for animating the
scale attribute on selected objects.
*/                                                                       


global proc scaleFromLocator()
{
    string $objToScale[] = `ls -selection`;
    
    /*-------scale controller-------*/ 
    //create locator and 2 circles around it
    string $controlerName[] = `spaceLocator -position 0 0 0 -name scaleControl`;
    //add radius attribute to object
    addAttr -ln "radius" -attributeType double -defaultValue 1 -keyable true;
    //add radius multiplier attribute
    addAttr -ln "radMultiply" -attributeType double -min 0 -max 10 -defaultValue 1 -keyable true;
    //add Zero size threshold for scaled objects
    addAttr -ln "sizeThreshold" -attributeType double -min 0 -max 1 -defaultValue .1 -keyable true;
    connectAttr ($controlerName[0]+".radius") ($controlerName[0]+".scaleX");
    connectAttr ($controlerName[0]+".radius") ($controlerName[0]+".scaleY");
    connectAttr ($controlerName[0]+".radius") ($controlerName[0]+".scaleZ");
    setAttr -keyable false -channelBox false ($controlerName[0] + ".sx");
    setAttr -keyable false -channelBox false ($controlerName[0] + ".sy");
    setAttr -keyable false -channelBox false ($controlerName[0] + ".sz");
    
    //Outer Radius Visualization
    circle -constructionHistory on -object on -normal 0 0 0 -radius 1 -name vertCircle;
    circle -constructionHistory on -object on -normal 0 90 0 -radius 1 -name horizCircle;
    circle -constructionHistory on -object on -normal 45 0 0 -radius 1 -name perpCircle;
    parent horizCircle scaleControl;
    parent vertCircle scaleControl;
    parent perpCircle scaleControl;
        //make circles unselectable and uneditable
        setAttr "vertCircleShape.overrideEnabled" 1;
        setAttr "vertCircleShape.overrideDisplayType" 2;
        
        setAttr "horizCircleShape.overrideEnabled" 1;
        setAttr "horizCircleShape.overrideDisplayType" 2;
        
        setAttr "perpCircleShape.overrideEnabled" 1;
        setAttr "perpCircleShape.overrideDisplayType" 2;
    
    //make empty group to house distanceNodes
    string $distanceGrpName = ($controlerName[0] + "_distanceNodes");
    group -empty -name $distanceGrpName;
    parent $distanceGrpName scaleControl;
     
    for ($obj in $objToScale)
    {
        float $disStrtPtX = `getAttr scaleControl.translateX`;
        float $disStrtPtY = `getAttr scaleControl.translateY`;
        float $disStrtPtZ = `getAttr scaleControl.translateZ`;
        
        float $disEndPtX = `getAttr ($obj + ".translateX")`; 
        float $disEndPtY = `getAttr ($obj + ".translateY")`;
        float $disEndPtZ = `getAttr ($obj + ".translateZ")`;
        
        //create distance measurement between locator and object
        string $locName = ($obj + "Locator");
        spaceLocator -name $locName -position $disEndPtX $disEndPtY $disEndPtZ;
        hide $locName;
        string $hideDistance = `distanceDimension -sp $disStrtPtX $disStrtPtY $disStrtPtZ -ep $disEndPtX $disEndPtY $disEndPtZ`;
        string $nonShapeName[] = `listRelatives -parent $hideDistance`;
        string $newDistanceName = ($obj + $nonShapeName[0]);
        rename $nonShapeName[0] $newDistanceName;
        hide $newDistanceName;
        parent $newDistanceName $distanceGrpName;
        parent $locName $obj;
        
        //constrain the control node and objects
        
        //utility nodes
        string $condName = ($locName + "condition");
        shadingNode -asUtility condition -name $condName;
        setAttr ($condName + ".operation") 5;
        string $multDivName = ($locName + "multDiv");
        shadingNode -asUtility multiplyDivide -name $multDivName;
        setAttr ($multDivName + ".operation") 2;
        string $subtractName = ($locName + "subtract");
        shadingNode -asUtility plusMinusAverage -name $subtractName;
        setAttr ($subtractName + ".operation") 2;
        string $radMultName = ($locName + "radMult");
        shadingNode -asUtility multiplyDivide -name $radMultName;
        setAttr ($radMultName + ".operation") 3;
        string $minSizeCondName = ($locName + "minSizeCondition");
        shadingNode -asUtility condition -name $minSizeCondName;
        setAttr ($minSizeCondName + ".operation") 5;
        
        /*-------PlusMinusAverage-------*/
        //connect distance to plusMinusAverage 3Dx
        connectAttr ($obj + $hideDistance + ".distance") ($subtractName + ".input3D[0].input3Dx");
        //connect locatorControl to plusMinusAverage 3Dx
        connectAttr ($controlerName[0]+".radius") ($subtractName + ".input3D[1].input3Dx");
        
        /*-------MultiplyDivide-------*/
        //connect distance to multiplyDivide
        connectAttr ($obj + $hideDistance + ".distance") ($multDivName + ".input1X");
        //connect locatorControl to multiplyDivide
        connectAttr ($controlerName[0]+".radius") ($multDivName + ".input2X");
        
        /*-------Condition-------*/
        //connect multiplier2 to condition
        connectAttr ($radMultName + ".outputX") ($condName + ".colorIfTrueR");
        //connect plusMinusAverage to condition
        connectAttr ($subtractName + ".output3Dx") ($condName + ".firstTerm");
        
        /*-------Multiplier2-------*/
        //connect multiplyDivide to Multiplier2
        connectAttr ($multDivName + ".outputX") ($radMultName + ".input1X");
        //connect scaleController multiplier attribute to input2X
        connectAttr ($controlerName[0] + ".radMultiply") ($radMultName + ".input2X");
        
        /*-------Condition2-------*/
        //connect output 1st condition to input 1 on 2nd condition
        connectAttr ($condName + ".outColorR") ($minSizeCondName + ".firstTerm");
        //connect min size threshold to 2nd condition input
        connectAttr ($controlerName[0] + ".sizeThreshold") ($minSizeCondName + ".secondTerm");
        //connect condition 1 out value to condition 2 false output
        connectAttr ($condName + ".outColorR") ($minSizeCondName + ".colorIfFalseR");
        
        //connect condition to objScale
        connectAttr ($minSizeCondName + ".outColorR") ($obj + ".scaleX");
        connectAttr ($minSizeCondName + ".outColorR") ($obj + ".scaleY");
        connectAttr ($minSizeCondName + ".outColorR") ($obj + ".scaleZ");
    }
    delete -constructionHistory $controlerName[0];
}