1 2 Previous Next 40 Replies Latest reply on Jan 26, 2018 5:26 PM by Jodi_Frye

    script for distributing smart object instances along path for testing

    c.pfaffenbichler Level 9

      If someone wants to test this Script please let me know if you notice issues.

      It is supposed to distribute the selected Layers along the selected Path as Smart Object instances.

      Not that much use for that, I guess, but what the hey …

      pathLayersDistrTestScr.png

      // distribute selected layers as smart object instances along selected path, if no path is selected use the first one;
      // additional points are calculated along the path to use for positioning the instances;
      // 2015, use it at your own risk;
      #target photoshop
      if (app.documents.length > 0) {
      var myDocument = app.activeDocument;
      if (myDocument.pathItems.length > 0) {
      // get id, center and half-dimensions of selected layers;
      var theLayers = smartifyAndGetSelectedLayersIdxEtc();
      // get selected path;
      var thePath = selectedPath ();
      if (thePath == undefined) {var thePath = myDocument.pathItems[0]};
      ////////////////////////////////////
      if (theLayers.length > 0) {
      var originalRulerUnits = app.preferences.rulerUnits;
      app.preferences.rulerUnits = Units.PIXELS;
      var originalResolution = myDocument.resolution;
      myDocument.resizeImage(undefined, undefined, 72, ResampleMethod.NONE);
      // create a layerset to hold the copies;
      var myLayerSet = myDocument.layerSets.add();
      myLayerSet.name = "copies on "+thePath.name;
      var theGroupIndex = getLayerIndex(myLayerSet)-1;
      // collect path info, array of points, angle, distance from last point;
      var thePath = getPointsOnPath2015a (myDocument, thePath);
      ////////////////////////////////////
      for (var m = 0; m < thePath.length; m++) {
        var theCounter = 0;
        var thisSubPath = thePath[m];
        var thisLayer = theNextInTheArray(theLayers, theCounter);
        var nextLayer = theNextInTheArray(theLayers, theCounter+1);
        var theDistanceCovered = 0;
        var theTargetLength = thisLayer[3];
      // perform on each sub path array;
        for (var n = 0; n < thisSubPath.length; n++) {
        theDistanceCovered = theDistanceCovered + Number(thisSubPath[n][2]);
      // if the length is met place instance at position of point with angle;
        if (theDistanceCovered >= theTargetLength) {
        theTargetLength = thisLayer[3] + nextLayer[3];
        duplicateMoveAndScale (myDocument, thisLayer[0], theGroupIndex, thisSubPath[n][1], thisSubPath[n][0][0]-thisLayer[1], thisSubPath[n][0][1]-thisLayer[2], 100, 100);
        theCounter++;
        var thisLayer = theNextInTheArray(theLayers, theCounter);
        var nextLayer = theNextInTheArray(theLayers, theCounter+1);
        theDistanceCovered = 0;
        }
        }
        };
      ////////////////////////////////////
      // reset;
      app.preferences.rulerUnits = originalRulerUnits;
      myDocument.resizeImage(undefined, undefined, originalResolution, ResampleMethod.NONE);
      };
      ////////////////////////////////////
      }
      };
      ////////////////////////////////////
      ////////////////////////////////////
      ////////////////////////////////////
      ////// based on code by mike hale and paul riggott //////
      function selectLayerByID(index,add){
      add = undefined ? add = false:add
      var ref = new ActionReference();
          ref.putIdentifier(charIDToTypeID("Lyr "), index);
          var desc = new ActionDescriptor();
          desc.putReference(charIDToTypeID("null"), ref );
             if(add) desc.putEnumerated( stringIDToTypeID( "selectionModifier" ), stringIDToTypeID( "selectionModifierType" ), stringIDToTypeID( "addToSelection" ) );
            desc.putBoolean( charIDToTypeID( "MkVs" ), false );
         try{
          executeAction(charIDToTypeID("slct"), desc, DialogModes.NO );
      }catch(e){
      alert(e.message);
      }
      };
      // by mike hale, via paul riggott;
      function selectLayerByIndex(index,add){
      // http://forums.adobe.com/message/1944754#1944754
      add = undefined ? add = false:add
      var ref = new ActionReference();
          ref.putIndex(charIDToTypeID("Lyr "), index);
          var desc = new ActionDescriptor();
          desc.putReference(charIDToTypeID("null"), ref );
             if(add) desc.putEnumerated( stringIDToTypeID( "selectionModifier" ), stringIDToTypeID( "selectionModifierType" ), stringIDToTypeID( "addToSelection" ) );
            desc.putBoolean( charIDToTypeID( "MkVs" ), false );
         try{
          executeAction(charIDToTypeID("slct"), desc, DialogModes.NO );
      }catch(e){
      alert(e.message);
      }
      };
      // by mike hale, via paul riggott;
      function getLayerIndex(theLayer){
      // http://forums.adobe.com/message/1944754#1944754
      app.activeDocument.activeLayer = theLayer;
      //Assumes activeDocument and activeLayer
          var ref = new ActionReference();
          ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
          d = executeActionGet(ref);
      return d.getInteger(stringIDToTypeID('itemIndex'));
      };
      // by mike hale, via paul riggott;
      function getLayerId(theLayer){
      // http://forums.adobe.com/message/1944754#1944754
      app.activeDocument.activeLayer = theLayer;
      //Assumes activeDocument and activeLayer
          var ref = new ActionReference();
          ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
          d = executeActionGet(ref);
      return d.getInteger(charIDToTypeID('LyrI'));
      };
      ////// get array of arrays of smart objects witrh index, center and half-dimensions //////
      function smartifyAndGetSelectedLayersIdxEtc(){
        var selectedLayers = new Array;
        var ref = new ActionReference();
        ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
        var desc = executeActionGet(ref);
        if( desc.hasKey( stringIDToTypeID( 'targetLayers' ) ) ){
        desc = desc.getList( stringIDToTypeID( 'targetLayers' ));
        var c = desc.count;
        var selectedLayers = new Array();
        for(var i=0;i<c;i++){
        try{
        activeDocument.backgroundLayer;
        selectedLayers.push(  desc.getReference( i ).getIndex() );
        }catch(e){
        selectedLayers.push(  desc.getReference( i ).getIndex()+1 );
        };
        }
        }else{
        var ref = new ActionReference();
        ref.putProperty( charIDToTypeID("Prpr") , charIDToTypeID( "ItmI" ));
        ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
        try{
        activeDocument.backgroundLayer;
        selectedLayers.push( executeActionGet(ref).getInteger(charIDToTypeID( "ItmI" ))-1);
        }catch(e){
        selectedLayers.push( executeActionGet(ref).getInteger(charIDToTypeID( "ItmI" )));
        };
        };
      ////////////////////////////////////
      var theArray = new Array;
      var theIDs = new Array;
      for (var m = 0; m < selectedLayers.length; m++) {
      var thisIndex = selectedLayers[m];
      var ref = new ActionReference();
      ref.putIndex( charIDToTypeID("Lyr "), thisIndex);
      var layerDesc = executeActionGet(ref);
      var thisID = layerDesc.getInteger(stringIDToTypeID("layerID"));
      var theBounds = layerDesc.getObjectValue(stringIDToTypeID("bounds"));
      var halfWidth = theBounds.getUnitDoubleValue(stringIDToTypeID("width")) / 2;
      var halfHeight = theBounds.getUnitDoubleValue(stringIDToTypeID("height")) / 2;
      var theX = theBounds.getUnitDoubleValue(stringIDToTypeID("left")) + halfWidth;
      var theY = theBounds.getUnitDoubleValue(stringIDToTypeID("top")) + halfHeight;
      theIDs.push ([thisID, theX, theY, halfWidth, halfHeight])
      };
      ////////////////////////////////////
      for (var n = 0; n < theIDs.length; n++) {
      if (hasSmartObject(theIDs[n][0]) == false) {
        try {
        selectLayerByID(theIDs[n][0], false);
        var id557 = charIDToTypeID( "slct" );
        var desc108 = new ActionDescriptor();
        var id558 = charIDToTypeID( "null" );
        var ref77 = new ActionReference();
        var id559 = charIDToTypeID( "Mn  " );
        var id560 = charIDToTypeID( "MnIt" );
        var id561 = stringIDToTypeID( "newPlacedLayer" );
        ref77.putEnumerated( id559, id560, id561 );
        desc108.putReference( id558, ref77 );
        executeAction( id557, desc108, DialogModes.NO );
        theArray.push([getLayerId(app.activeDocument.activeLayer), theIDs[n][1], theIDs[n][2], theIDs[n][3], theIDs[n][4]]);
        } catch (e) {}
        }
      else {theArray.push(theIDs[n])};
      };
      ////////////////////////////////////
      return theArray
      ////////////////////////////////////
      //return selectedLayers;
      };
      ////// smart object or not //////
      function hasSmartObject(idx){
      var ref = new ActionReference();
      ref.putProperty( charIDToTypeID("Prpr") , stringIDToTypeID( "smartObject" ));
      //ref.putIndex( charIDToTypeID( "Lyr " ), idx);
      ref.putIdentifier( charIDToTypeID( "Lyr " ), idx);
      var desc = executeActionGet(ref);
      if(desc.hasKey(stringIDToTypeID('smartObject'))) {return true}
      else {return false};
      };
      ////// determine selected path, updated 08.2011 //////
      function selectedPath () {
      try {
      var ref = new ActionReference();
      ref.putEnumerated( charIDToTypeID("Path"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
      var desc = executeActionGet(ref);
      var theName = desc.getString(charIDToTypeID("PthN"));
      return app.activeDocument.pathItems.getByName(theName)
      }
      catch (e) {
        return undefined
        }
      };
      ////// collect path info from actiondescriptor, smooth added //////
      function collectPathInfoFromDesc2012 (myDocument, thePath) {
      var originalRulerUnits = app.preferences.rulerUnits;
      app.preferences.rulerUnits = Units.POINTS;
      // based of functions from xbytor’s stdlib;
      var ref = new ActionReference();
      for (var l = 0; l < myDocument.pathItems.length; l++) {
        var thisPath = myDocument.pathItems[l];
        if (thisPath == thePath && thisPath.name == "Work Path") {
        ref.putProperty(cTID("Path"), cTID("WrPt"));
        };
        if (thisPath == thePath && thisPath.name != "Work Path" && thisPath.kind != PathKind.VECTORMASK) {
        ref.putIndex(cTID("Path"), l + 1);
        };
        if (thisPath == thePath && thisPath.kind == PathKind.VECTORMASK) {
              var idPath = charIDToTypeID( "Path" );
              var idPath = charIDToTypeID( "Path" );
              var idvectorMask = stringIDToTypeID( "vectorMask" );
              ref.putEnumerated( idPath, idPath, idvectorMask );
        };
        };
      var desc = app.executeActionGet(ref);
      var pname = desc.getString(cTID('PthN'));
      // create new array;
      var theArray = new Array;
      var pathComponents = desc.getObjectValue(cTID("PthC")).getList(sTID('pathComponents'));
      // for subpathitems;
      for (var m = 0; m < pathComponents.count; m++) {
        var listKey = pathComponents.getObjectValue(m).getList(sTID("subpathListKey"));
        var operation1 = pathComponents.getObjectValue(m).getEnumerationValue(sTID("shapeOperation"));
        switch (operation1) {
        case 1097098272:
        var operation = 1097098272 //cTID('Add ');
        break;
        case 1398961266:
        var operation = 1398961266 //cTID('Sbtr');
        break;
        case 1231975538:
        var operation = 1231975538 //cTID('Intr');
        break;
        default:
      // case 1102:
        var operation = sTID('xor') //ShapeOperation.SHAPEXOR;
        break;
        };
      // for subpathitem’s count;
        for (var n = 0; n < listKey.count; n++) {
        theArray.push(new Array);
        var points = listKey.getObjectValue(n).getList(sTID('points'));
        try {var closed = listKey.getObjectValue(n).getBoolean(sTID("closedSubpath"))}
        catch (e) {var closed = false};
      // for subpathitem’s segment’s number of points;
        for (var o = 0; o < points.count; o++) {
        var anchorObj = points.getObjectValue(o).getObjectValue(sTID("anchor"));
        var anchor = [anchorObj.getUnitDoubleValue(sTID('horizontal')), anchorObj.getUnitDoubleValue(sTID('vertical'))];
        var thisPoint = [anchor];
        try {
        var left = points.getObjectValue(o).getObjectValue(cTID("Fwd "));
        var leftDirection = [left.getUnitDoubleValue(sTID('horizontal')), left.getUnitDoubleValue(sTID('vertical'))];
        thisPoint.push(leftDirection)
        }
        catch (e) {
        thisPoint.push(anchor)
        };
        try {
        var right = points.getObjectValue(o).getObjectValue(cTID("Bwd "));
        var rightDirection = [right.getUnitDoubleValue(sTID('horizontal')), right.getUnitDoubleValue(sTID('vertical'))];
        thisPoint.push(rightDirection)
        }
        catch (e) {
        thisPoint.push(anchor)
        };
        try {
        var smoothOr = points.getObjectValue(o).getBoolean(cTID("Smoo"));
        thisPoint.push(smoothOr)
        }
        catch (e) {thisPoint.push(false)};
        theArray[theArray.length - 1].push(thisPoint);
        };
        theArray[theArray.length - 1].push(closed);
        theArray[theArray.length - 1].push(operation);
        };
        };
      // by xbytor, thanks to him;
      function cTID (s) { return cTID[s] || cTID[s] = app.charIDToTypeID(s); };
      function sTID (s) { return sTID[s] || sTID[s] = app.stringIDToTypeID(s); };
      // reset;
      app.preferences.rulerUnits = originalRulerUnits;
      return theArray;
      };
      ////// determine length of path by creating additional points, by SATO Hiroyuki //////
      function getLength(q, div_num){
      ////// from //////
      // Path Length.js;
      // Copyright(c) 2009 SATO Hiroyuki
      // http://park12.wakwak.com/~shp/lc/et/en_aics_script.html
      // ------------------------------------------------
      // return the segment length
      // segment = part of a path between 2 anchors
      // q = [Q0[x,y],Q1,Q2,Q3], div_num = division number
      // Simpson's method : with simplified coefficients to speed-up
      
      
        var div_unit = 1 / div_num;
        var m = [q[3][0] - q[0][0] + 3 * (q[1][0] - q[2][0]),
                 q[0][0] - 2 * q[1][0] + q[2][0],
                 q[1][0] - q[0][0]];
        var n = [q[3][1] - q[0][1] + 3 * (q[1][1] - q[2][1]),
                 q[0][1] - 2 * q[1][1] + q[2][1],
                 q[1][1] - q[0][1]];
        var k = [m[0] * m[0] + n[0] * n[0],
                 4 * (m[0] * m[1] + n[0] * n[1]),
                 2 * ((m[0] * m[2] + n[0] * n[2]) + 2 * (m[1] * m[1] + n[1] * n[1])),
                 4 * (m[1] * m[2] + n[1] * n[2]),
                 m[2] * m[2] + n[2] * n[2]];
        var fc = function(t, k){
          return Math.sqrt(t * ( t * ( t * ( t * k[0] + k[1]) + k[2]) + k[3]) + k[4]) || 0;
        };
        var total = 0;
        var i;
        for(i = 1; i < div_num; i += 2){
          total += fc(i * div_unit, k);
        };
        total *= 2;
        for(i = 2; i < div_num; i += 2){
          total += fc(i * div_unit, k);
        };
        return (fc(0, k) + fc(1, k) + total * 2) * div_unit;
      };
      ////// function to get array of points on a path; with the direction and distance to previous point //////
      function getPointsOnPath2015a (myDocument, thePath) {
      /*var originalRulerUnits = app.preferences.rulerUnits;
      app.preferences.rulerUnits = Units.PIXELS;
      var originalResolution = app.activeDocument.resolution;
      app.activeDocument.resizeImage(undefined, undefined, 72, ResampleMethod.NONE);*/
      ////////////////////////////////////
      // get path info;
      var theArray = collectPathInfoFromDesc2012(myDocument, thePath);
      ////////////////////////////////////
      // create a high number of new points along the subpaths;
      var hypotheticalPoints = new Array;
      // and collect the distances;
      var theDistances = new Array;
      // work through the original array;
      for (var m = 0; m < theArray.length; m++) {
        var theSubArray = theArray[m];
        var oneSubPath = new Array;
        var closed = theSubArray[theSubArray.length - 2];
      // change sub array;
        theSubArray = theSubArray.slice(0, theSubArray.length - 2);
        theSubArray.push(theArray[m][0]);
        theSubArray.push(theArray[m][1]);
        theSubArray.push(theArray[m][theArray[m].length-2]);
        theSubArray.push(theArray[m][theArray[m].length-1]);
      // if closed;
        if (closed == true) {
        var theSegments = theSubArray.length - 4
        }
      // if not closed;
        else {
        var theSegments = theSubArray.length - 5;
        };
      // add first point;
        var pointA = theArray[m][0][0];
        var handleA = theArray[m][0][1];
        var pointB = theArray[m][1][0];
        var handleB = theArray[m][1][2];
      // add angle to ne next point;
        if (pointA == handleA) {var theAngle = getAngle(pointA, handleB)}
        else {var theAngle = getAngle(pointA, handleA)};
        oneSubPath.push([pointA, theAngle, 0]);
      // add points;
        for (var n = 1; n <= theSegments; n++) {
      // the in-between points;
        var theNumberOfPoints = Math.round(getLength([pointA, handleA, handleB, pointB], 100)) * 3;
        for (var o = 1; o < theNumberOfPoints; o++) {
        var theFragment = 1 / theNumberOfPoints * o;
        oneSubPath.push(bezierPoint (theFragment, pointA, handleA, pointB, handleB));
        var theDist = getDistance (oneSubPath[oneSubPath.length-2][0], oneSubPath[oneSubPath.length-1][0])
        oneSubPath[oneSubPath.length-1].push(theDist)
        };
      // the next point;
        var pointA = theSubArray[n][0];
        var handleA = theSubArray[n][1];
        var theNext = n + 1;
        var pointB = theSubArray[theNext][0];
        var handleB = theSubArray[theNext][2];
      // get angle;
        if (pointA != handleB) {var theAngle = getAngle(pointA, handleB)}
        else {var theAngle = getAngle(theSubArray[n-1][1], pointA)};
      // angle for the last point;
        if (n == theSegments) {
        var theAngle = getAngle(pointA, theSubArray[n][1])
        };
      // add point;
        var theDist = getDistance (theSubArray[n][0], oneSubPath[oneSubPath.length-1][0])
        oneSubPath.push([theSubArray[n][0], theAngle, theDist])
        };
        hypotheticalPoints.push(oneSubPath);
        };
      return hypotheticalPoints
      };
      ////// get point on bezier curve and angle //////
      function bezierPoint (theFragment, pointA, handleA, pointB, handleB) {
      // the horizontal;
        var theOne = (handleA[0] - pointA[0]) * theFragment + pointA[0];
        var theTwo = (handleB[0] - handleA[0]) * theFragment + handleA[0];
        var theThree = (pointB[0] - handleB[0]) * theFragment + handleB[0];
        var theOneTwoH = (theTwo - theOne) * theFragment + theOne;
        var theTwoThreeH = (theThree - theTwo) * theFragment + theTwo;
        var theX = (theTwoThreeH - theOneTwoH) * theFragment + theOneTwoH;
      // the vertical;
        var theOne = (handleA[1] - pointA[1]) * theFragment + pointA[1];
        var theTwo = (handleB[1] - handleA[1]) * theFragment + handleA[1];
        var theThree = (pointB[1] - handleB[1]) * theFragment + handleB[1];
        var theOneTwoV = (theTwo - theOne) * theFragment + theOne;
        var theTwoThreeV = (theThree - theTwo) * theFragment + theTwo;
        var theY = (theTwoThreeV - theOneTwoV) * theFragment + theOneTwoV;
      // the point;
        var thePoint = [[theX, theY], getAngle ([theOneTwoH, theOneTwoV], [theTwoThreeH, theTwoThreeV])];
      // var thePoint = [[theX, theY],;
        return thePoint
        };
      ////// radians //////
      function radiansOf (theAngle) {
        return theAngle * Math.PI / 180
        };
      ////// angle from radians //////
      function angleFromRadians (theRad) {
        return theRad / Math.PI * 180
        };
      ////// get an angle, 3:00 being 0˚, 6:00 90˚, etc. //////
      function getAngle (pointOne, pointTwo) {
      // calculate the triangle sides;
        var width = pointTwo[0] - pointOne[0];
        var height = pointTwo[1] - pointOne[1];
        var sideC = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2));
      // calculate the angles;
        if (width+width > width) {theAngle = Math.asin(height / sideC) * 360 / 2 / Math.PI}
        else {theAngle = 180 - (Math.asin(height / sideC) * 360 / 2 / Math.PI)};
        if (theAngle < 0) {theAngle = (360 + theAngle)};
      // if (theAngle > 180) {theAngle = (360 - theAngle) * (-1)};
        return theAngle
        };
      ////// get a distance between two points //////
      function getDistance (pointOne, pointTwo) {
      // calculate the triangle sides;
        var width = pointTwo[0] - pointOne[0];
        var height = pointTwo[1] - pointOne[1];
        var sideC = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2));
        return sideC
        };
      ////// rotate and move //////
      function duplicateMoveAndScale (myDocument, theIndex, theGroupIndex, thisAngle, horizontalOffset, verticalOffset, horScale, verScale) {
      // duplicate by index;
      // =======================================================
      var idmove = charIDToTypeID( "move" );
          var desc8 = new ActionDescriptor();
          var idnull = charIDToTypeID( "null" );
              var ref8 = new ActionReference();
              var idLyr = charIDToTypeID( "Lyr " );
              ref8.putIdentifier( charIDToTypeID( "Lyr " ), theIndex );
          desc8.putReference( idnull, ref8 );
          var idT = charIDToTypeID( "T   " );
              var ref9 = new ActionReference();
              var idLyr = charIDToTypeID( "Lyr " );
              ref9.putIndex( idLyr, theGroupIndex );
          desc8.putReference( idT, ref9 );
          var idDplc = charIDToTypeID( "Dplc" );
          desc8.putBoolean( idDplc, true );
          var idAdjs = charIDToTypeID( "Adjs" );
          desc8.putBoolean( idAdjs, false );
          var idVrsn = charIDToTypeID( "Vrsn" );
          desc8.putInteger( idVrsn, 5 );
      executeAction( idmove, desc8, DialogModes.NO );
      // do the transformations;
      // =======================================================
      var idTrnf = charIDToTypeID( "Trnf" );
          var desc3 = new ActionDescriptor();
          var idnull = charIDToTypeID( "null" );
              var ref2 = new ActionReference();
              var idLyr = charIDToTypeID( "Lyr " );
              var idOrdn = charIDToTypeID( "Ordn" );
              var idTrgt = charIDToTypeID( "Trgt" );
              ref2.putEnumerated( idLyr, idOrdn, idTrgt );
          desc3.putReference( idnull, ref2 );
          var idFTcs = charIDToTypeID( "FTcs" );
          var idQCSt = charIDToTypeID( "QCSt" );
          var idQcsa = charIDToTypeID( "Qcsa" );
          desc3.putEnumerated( idFTcs, idQCSt, idQcsa );
          var idOfst = charIDToTypeID( "Ofst" );
              var desc4 = new ActionDescriptor();
              var idHrzn = charIDToTypeID( "Hrzn" );
              var idPxl = charIDToTypeID( "#Pxl" );
              desc4.putUnitDouble( idHrzn, idPxl, horizontalOffset );
              var idVrtc = charIDToTypeID( "Vrtc" );
              var idPxl = charIDToTypeID( "#Pxl" );
              desc4.putUnitDouble( idVrtc, idPxl, verticalOffset );
          var idOfst = charIDToTypeID( "Ofst" );
          desc3.putObject( idOfst, idOfst, desc4 );
          var idWdth = charIDToTypeID( "Wdth" );
          var idPrc = charIDToTypeID( "#Prc" );
          desc3.putUnitDouble( idWdth, idPrc, horScale );
          var idHght = charIDToTypeID( "Hght" );
          var idPrc = charIDToTypeID( "#Prc" );
          desc3.putUnitDouble( idHght, idPrc, verScale );
      if (thisAngle != 0) {
          var idAngl = charIDToTypeID( "Angl" );
          var idAng = charIDToTypeID( "#Ang" );
          desc3.putUnitDouble( idAngl, idAng, thisAngle );
        };
      executeAction( idTrnf, desc3, DialogModes.NO );
      };
      ////// get netx in an array circularly //////
      function theNextInTheArray (theArray, theNumber) {
      if (theNumber < theArray.length - 1) {return theArray[theNumber]}
      else {
        var theNumber = theNumber - (Math.floor(theNumber / theArray.length )) * theArray.length;
        return theArray[theNumber]
        }
      };
      
      
        • 3. Re: script for distributing smart object instances along path for testing
          pixxxel schubser MVP & Adobe Community Professional

          Hi c.pfaffenbichler,

          I do not have the latest versions here.

           

          And I get no result because of

          line 148: var halfWidth = theBounds.getUnitDoubleValue(stringIDToTypeID("width")) / 2; 

           

          seems not compatible with older versions.

          • 5. Re: script for distributing smart object instances along path for testing
            pixxxel schubser MVP & Adobe Community Professional

            I use my own PS CS3 and have now tested in addition with the PS CS5 (64 bit) of my son.

            --> the same result: error in line 148

            »Allgemeiner Photoshop-Fehler. Die Funktion steht in dieser Version von Photoship möglicherweise nicht zur Verfügung«

            Translation:  General Photoshop error occured. This functionality may not be available in this version of Photoshop.

             

            • 6. Re: script for distributing smart object instances along path for testing
              c.pfaffenbichler Level 9

              What do you get when you run this?

              #target photoshop
              if (app.documents.length > 0) {
              var ref = new ActionReference();
              ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
              var layerDesc = executeActionGet(ref);
              var theBounds = layerDesc.getObjectValue(stringIDToTypeID("bounds"));
              checkDesc2 (theBounds)
              };
              ////// based on code by michael l hale //////
              function checkDesc2 (theDesc) {
              var c = theDesc.count;
              var str = '';
              for(var i=0;i<c;i++){ //enumerate descriptor's keys
                str = str + 'Key '+i+' = '+typeIDToStringID(theDesc.getKey(i))+': '+theDesc.getType(theDesc.getKey(i))+'\n'+getValues (theDesc, i)+'\n';
                };
              alert("desc\n\n"+str);
              };
              ////// check //////
              function getValues (theDesc, theNumber) {
              switch (theDesc.getType(theDesc.getKey(theNumber))) {
              case DescValueType.BOOLEANTYPE:
              return theDesc.getBoolean(theDesc.getKey(theNumber));
              break;
              case DescValueType.CLASSTYPE:
              return theDesc.getClass(theDesc.getKey(theNumber));
              break;
              case DescValueType.DOUBLETYPE:
              return theDesc.getDouble(theDesc.getKey(theNumber));
              break;
              case DescValueType.ENUMERATEDTYPE:
              return (typeIDToStringID(theDesc.getEnumerationValue(theDesc.getKey(theNumber)))+"_"+typeIDToStringID(theDesc.getEnumerationType(theDesc.getKey(theNumber))));
              break;
              case DescValueType.INTEGERTYPE:
              return theDesc.getInteger(theDesc.getKey(theNumber));
              break;
              case DescValueType.LISTTYPE:
              return theDesc.getList(theDesc.getKey(theNumber));
              break;
              case DescValueType.OBJECTTYPE:
              return (theDesc.getObjectValue(theDesc.getKey(theNumber))+"_"+typeIDToStringID(theDesc.getObjectType(theDesc.getKey(theNumber))));
              break;
              case DescValueType.REFERENCETYPE:
              return theDesc.getReference(theDesc.getKey(theNumber));
              break;
              case DescValueType.STRINGTYPE:
              return theDesc.getString(theDesc.getKey(theNumber));
              break;
              case DescValueType.UNITDOUBLE:
              return (theDesc.getUnitDoubleValue(theDesc.getKey(theNumber))+"_"+typeIDToStringID(theDesc.getUnitDoubleType(theDesc.getKey(theNumber))));
              break;
              default:
              break;
              };
              };
              
              2 people found this helpful
              • 7. Re: script for distributing smart object instances along path for testing
                pixxxel schubser MVP & Adobe Community Professional

                In CS3 I get this:

                desc
                
                Key 0 = top: DescValueType.UNITDOUBLE
                188_pixelsUnit
                Key 1 = left: DescValueType.UNITDOUBLE
                238_pixelsUnit
                Key 2 = bottom: DescValueType.UNITDOUBLE
                222_pixelsUnit
                Key 3 = right: DescValueType.UNITDOUBLE
                276_pixelsUnit
                

                 

                and in CS5 I get:

                desc
                
                Key 0 = top: DescValueType.UNITDOUBLE
                416_pixelsUnit
                Key 1 = left: DescValueType.UNITDOUBLE
                642_pixelsUnit
                Key 2 = bottom: DescValueType.UNITDOUBLE
                467_pixelsUnit
                Key 3 = right: DescValueType.UNITDOUBLE
                692_pixelsUnit
                

                 

                 

                It seems to be the same in both versions.

                 

                • 8. Re: script for distributing smart object instances along path for testing
                  pixxxel schubser MVP & Adobe Community Professional

                  This works with CS3:

                   

                  replace these two lines:

                  var halfWidth = theBounds.getUnitDoubleValue(stringIDToTypeID("width")) / 2;

                  var halfHeight = theBounds.getUnitDoubleValue(stringIDToTypeID("height")) / 2;

                   

                  with this:

                  var halfWidth = (theBounds.getUnitDoubleValue(stringIDToTypeID("right")) - theBounds.getUnitDoubleValue(stringIDToTypeID("left")) ) / 2;

                  var halfHeight = (theBounds.getUnitDoubleValue(stringIDToTypeID("bottom")) - theBounds.getUnitDoubleValue(stringIDToTypeID("top")) ) / 2;

                  1 person found this helpful
                  • 9. Re: script for distributing smart object instances along path for testing
                    c.pfaffenbichler Level 9

                    On Photoshop CC I get

                    Key 0 = top: DescValueType.UNITDOUBLE

                    1647_pixelsUnit

                    Key 1 = left: DescValueType.UNITDOUBLE

                    1510_pixelsUnit

                    Key 2 = bottom: DescValueType.UNITDOUBLE

                    2440_pixelsUnit

                    Key 3 = right: DescValueType.UNITDOUBLE

                    2561_pixelsUnit

                    Key 4 = width: DescValueType.UNITDOUBLE

                    1051_pixelsUnit

                    Key 5 = height: DescValueType.UNITDOUBLE

                    793_pixelsUnit

                     

                    Amending the lines

                    var halfWidth = theBounds.getUnitDoubleValue(stringIDToTypeID("width")) / 2; 
                    var halfHeight = theBounds.getUnitDoubleValue(stringIDToTypeID("height")) / 2; 
                    

                    to

                    var halfWidth = (theBounds.getUnitDoubleValue(stringIDToTypeID("right")) - theBounds.getUnitDoubleValue(stringIDToTypeID("left"))) / 2;
                    var halfHeight = (theBounds.getUnitDoubleValue(stringIDToTypeID("bottom")) - theBounds.getUnitDoubleValue(stringIDToTypeID("top"))) / 2;
                    

                    should solve that issue.

                    1 person found this helpful
                    • 10. Re: script for distributing smart object instances along path for testing
                      c.pfaffenbichler Level 9

                      I see you just posted the solution yourself.

                      • 12. Re: script for distributing smart object instances along path for testing
                        pixxxel schubser MVP & Adobe Community Professional

                        It seems, that earlier versions of PS don't know the value for width and height.

                         

                        But now your script runs also with CS3

                        c_pfaffenbichler2.png

                         

                        Perhaps You could built in neverinteract with all (to suppress this message - convert to Smart object)

                        c_pfaffenbichler3.png

                        • 13. Re: script for distributing smart object instances along path for testing
                          JJMack Most Valuable Participant

                          I Added a toggle pallets at the beginning and end to speed execution up my processors are onle 2GHz. 

                          Atom.gif

                          1 person found this helpful
                          • 14. Re: script for distributing smart object instances along path for testing
                            c.pfaffenbichler Level 9
                            I Added a toggle pallets at the beginning and end to speed execution up

                            Good point.

                            • 15. Re: script for distributing smart object instances along path for testing
                              pixxxel schubser MVP & Adobe Community Professional

                              Another point:

                              If the language of PS is not english && the pathItems[0] is a "Workpath", than the script fails.

                               

                              Perhaps is could be better to use the pathItems[0].kind instead of the pathItems[0].name for "Workpaths".

                              1 person found this helpful
                              • 17. Re: script for distributing smart object instances along path for testing
                                c.pfaffenbichler Level 9

                                Perhaps is could be better to use the pathItems[0].kind instead of the pathItems[0].name for "Workpaths".

                                Very much so!

                                1 person found this helpful
                                • 18. Re: script for distributing smart object instances along path for testing
                                  c.pfaffenbichler Level 9

                                  Thank you all for your posts.

                                   

                                  I wondered if I just can’t remember or figure out how to assign posts the "helpful" label but it seems the OP does not have that option anymore:

                                  How to mark a post/reply as helpful?

                                  So, despite thus bloating the "like"-count of a thread I started myself, I just "like"-d a couple of them.

                                   

                                  I suppose the Script could (apart from the performance- and language-related issues JJMack and pixel schubser have pointed out) do with some more checks to avoid tripping it up (like deselecting if a Selection is active), but I do not intend to publish it "professionally" anyway …

                                  1 person found this helpful
                                  • 19. Re: script for distributing smart object instances along path for testing
                                    MBA-2-rae Level 1

                                    two years ago I wrote a script to design the wave pattern of the Copacabana pathway (just for fun).

                                    Unfortunately I didn't find out yet how to fill the solid B&W pattern with the typical mosaic stone pieces.

                                    Now your script is raising hope to solve this problem distributing layers along the wavelike paths.

                                    I'll take a new run asap.

                                    Thanks for this inspiring script!

                                    • 20. Re: script for distributing smart object instances along path for testing
                                      EnsilZah_ Level 1

                                      Nice.
                                      I was planning on doing something similar after I wrote a script that distributes smart objects based on Photoshop's blob detection function.
                                      I'll have to dig into this later to modify it for my purposes.

                                       

                                      I'd put a suspend history function in there, so you can undo the whole thing in one undo.
                                      And give it a UI similar to the Brush Window: spacing, scattering, color dynamics, shape dynamics, etc.

                                       

                                      Anyway, thanks for a potentially useful script.

                                      • 21. Re: script for distributing smart object instances along path for testing
                                        Lionel Drew

                                        HI, I'm new here, and I'm very interested in this script.  Not sure if you think it needs more testing, but I would like to exercise your script over the next few days.  Can I rely on the script as posted above, or should I download a different version - and if so, from where?  I'm very much a javascript novice, so I have to rely on extensive coding experience that is now very old.  Amazing to me how much of today's world relies on an interpreted language that permits self-modification, but I guess nothing stays the same.

                                         

                                        Thanks.

                                        • 22. Re: script for distributing smart object instances along path for testing
                                          c.pfaffenbichler Level 9

                                          This is the last version I did, but I may not have included all improvements mentioned by the others:

                                          // distribute selected layers as smart object instances along selected path, if no path is selected use the first one;

                                          // additional points are calculated along the path to use for positioning the instances;

                                          // 2015, use it at your own risk;

                                          #target photoshop

                                          if (app.documents.length > 0) {

                                          var myDocument = app.activeDocument;

                                          if (myDocument.pathItems.length > 0) {

                                          // get id, center and half-dimensions of selected layers;

                                          var theLayers = smartifyAndGetSelectedLayersIdxEtc();

                                          // get selected path;

                                          var thePath = selectedPath2015 ();

                                          if (thePath == undefined) {var thePath = myDocument.pathItems[0]};

                                          ////////////////////////////////////

                                          if (theLayers.length > 0) {

                                          app.togglePalettes();

                                          myDocument.selection.deselect();

                                          var originalRulerUnits = app.preferences.rulerUnits;

                                          app.preferences.rulerUnits = Units.PIXELS;

                                          var originalResolution = myDocument.resolution;

                                          myDocument.resizeImage(undefined, undefined, 72, ResampleMethod.NONE);

                                          // create a layerset to hold the copies;

                                          var myLayerSet = myDocument.layerSets.add();

                                          myLayerSet.name = "copies on "+thePath.name;

                                          var theGroupIndex = getLayerIndex(myLayerSet)-1;

                                          // collect path info, array of points, angle, distance from last point;

                                          var thePath = getPointsOnPath2015a (myDocument, thePath);

                                          ////////////////////////////////////

                                          for (var m = 0; m < thePath.length; m++) {

                                            var theCounter = 0;

                                            var thisSubPath = thePath[m];

                                            var thisLayer = theNextInTheArray(theLayers, theCounter);

                                            var nextLayer = theNextInTheArray(theLayers, theCounter+1);

                                            var theDistanceCovered = 0;

                                            var theTargetLength = thisLayer[3];

                                          // perform on each sub path array;

                                            for (var n = 0; n < thisSubPath.length; n++) {

                                            theDistanceCovered = theDistanceCovered + Number(thisSubPath[n][2]);

                                          // if the length is met place instance at position of point with angle;

                                            if (theDistanceCovered >= theTargetLength) {

                                            theTargetLength = thisLayer[3] + nextLayer[3];

                                            duplicateMoveAndScale (myDocument, thisLayer[0], theGroupIndex, thisSubPath[n][1], thisSubPath[n][0][0]-thisLayer[1], thisSubPath[n][0][1]-thisLayer[2], 100, 100);

                                            theCounter++;

                                            var thisLayer = theNextInTheArray(theLayers, theCounter);

                                            var nextLayer = theNextInTheArray(theLayers, theCounter+1);

                                            theDistanceCovered = 0;

                                            }

                                            }

                                            };

                                          ////////////////////////////////////

                                          // reset;

                                          app.preferences.rulerUnits = originalRulerUnits;

                                          myDocument.resizeImage(undefined, undefined, originalResolution, ResampleMethod.NONE);

                                          app.togglePalettes();

                                          };

                                          ////////////////////////////////////

                                          }

                                          };

                                          ////////////////////////////////////

                                          ////////////////////////////////////

                                          ////////////////////////////////////

                                          ////// based on code by mike hale and paul riggott //////

                                          function selectLayerByID(index,add){

                                          add = undefined ? add = false:add

                                          var ref = new ActionReference();

                                              ref.putIdentifier(charIDToTypeID("Lyr "), index);

                                              var desc = new ActionDescriptor();

                                              desc.putReference(charIDToTypeID("null"), ref );

                                                 if(add) desc.putEnumerated( stringIDToTypeID( "selectionModifier" ), stringIDToTypeID( "selectionModifierType" ), stringIDToTypeID( "addToSelection" ) );

                                                desc.putBoolean( charIDToTypeID( "MkVs" ), false );

                                             try{

                                              executeAction(charIDToTypeID("slct"), desc, DialogModes.NO );

                                          }catch(e){

                                          alert(e.message);

                                          }

                                          };

                                          // by mike hale, via paul riggott;

                                          function selectLayerByIndex(index,add){

                                          // http://forums.adobe.com/message/1944754#1944754

                                          add = undefined ? add = false:add

                                          var ref = new ActionReference();

                                              ref.putIndex(charIDToTypeID("Lyr "), index);

                                              var desc = new ActionDescriptor();

                                              desc.putReference(charIDToTypeID("null"), ref );

                                                 if(add) desc.putEnumerated( stringIDToTypeID( "selectionModifier" ), stringIDToTypeID( "selectionModifierType" ), stringIDToTypeID( "addToSelection" ) );

                                                desc.putBoolean( charIDToTypeID( "MkVs" ), false );

                                             try{

                                              executeAction(charIDToTypeID("slct"), desc, DialogModes.NO );

                                          }catch(e){

                                          alert(e.message);

                                          }

                                          };

                                          // by mike hale, via paul riggott;

                                          function getLayerIndex(theLayer){

                                          // http://forums.adobe.com/message/1944754#1944754

                                          app.activeDocument.activeLayer = theLayer;

                                          //Assumes activeDocument and activeLayer

                                              var ref = new ActionReference();

                                              ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));

                                              d = executeActionGet(ref);

                                          return d.getInteger(stringIDToTypeID('itemIndex'));

                                          };

                                          // by mike hale, via paul riggott;

                                          function getLayerId(theLayer){

                                          // http://forums.adobe.com/message/1944754#1944754

                                          app.activeDocument.activeLayer = theLayer;

                                          //Assumes activeDocument and activeLayer

                                              var ref = new ActionReference();

                                              ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));

                                              d = executeActionGet(ref);

                                          return d.getInteger(charIDToTypeID('LyrI'));

                                          };

                                          ////// get array of arrays of smart objects witrh index, center and half-dimensions //////

                                          function smartifyAndGetSelectedLayersIdxEtc(){

                                            var selectedLayers = new Array;

                                            var ref = new ActionReference();

                                            ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );

                                            var desc = executeActionGet(ref);

                                            if( desc.hasKey( stringIDToTypeID( 'targetLayers' ) ) ){

                                            desc = desc.getList( stringIDToTypeID( 'targetLayers' ));

                                            var c = desc.count;

                                            var selectedLayers = new Array();

                                            for(var i=0;i<c;i++){

                                            try{

                                            activeDocument.backgroundLayer;

                                            selectedLayers.push(  desc.getReference( i ).getIndex() );

                                            }catch(e){

                                            selectedLayers.push(  desc.getReference( i ).getIndex()+1 );

                                            };

                                            }

                                            }else{

                                            var ref = new ActionReference();

                                            ref.putProperty( charIDToTypeID("Prpr") , charIDToTypeID( "ItmI" ));

                                            ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );

                                            try{

                                            activeDocument.backgroundLayer;

                                            selectedLayers.push( executeActionGet(ref).getInteger(charIDToTypeID( "ItmI" ))-1);

                                            }catch(e){

                                            selectedLayers.push( executeActionGet(ref).getInteger(charIDToTypeID( "ItmI" )));

                                            };

                                            };

                                          ////////////////////////////////////

                                          var theArray = new Array;

                                          var theIDs = new Array;

                                          for (var m = 0; m < selectedLayers.length; m++) {

                                          var thisIndex = selectedLayers[m];

                                          var ref = new ActionReference();

                                          ref.putIndex( charIDToTypeID("Lyr "), thisIndex);

                                          var layerDesc = executeActionGet(ref);

                                          var thisID = layerDesc.getInteger(stringIDToTypeID("layerID"));

                                          var theBounds = layerDesc.getObjectValue(stringIDToTypeID("bounds"));

                                          var halfWidth = theBounds.getUnitDoubleValue(stringIDToTypeID("width")) / 2;

                                          var halfHeight = theBounds.getUnitDoubleValue(stringIDToTypeID("height")) / 2;

                                          var theX = theBounds.getUnitDoubleValue(stringIDToTypeID("left")) + halfWidth;

                                          var theY = theBounds.getUnitDoubleValue(stringIDToTypeID("top")) + halfHeight;

                                          theIDs.push ([thisID, theX, theY, halfWidth, halfHeight])

                                          };

                                          ////////////////////////////////////

                                          for (var n = 0; n < theIDs.length; n++) {

                                          if (hasSmartObject(theIDs[n][0]) == false) {

                                            try {

                                            selectLayerByID(theIDs[n][0], false);

                                            var id557 = charIDToTypeID( "slct" );

                                            var desc108 = new ActionDescriptor();

                                            var id558 = charIDToTypeID( "null" );

                                            var ref77 = new ActionReference();

                                            var id559 = charIDToTypeID( "Mn  " );

                                            var id560 = charIDToTypeID( "MnIt" );

                                            var id561 = stringIDToTypeID( "newPlacedLayer" );

                                            ref77.putEnumerated( id559, id560, id561 );

                                            desc108.putReference( id558, ref77 );

                                            executeAction( id557, desc108, DialogModes.NO );

                                            theArray.push([getLayerId(app.activeDocument.activeLayer), theIDs[n][1], theIDs[n][2], theIDs[n][3], theIDs[n][4]]);

                                            } catch (e) {}

                                            }

                                          else {theArray.push(theIDs[n])};

                                          };

                                          ////////////////////////////////////

                                          return theArray

                                          ////////////////////////////////////

                                          //return selectedLayers;

                                          };

                                          ////// smart object or not //////

                                          function hasSmartObject(idx){

                                          var ref = new ActionReference();

                                          ref.putProperty( charIDToTypeID("Prpr") , stringIDToTypeID( "smartObject" ));

                                          //ref.putIndex( charIDToTypeID( "Lyr " ), idx);

                                          ref.putIdentifier( charIDToTypeID( "Lyr " ), idx);

                                          var desc = executeActionGet(ref);

                                          if(desc.hasKey(stringIDToTypeID('smartObject'))) {return true}

                                          else {return false};

                                          };

                                          ////// determine selected path, updated 09.2015 //////

                                          function selectedPath2015 () {

                                          try {

                                          var ref = new ActionReference();

                                          ref.putProperty (stringIDToTypeID("property"), stringIDToTypeID("targetPathIndex"));

                                          ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );

                                          var docDesc = executeActionGet(ref);

                                          return app.activeDocument.pathItems[docDesc.getInteger(stringIDToTypeID("targetPathIndex"))]

                                          }

                                          catch (e) {return undefined}

                                          };

                                          ////// collect path info from actiondescriptor, smooth added //////

                                          function collectPathInfoFromDesc2012 (myDocument, thePath) {

                                          var originalRulerUnits = app.preferences.rulerUnits;

                                          app.preferences.rulerUnits = Units.POINTS;

                                          // based of functions from xbytor’s stdlib;

                                          var ref = new ActionReference();

                                          for (var l = 0; l < myDocument.pathItems.length; l++) {

                                            var thisPath = myDocument.pathItems[l];

                                            if (thisPath == thePath && thisPath.kind == PathKind.WORKPATH) {

                                            ref.putProperty(cTID("Path"), cTID("WrPt"));

                                            };

                                            if (thisPath == thePath && thisPath.kind != PathKind.WORKPATH && thisPath.kind != PathKind.VECTORMASK) {

                                            ref.putIndex(cTID("Path"), l + 1);

                                            };

                                            if (thisPath == thePath && thisPath.kind == PathKind.VECTORMASK) {

                                                  var idPath = charIDToTypeID( "Path" );

                                                  var idPath = charIDToTypeID( "Path" );

                                                  var idvectorMask = stringIDToTypeID( "vectorMask" );

                                                  ref.putEnumerated( idPath, idPath, idvectorMask );

                                            };

                                            };

                                          var desc = app.executeActionGet(ref);

                                          var pname = desc.getString(cTID('PthN'));

                                          // create new array;

                                          var theArray = new Array;

                                          var pathComponents = desc.getObjectValue(cTID("PthC")).getList(sTID('pathComponents'));

                                          // for subpathitems;

                                          for (var m = 0; m < pathComponents.count; m++) {

                                            var listKey = pathComponents.getObjectValue(m).getList(sTID("subpathListKey"));

                                            var operation1 = pathComponents.getObjectValue(m).getEnumerationValue(sTID("shapeOperation"));

                                            switch (operation1) {

                                            case 1097098272:

                                            var operation = 1097098272 //cTID('Add ');

                                            break;

                                            case 1398961266:

                                            var operation = 1398961266 //cTID('Sbtr');

                                            break;

                                            case 1231975538:

                                            var operation = 1231975538 //cTID('Intr');

                                            break;

                                            default:

                                          // case 1102:

                                            var operation = sTID('xor') //ShapeOperation.SHAPEXOR;

                                            break;

                                            };

                                          // for subpathitem’s count;

                                            for (var n = 0; n < listKey.count; n++) {

                                            theArray.push(new Array);

                                            var points = listKey.getObjectValue(n).getList(sTID('points'));

                                            try {var closed = listKey.getObjectValue(n).getBoolean(sTID("closedSubpath"))}

                                            catch (e) {var closed = false};

                                          // for subpathitem’s segment’s number of points;

                                            for (var o = 0; o < points.count; o++) {

                                            var anchorObj = points.getObjectValue(o).getObjectValue(sTID("anchor"));

                                            var anchor = [anchorObj.getUnitDoubleValue(sTID('horizontal')), anchorObj.getUnitDoubleValue(sTID('vertical'))];

                                            var thisPoint = [anchor];

                                            try {

                                            var left = points.getObjectValue(o).getObjectValue(cTID("Fwd "));

                                            var leftDirection = [left.getUnitDoubleValue(sTID('horizontal')), left.getUnitDoubleValue(sTID('vertical'))];

                                            thisPoint.push(leftDirection)

                                            }

                                            catch (e) {

                                            thisPoint.push(anchor)

                                            };

                                            try {

                                            var right = points.getObjectValue(o).getObjectValue(cTID("Bwd "));

                                            var rightDirection = [right.getUnitDoubleValue(sTID('horizontal')), right.getUnitDoubleValue(sTID('vertical'))];

                                            thisPoint.push(rightDirection)

                                            }

                                            catch (e) {

                                            thisPoint.push(anchor)

                                            };

                                            try {

                                            var smoothOr = points.getObjectValue(o).getBoolean(cTID("Smoo"));

                                            thisPoint.push(smoothOr)

                                            }

                                            catch (e) {thisPoint.push(false)};

                                            theArray[theArray.length - 1].push(thisPoint);

                                            };

                                            theArray[theArray.length - 1].push(closed);

                                            theArray[theArray.length - 1].push(operation);

                                            };

                                            };

                                          // by xbytor, thanks to him;

                                          function cTID (s) { return cTID[s] || cTID[s] = app.charIDToTypeID(s); };

                                          function sTID (s) { return sTID[s] || sTID[s] = app.stringIDToTypeID(s); };

                                          // reset;

                                          app.preferences.rulerUnits = originalRulerUnits;

                                          return theArray;

                                          };

                                          ////// determine length of path by creating additional points, by SATO Hiroyuki //////

                                          function getLength(q, div_num){

                                          ////// from //////

                                          // Path Length.js;

                                          // Copyright(c) 2009 SATO Hiroyuki

                                          // http://park12.wakwak.com/~shp/lc/et/en_aics_script.html

                                          // ------------------------------------------------

                                          // return the segment length

                                          // segment = part of a path between 2 anchors

                                          // q = [Q0[x,y],Q1,Q2,Q3], div_num = division number

                                          // Simpson's method : with simplified coefficients to speed-up

                                           

                                           

                                            var div_unit = 1 / div_num;

                                            var m = [q[3][0] - q[0][0] + 3 * (q[1][0] - q[2][0]),

                                                     q[0][0] - 2 * q[1][0] + q[2][0],

                                                     q[1][0] - q[0][0]];

                                            var n = [q[3][1] - q[0][1] + 3 * (q[1][1] - q[2][1]),

                                                     q[0][1] - 2 * q[1][1] + q[2][1],

                                                     q[1][1] - q[0][1]];

                                            var k = [m[0] * m[0] + n[0] * n[0],

                                                     4 * (m[0] * m[1] + n[0] * n[1]),

                                                     2 * ((m[0] * m[2] + n[0] * n[2]) + 2 * (m[1] * m[1] + n[1] * n[1])),

                                                     4 * (m[1] * m[2] + n[1] * n[2]),

                                                     m[2] * m[2] + n[2] * n[2]];

                                            var fc = function(t, k){

                                              return Math.sqrt(t * ( t * ( t * ( t * k[0] + k[1]) + k[2]) + k[3]) + k[4]) || 0;

                                            };

                                            var total = 0;

                                            var i;

                                            for(i = 1; i < div_num; i += 2){

                                              total += fc(i * div_unit, k);

                                            };

                                            total *= 2;

                                            for(i = 2; i < div_num; i += 2){

                                              total += fc(i * div_unit, k);

                                            };

                                            return (fc(0, k) + fc(1, k) + total * 2) * div_unit;

                                          };

                                          ////// function to get array of points on a path; with the direction and distance to previous point //////

                                          function getPointsOnPath2015a (myDocument, thePath) {

                                          /*var originalRulerUnits = app.preferences.rulerUnits;

                                          app.preferences.rulerUnits = Units.PIXELS;

                                          var originalResolution = app.activeDocument.resolution;

                                          app.activeDocument.resizeImage(undefined, undefined, 72, ResampleMethod.NONE);*/

                                          ////////////////////////////////////

                                          // get path info;

                                          var theArray = collectPathInfoFromDesc2012(myDocument, thePath);

                                          ////////////////////////////////////

                                          // create a high number of new points along the subpaths;

                                          var hypotheticalPoints = new Array;

                                          // and collect the distances;

                                          var theDistances = new Array;

                                          // work through the original array;

                                          for (var m = 0; m < theArray.length; m++) {

                                            var theSubArray = theArray[m];

                                            var oneSubPath = new Array;

                                            var closed = theSubArray[theSubArray.length - 2];

                                          // change sub array;

                                            theSubArray = theSubArray.slice(0, theSubArray.length - 2);

                                            theSubArray.push(theArray[m][0]);

                                            theSubArray.push(theArray[m][1]);

                                            theSubArray.push(theArray[m][theArray[m].length-2]);

                                            theSubArray.push(theArray[m][theArray[m].length-1]);

                                          // if closed;

                                            if (closed == true) {

                                            var theSegments = theSubArray.length - 4

                                            }

                                          // if not closed;

                                            else {

                                            var theSegments = theSubArray.length - 5;

                                            };

                                          // add first point;

                                            var pointA = theArray[m][0][0];

                                            var handleA = theArray[m][0][1];

                                            var pointB = theArray[m][1][0];

                                            var handleB = theArray[m][1][2];

                                          // add angle to ne next point;

                                            if (pointA == handleA) {var theAngle = getAngle(pointA, handleB)}

                                            else {var theAngle = getAngle(pointA, handleA)};

                                            oneSubPath.push([pointA, theAngle, 0]);

                                          // add points;

                                            for (var n = 1; n <= theSegments; n++) {

                                          // the in-between points;

                                            var theNumberOfPoints = Math.round(getLength([pointA, handleA, handleB, pointB], 100)) * 3;

                                            for (var o = 1; o < theNumberOfPoints; o++) {

                                            var theFragment = 1 / theNumberOfPoints * o;

                                            oneSubPath.push(bezierPoint (theFragment, pointA, handleA, pointB, handleB));

                                            var theDist = getDistance (oneSubPath[oneSubPath.length-2][0], oneSubPath[oneSubPath.length-1][0])

                                            oneSubPath[oneSubPath.length-1].push(theDist)

                                            };

                                          // the next point;

                                            var pointA = theSubArray[n][0];

                                            var handleA = theSubArray[n][1];

                                            var theNext = n + 1;

                                            var pointB = theSubArray[theNext][0];

                                            var handleB = theSubArray[theNext][2];

                                          // get angle;

                                            if (pointA != handleB) {var theAngle = getAngle(pointA, handleB)}

                                            else {var theAngle = getAngle(theSubArray[n-1][1], pointA)};

                                          // angle for the last point;

                                            if (n == theSegments) {

                                            var theAngle = getAngle(pointA, theSubArray[n][1])

                                            };

                                          // add point;

                                            var theDist = getDistance (theSubArray[n][0], oneSubPath[oneSubPath.length-1][0])

                                            oneSubPath.push([theSubArray[n][0], theAngle, theDist])

                                            };

                                            hypotheticalPoints.push(oneSubPath);

                                            };

                                          return hypotheticalPoints

                                          };

                                          ////// get point on bezier curve and angle //////

                                          function bezierPoint (theFragment, pointA, handleA, pointB, handleB) {

                                          // the horizontal;

                                            var theOne = (handleA[0] - pointA[0]) * theFragment + pointA[0];

                                            var theTwo = (handleB[0] - handleA[0]) * theFragment + handleA[0];

                                            var theThree = (pointB[0] - handleB[0]) * theFragment + handleB[0];

                                            var theOneTwoH = (theTwo - theOne) * theFragment + theOne;

                                            var theTwoThreeH = (theThree - theTwo) * theFragment + theTwo;

                                            var theX = (theTwoThreeH - theOneTwoH) * theFragment + theOneTwoH;

                                          // the vertical;

                                            var theOne = (handleA[1] - pointA[1]) * theFragment + pointA[1];

                                            var theTwo = (handleB[1] - handleA[1]) * theFragment + handleA[1];

                                            var theThree = (pointB[1] - handleB[1]) * theFragment + handleB[1];

                                            var theOneTwoV = (theTwo - theOne) * theFragment + theOne;

                                            var theTwoThreeV = (theThree - theTwo) * theFragment + theTwo;

                                            var theY = (theTwoThreeV - theOneTwoV) * theFragment + theOneTwoV;

                                          // the point;

                                            var thePoint = [[theX, theY], getAngle ([theOneTwoH, theOneTwoV], [theTwoThreeH, theTwoThreeV])];

                                          // var thePoint = [[theX, theY],;

                                            return thePoint

                                            };

                                          ////// radians //////

                                          function radiansOf (theAngle) {

                                            return theAngle * Math.PI / 180

                                            };

                                          ////// angle from radians //////

                                          function angleFromRadians (theRad) {

                                            return theRad / Math.PI * 180

                                            };

                                          ////// get an angle, 3:00 being 0˚, 6:00 90˚, etc. //////

                                          function getAngle (pointOne, pointTwo) {

                                          // calculate the triangle sides;

                                            var width = pointTwo[0] - pointOne[0];

                                            var height = pointTwo[1] - pointOne[1];

                                            var sideC = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2));

                                          // calculate the angles;

                                            if (width+width > width) {theAngle = Math.asin(height / sideC) * 360 / 2 / Math.PI}

                                            else {theAngle = 180 - (Math.asin(height / sideC) * 360 / 2 / Math.PI)};

                                            if (theAngle < 0) {theAngle = (360 + theAngle)};

                                          // if (theAngle > 180) {theAngle = (360 - theAngle) * (-1)};

                                            return theAngle

                                            };

                                          ////// get a distance between two points //////

                                          function getDistance (pointOne, pointTwo) {

                                          // calculate the triangle sides;

                                            var width = pointTwo[0] - pointOne[0];

                                            var height = pointTwo[1] - pointOne[1];

                                            var sideC = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2));

                                            return sideC

                                            };

                                          ////// rotate and move //////

                                          function duplicateMoveAndScale (myDocument, theIndex, theGroupIndex, thisAngle, horizontalOffset, verticalOffset, horScale, verScale) {

                                          // duplicate by index;

                                          // =======================================================

                                          var idmove = charIDToTypeID( "move" );

                                              var desc8 = new ActionDescriptor();

                                              var idnull = charIDToTypeID( "null" );

                                                  var ref8 = new ActionReference();

                                                  var idLyr = charIDToTypeID( "Lyr " );

                                                  ref8.putIdentifier( charIDToTypeID( "Lyr " ), theIndex );

                                              desc8.putReference( idnull, ref8 );

                                              var idT = charIDToTypeID( "T   " );

                                                  var ref9 = new ActionReference();

                                                  var idLyr = charIDToTypeID( "Lyr " );

                                                  ref9.putIndex( idLyr, theGroupIndex );

                                              desc8.putReference( idT, ref9 );

                                              var idDplc = charIDToTypeID( "Dplc" );

                                              desc8.putBoolean( idDplc, true );

                                              var idAdjs = charIDToTypeID( "Adjs" );

                                              desc8.putBoolean( idAdjs, false );

                                              var idVrsn = charIDToTypeID( "Vrsn" );

                                              desc8.putInteger( idVrsn, 5 );

                                          executeAction( idmove, desc8, DialogModes.NO );

                                          // do the transformations;

                                          // =======================================================

                                          var idTrnf = charIDToTypeID( "Trnf" );

                                              var desc3 = new ActionDescriptor();

                                              var idnull = charIDToTypeID( "null" );

                                                  var ref2 = new ActionReference();

                                                  var idLyr = charIDToTypeID( "Lyr " );

                                                  var idOrdn = charIDToTypeID( "Ordn" );

                                                  var idTrgt = charIDToTypeID( "Trgt" );

                                                  ref2.putEnumerated( idLyr, idOrdn, idTrgt );

                                              desc3.putReference( idnull, ref2 );

                                              var idFTcs = charIDToTypeID( "FTcs" );

                                              var idQCSt = charIDToTypeID( "QCSt" );

                                              var idQcsa = charIDToTypeID( "Qcsa" );

                                              desc3.putEnumerated( idFTcs, idQCSt, idQcsa );

                                              var idOfst = charIDToTypeID( "Ofst" );

                                                  var desc4 = new ActionDescriptor();

                                                  var idHrzn = charIDToTypeID( "Hrzn" );

                                                  var idPxl = charIDToTypeID( "#Pxl" );

                                                  desc4.putUnitDouble( idHrzn, idPxl, horizontalOffset );

                                                  var idVrtc = charIDToTypeID( "Vrtc" );

                                                  var idPxl = charIDToTypeID( "#Pxl" );

                                                  desc4.putUnitDouble( idVrtc, idPxl, verticalOffset );

                                              var idOfst = charIDToTypeID( "Ofst" );

                                              desc3.putObject( idOfst, idOfst, desc4 );

                                              var idWdth = charIDToTypeID( "Wdth" );

                                              var idPrc = charIDToTypeID( "#Prc" );

                                              desc3.putUnitDouble( idWdth, idPrc, horScale );

                                              var idHght = charIDToTypeID( "Hght" );

                                              var idPrc = charIDToTypeID( "#Prc" );

                                              desc3.putUnitDouble( idHght, idPrc, verScale );

                                          if (thisAngle != 0) {

                                              var idAngl = charIDToTypeID( "Angl" );

                                              var idAng = charIDToTypeID( "#Ang" );

                                              desc3.putUnitDouble( idAngl, idAng, thisAngle );

                                            };

                                          executeAction( idTrnf, desc3, DialogModes.NO );

                                          };

                                          ////// get netx in an array circularly //////

                                          function theNextInTheArray (theArray, theNumber) {

                                          if (theNumber < theArray.length - 1) {return theArray[theNumber]}

                                          else {

                                            var theNumber = theNumber - (Math.floor(theNumber / theArray.length )) * theArray.length;

                                            return theArray[theNumber]

                                            }

                                          };

                                          • 23. Re: script for distributing smart object instances along path for testing
                                            Lionel Drew Level 1

                                            Thank you very much.  I will let you know how things turn out.

                                             

                                            Regards

                                            Lionel

                                            • 24. Re: script for distributing smart object instances along path for testing
                                              DBarranca Level 4

                                              Thanks for sharing!

                                              Always interesting to look at your code.

                                               

                                              Davide

                                              • 25. Re: script for distributing smart object instances along path for testing
                                                Jodi_Frye Level 3

                                                Hey there I recently got back into playing with the old deco scripts we created back in 2012 when we were testing and creating them. I have a particular script that places patterns along a path that I really like. I'm still using CS6 but a couple of weeks ago I downloaded CC version and I really liked the ' Place Along Path ' in the Fill dialogue box of scripted patterns. It has a lot of nice options that my script does not have. I wish I knew who wrote the script back then but I have no clue. This particular script script places a pattern along a path and copies and flips it. For instance if your pattern is a horizontal leaf it will create a path that has leaves on both sides. I really like it but I miss not having the color random option that is in CC. I have no idea how to write scripts. All I ever do is edit the numbers... so I don't know how to add the option to this script. This is what the dialogue box looks like.

                                                 

                                                Path-Fill.jpg

                                                 

                                                 

                                                This is the script;

                                                 

                                                #target photoshop
                                                app.bringToFront();
                                                main();
                                                function main(){
                                                var updated=false;
                                                if(!documents.length) return;
                                                var file = File(Folder.temp +"/deco.pat");
                                                if(file.exists) file.remove();
                                                savePatterns( file );
                                                  file.open("r");
                                                  file.encoding = 'BINARY';
                                                  var str = file.read();
                                                  file.close();
                                                  var patterns=[];
                                                  var rex = /(\x00\w|\x00\d)(\x00\-|\x00\w|\x00\s|\x00\d)+\x00\x00\$[-a-z\d]+/g;
                                                  while ((result = rex.exec(str)) != null) {
                                                      var sp = result[0].toString().replace(/\x00/g, '').split('$');
                                                      var X = readInt16(str,(result.index+(result[0].length)+22));
                                                      var Y = readInt16(str,(result.index+(result[0].length)+18));
                                                    patterns.push([[sp[0]],[sp[1]],[X],[Y]]);      
                                                      }
                                                patterns=ReturnUniqueSortedList(patterns);
                                                file.remove();
                                                var win = new Window( 'dialog', 'Path Fill' );
                                                g = win.graphics;
                                                var myBrush = g.newBrush(g.BrushType.SOLID_COLOR, [0.99, 0.99, 0.99, 1]);
                                                g.backgroundColor = myBrush;
                                                win.p1= win.add("panel", undefined, undefined, {borderStyle:"black"});
                                                win.g1 = win.p1.add('group');
                                                win.g1.orientation = "row";
                                                win.title = win.g1.add('statictext',undefined,'Path Fill');
                                                win.title.alignment="fill";
                                                var g = win.title.graphics;
                                                g.font = ScriptUI.newFont("Georgia","BOLD",22);
                                                win.g5 =win.p1.add('group');
                                                win.g5.orientation = "row";
                                                win.g5.alignment='fill';
                                                win.g5.spacing=10;
                                                win.g5.st1 = win.g5.add('statictext',undefined,'Spacing pattern (in pixels): ');
                                                win.g5.st1.preferredSize=[250,20];
                                                win.g5.et1 = win.g5.add('edittext',undefined,'20,100');
                                                win.g5.et1.preferredSize=[200,20];
                                                win.g5.et1.onChanging = function() {
                                                  if (this.text.match(/[^,.\-\d]/)) {
                                                    this.text = this.text.replace(/[^,.\-\d]/g, '');
                                                  }
                                                };
                                                
                                                win.g6 =win.p1.add('group');
                                                win.g6.orientation = "row";
                                                win.g6.alignment='fill';
                                                win.g6.spacing=10;
                                                win.g6.st1 = win.g6.add('statictext',undefined,'Rotation pattern (in degrees): ');
                                                win.g6.st1.preferredSize=[250,20];
                                                win.g6.et1 = win.g6.add('edittext',undefined,'60,-60');
                                                win.g6.et1.preferredSize=[200,20];
                                                win.g6.et1.onChanging = function() {
                                                  if (this.text.match(/[^,.\-\d]/)) {
                                                    this.text = this.text.replace(/[^,.\-\d]/g, '');
                                                  }
                                                };
                                                
                                                win.g7 =win.p1.add('group');
                                                win.g7.orientation = "row";
                                                win.g7.alignment='fill';
                                                win.g7.spacing=10;
                                                win.g7.st1 = win.g7.add('statictext',undefined,'Size Factor Pattern : ');
                                                win.g7.st1.preferredSize=[250,20];
                                                win.g7.et1 = win.g7.add('edittext',undefined,'1,.9,.8');
                                                win.g7.et1.preferredSize=[200,20];
                                                win.g7.et1.onChanging = function() {
                                                  if (this.text.match(/[^,.\-\d]/)) {
                                                    this.text = this.text.replace(/[^,.\-\d]/g, '');
                                                  }
                                                };
                                                
                                                win.g11 =win.p1.add('group');
                                                win.g11.orientation = "row";
                                                win.g11.alignment='fill';
                                                win.g11.spacing=10;
                                                win.g11.st1 = win.g11.add('statictext',undefined,'Mirror Pattern : ');
                                                win.g11.st1.preferredSize=[250,20];
                                                win.g11.et1 = win.g11.add('edittext',undefined,'1,-1');
                                                win.g11.et1.preferredSize=[200,20];
                                                win.g11.et1.onChanging = function() {
                                                  if (this.text.match(/[^,.\-\d]/)) {
                                                    this.text = this.text.replace(/[^,.\-\d]/g, '');
                                                  }
                                                };
                                                
                                                win.g8 =win.p1.add('group');
                                                win.g8.orientation = "row";
                                                win.g8.alignment='fill';
                                                win.g8.spacing=10;
                                                win.g8.st1 = win.g8.add('statictext',undefined,'Parallel offset factor pattern: ');
                                                win.g8.st1.preferredSize=[250,20];
                                                win.g8.et1 = win.g8.add('edittext',undefined,'1');
                                                win.g8.et1.preferredSize=[200,20];
                                                win.g8.et1.onChanging = function() {
                                                  if (this.text.match(/[^,.\-\d]/)) {
                                                    this.text = this.text.replace(/[^,.\-\d]/g, '');
                                                  }
                                                };
                                                
                                                
                                                
                                                
                                                
                                                win.g9 =win.p1.add('group');
                                                win.g9.orientation = "row";
                                                win.g9.alignment='fill';
                                                win.g9.spacing=10;
                                                win.g9.st1 = win.g9.add('statictext',undefined,'Final pattern size factor: ');
                                                win.g9.st1.preferredSize=[250,20];
                                                win.g9.et1 = win.g9.add('edittext',undefined,'1');
                                                win.g9.et1.preferredSize=[50,20];
                                                win.g9.et1.onChanging = function() {
                                                  if (this.text.match(/[^\-\.\d]/)) {
                                                    this.text = this.text.replace(/[^\-\.\d]/g, '');
                                                  }
                                                };
                                                win.g10 =win.p1.add('group');
                                                win.g10.orientation = "row";
                                                win.g10.alignment='fill';
                                                win.g10.st1 = win.g10.add('statictext',undefined,'Please select Pattern:');
                                                win.g10.st1.preferredSize=[250,20];
                                                win.g10.dd1 = win.g10.add('dropdownlist');
                                                for(var p in patterns){win.g10.dd1.add('item',patterns[p][0]);}
                                                win.g10.dd1.selection=0;
                                                win.g10.dd1.onChange = function(){
                                                var str = patterns[win.g10.dd1.selection.index][0].toString() + " ( X = " ;
                                                str += Number(patterns[win.g10.dd1.selection.index][2]) + " Y = ";
                                                str += Number(patterns[win.g10.dd1.selection.index][3]) + ")";
                                                win.g10.dd1.helpTip = str;
                                                }
                                                win.g10.dd1.onChange();
                                                win.g15 =win.p1.add('group');
                                                win.g15.orientation = "row";
                                                win.g15.alignment='fill';
                                                var Blend = ['Normal','Dissolve','-','Darken','Multiply','Color Burn','Linear Burn','Darker Color','-','Lighten','Screen','Color Dodge',
                                                    'Linear Dodge (Add)','Lighter Color','-','Overlay','Soft Light','Hard Light','Vivid Light','Linear Light', 'Pin Light','Hard Mix','-','Difference', 'Exclusion',
                                                    'Subtract','Divide','-','Hue','Saturation','Color','Luminosity'];
                                                var bMode=['Nrml','Dslv','-','Drkn','Mltp','CBrn','linearBurn','darkerColor','-','Lghn', 'Scrn',
                                                'CDdg','linearDodge','lighterColor','-','Ovrl','SftL','HrdL','vividLight','linearLight','pinLight','hardMix','-',
                                                'Dfrn','Xclu','blendSubtraction','blendDivide','-','H   ','Strt','Clr ','Lmns'];
                                                win.g15.st1 = win.g15.add('statictext',undefined,'Blend Mode:');
                                                win.g15.st1.preferredSize=[250,20];
                                                win.g15.dd1 = win.g15.add('dropdownlist',undefined,Blend);
                                                win.g15.dd1.selection=0;
                                                win.g20 =win.p1.add('group');
                                                win.g20.orientation = "row";
                                                win.g20.alignment='fill';
                                                win.g20.st1 = win.g20.add('statictext',undefined,'Opacity:');
                                                win.g20.st1.preferredSize=[250,20];
                                                win.g20.et1 = win.g20.add('edittext',undefined,'100');
                                                win.g20.et1.preferredSize=[50,20];
                                                win.g20.et1.onChanging = function() {
                                                  if (this.text.match(/[^\-\.\d]/)) {
                                                    this.text = this.text.replace(/[^\-\.\d]/g, '');
                                                  }
                                                };
                                                var pictureFlag = true          //flag about whether you choose to select patterns by name or by picture
                                                win.g100 =win.p1.add('group');
                                                win.g100.orientation = "row";
                                                win.g100.alignment='center';
                                                win.g100.bu1 = win.g100.add('button',undefined,'Update');
                                                win.g100.bu1.preferredSize=[150,30];
                                                win.g100.bu3 = win.g100.add('button',undefined,'See pattern pictures');
                                                win.g100.bu3.preferredSize=[150,30];
                                                win.g100.bu2 = win.g100.add('button',undefined,'Close');
                                                win.g100.bu2.onClick=function(){
                                                    win.close(0);
                                                }
                                                
                                                win.g100.bu2.preferredSize=[150,30];
                                                win.g100.bu1.onClick=function(){
                                                if(win.g5.et1.text == ''){
                                                   alert("Your spacing cannot be blank");
                                                    return;
                                                    }
                                                //if(isNaN(Number(win.g5.et1.text) )){
                                                //   alert("Your entry for the spacing is not a number");
                                                //  return;
                                                //  }
                                                if(win.g9.et1.text == ''){
                                                    alert("Your final size specification cannot be blank");
                                                    return;
                                                    }
                                                if(isNaN(Number(win.g9.et1.text) )){
                                                    alert("Your entry for the final size is not a number");
                                                    return;
                                                    }
                                                if(ScriptUI.environment.keyboardState.shiftKey){
                                                    win.close(0);
                                                    }
                                                pictureFlag = false;
                                                
                                                if (updated==true){
                                                executeAction( charIDToTypeID('undo'), undefined, DialogModes.NO );
                                                }
                                                updated=true;
                                                doit(pictureFlag);
                                                app.refresh();
                                                }       //end finction for using the patterns by name
                                                
                                                win.g100.bu3.onClick=function(){
                                                //if(win.g5.et1.text == ''){
                                                  //  alert("Your spacing cannot be blank");
                                                  //  return;
                                                  //  }
                                                
                                                if(win.g9.et1.text == ''){
                                                    alert("Your final size specification cannot be blank");
                                                    return;
                                                    }
                                                if(isNaN(Number(win.g9.et1.text) )){
                                                    alert("Your entry for the final size is not a number");
                                                    return;
                                                    }
                                                
                                                pictureFlag = true;
                                                if(!ScriptUI.environment.keyboardState.shiftKey) win.close(0);
                                                doit(pictureFlag);
                                                app.refresh();
                                                }       //end finction for using the patterns by pictures - through the fill dialog box
                                                //}       //closing brace to end main
                                                
                                                function doit(useFillBoxFlag) {
                                                // Save the current preferences
                                                var startRulerUnits = app.preferences.rulerUnits;
                                                var startTypeUnits = app.preferences.typeUnits;
                                                var startDisplayDialogs = app.displayDialogs;
                                                // Set Adobe Photoshop CS6 to use pixels and display no dialogs
                                                app.preferences.rulerUnits = Units.PIXELS;
                                                app.preferences.typeUnits = TypeUnits.PIXELS;
                                                //app.displayDialogs = DialogModes.NO;
                                                
                                                var activePath=activePathIndex()
                                                if (activePath=-1)activePath=0;
                                                myPath=activeDocument.pathItems[activePathIndex()].subPathItems[0]; //I'm just calculating the first subpath of the active path
                                                
                                                var scriptEndSize = Number(win.g9.et1.text);   //factor of Final pattern size
                                                
                                                var spacing=[];
                                                spacing = win.g5.et1.text.match(/[0-9.]+/g);
                                                
                                                for (var i =0; i< spacing.length; i++){
                                                       spacing[i]=parseFloat(spacing[i]);
                                                   }
                                                
                                                
                                                
                                                spacedPoints= new Array;    //The position of each of the equally spaced points
                                                rotations = new Array;       //The rotation of each of the equally spaced points
                                                sizes = new Array;
                                                mirrors=new Array;
                                                
                                                
                                                //accuracy of calculation... how many straight line segments each curved segment is split into.
                                                var granularity = 100;
                                                
                                                var results = new Array; //points of the straight line segment.... these aren't evenly spaced.
                                                var pointCount=myPath.pathPoints.length-1;
                                                
                                                //Approximate Path by dividing into straight line segments
                                                var d = myPath.pathPoints[0].anchor;
                                                for(var i = 0; i< pointCount; i++)
                                                {
                                                    var a = d
                                                    var b = myPath.pathPoints[i].leftDirection;
                                                    var c = myPath.pathPoints[i+1].rightDirection;
                                                    var d = myPath.pathPoints[i+1].anchor; 
                                                    for (var j =0; j < granularity; j++)
                                                    {
                                                        var t = j/granularity;
                                                        results[i*granularity + j] = bezier (a, b, c, d, t);
                                                    }
                                                }
                                                
                                                // Calculate the last path segment if the path is closed.... same code as above
                                                if(myPath.closed==true){
                                                    var a = myPath.pathPoints[pointCount].anchor
                                                    var b = myPath.pathPoints[pointCount].leftDirection;
                                                    var c = myPath.pathPoints[0].rightDirection;
                                                    var d = myPath.pathPoints[0].anchor; 
                                                    for (var j =0; j < granularity; j++)
                                                    {
                                                        var t = j/granularity;
                                                        results[pointCount*granularity + j] = bezier (a, b, c, d, t);
                                                    }
                                                }
                                                
                                                spacedPoints[0]=(0,0)
                                                var totalEq=0;
                                                
                                                //Calculate the length of the curve up to each point
                                                var segmentLength= new Array;
                                                segmentLength[0]=0;
                                                var totalLength=segmentLength[0];
                                                for(var i = 0; i < results.length-1; i++)
                                                {
                                                    segmentLength[i+1]= segmentLength[i]+Math.sqrt(Math.pow(results[i][0]-results[i+1][0],2) + Math.pow(results[i][1]-results[i+1][1],2));
                                                }
                                                
                                                //Points aren't equally distributed, This makes an array of equally spaced points
                                                var spacingCount=0;
                                                var count = 0;
                                                var count2 = 0;
                                                var fullLength=segmentLength[segmentLength.length-1]
                                                
                                                //adjust spacing so it will devide evenly into the full length of a closed path
                                                /*
                                                if(myPath.closed==true){
                                                    spacing = fullLength / Math.round(fullLength/spacing)
                                                }
                                                */
                                                
                                                
                                                while(totalEq < segmentLength[segmentLength.length-1]){
                                                    while(totalEq>=segmentLength[count+1])
                                                    {
                                                        //alert(totalEq+"\n"+segmentLength[count+1])
                                                        count++;           
                                                    }
                                                    while(segmentLength[count+1]>=totalEq && totalEq < segmentLength[segmentLength.length-1])
                                                    { 
                                                        spacedPoints[count2]= lerp(results[count],results[count+1], (totalEq-segmentLength[count]) / (segmentLength[count+1]-segmentLength[count]));
                                                        rotations[count2]= Math.atan2 ((results[count+1][1]-results[count][1]),(results[count+1][0]-results[count][0]))*(180/Math.PI);
                                                        if(rotations[count2]<0)rotations[count2]+=360
                                                        sizes[count2]=1;
                                                      
                                                        totalEq+=spacing[spacingCount];
                                                        spacingCount++;
                                                        if (spacingCount==spacing.length) spacingCount=0
                                                       
                                                        //Create a count item to show where the points are
                                                        //activeDocument.countItems.add(spacedPoints[count2]);
                                                
                                                        count2++;
                                                    }
                                                }
                                                if(ScriptUI.environment.keyboardState.ctrlKey){
                                                spacedPoints = spacedPoints.reverse();
                                                }
                                                
                                                var rotationPattern=[];
                                                rotationPattern = win.g6.et1.text.match(/-?[0-9.]+/g);
                                                rotationCount=0;
                                                
                                                var mirrorPattern=[];
                                                mirrorPattern = win.g11.et1.text.match(/-?[0-9.]+/g);
                                                mirrorCount=0;
                                                
                                                var offsetPattern=[]
                                                offsetPattern = win.g8.et1.text.match(/-?[0-9.]+/g);
                                                offsetCount=0;
                                                
                                                var sizingPattern=[]
                                                sizingPattern = win.g7.et1.text.match(/-?[0-9.]+/g);
                                                sizingCount=0
                                                
                                                
                                                for (var i =0; i< rotationPattern.length; i++){
                                                    rotationPattern[i]=parseFloat(rotationPattern[i]);
                                                }
                                                for (var i =0; i< sizingPattern.length; i++){
                                                    sizingPattern[i]=parseFloat(sizingPattern[i]);
                                                }
                                                for (var i =0; i< mirrorPattern.length; i++){
                                                    mirrorPattern[i]=parseFloat(mirrorPattern[i]);
                                                }
                                                for (var i =0; i< offsetPattern.length; i++){
                                                    offsetPattern[i]=parseFloat(offsetPattern[i]);
                                                }
                                                
                                                for(var i=0;i<rotations.length;i++){
                                                    rotations[i]+=rotationPattern[rotationCount++]
                                                    if (rotationCount==rotationPattern.length)rotationCount=0;  
                                                  
                                                       sizes[i]*=sizingPattern[sizingCount++]
                                                     
                                                       sizes[i]*=(1-scriptEndSize)*(rotations.length-i)/rotations.length + scriptEndSize
                                                       //var scale = (100 - endsize)*(totalPointCount - n)/totalPointCount + endsize
                                                     
                                                     
                                                   if (sizingCount==sizingPattern.length)sizingCount=0;
                                                  
                                                   spacedPoints[i][0]+= Math.cos(rotations[i]*(Math.PI/180)) * offsetPattern[offsetCount]*Number(patterns[win.g10.dd1.selection.index][2])*sizes[i]
                                                   spacedPoints[i][1]+= Math.sin(rotations[i]*(Math.PI/180)) * offsetPattern[offsetCount++]*Number(patterns[win.g10.dd1.selection.index][2])*sizes[i]
                                                
                                                   if (offsetCount==offsetPattern.length)offsetCount=0;
                                                
                                                
                                                   mirrors[i]=mirrorPattern[mirrorCount++]
                                                   if (mirrorCount==mirrorPattern.length)mirrorCount=0;
                                                   }
                                                
                                                
                                                
                                                Math.cos(45*(Math.PI/180))
                                                
                                                
                                                
                                                
                                                //set temp vars in memory
                                                $.setenv("DECOpoints","var points = ["+spacedPoints.toString()+"];");
                                                $.setenv("DECOrotations","var rotations = ["+rotations.toString()+"];");
                                                $.setenv("DECOsizes","var sizes = ["+sizes.toString()+"];");
                                                $.setenv("DECOmirrors","var mirrors = ["+mirrors.toString()+"];");
                                                
                                                // Reset the application preferences
                                                app.preferences.rulerUnits = startRulerUnits;
                                                app.preferences.typeUnits = startTypeUnits;
                                                app.displayDialogs = startDisplayDialogs;
                                                //call fill menu
                                                var Name = patterns[win.g10.dd1.selection.index][0];
                                                var PatID = patterns[win.g10.dd1.selection.index][1];
                                                var BMODE = bMode[win.g15.dd1.selection.index];
                                                var Opacity = Number(win.g20.et1.text);
                                                if(Opacity > 100) Opacity = 100;
                                                if(Opacity < 0) Opacity = 0;
                                                
                                                decoFill(Name,PatID,BMODE,Opacity,useFillBoxFlag);
                                                }
                                                win.center();
                                                win.show();
                                                }
                                                function bezier(a,b,c,d,t)
                                                {
                                                    var ab,bc,cd,abbc,bccd;
                                                    ab = lerp(a,b,t);
                                                    bc = lerp(b,c,t);
                                                    cd = lerp(c,d,t);
                                                    abbc = lerp(ab,bc,t);
                                                    bccd = lerp(bc,cd,t);
                                                    return lerp(abbc,bccd,t);
                                                }
                                                
                                                function lerp(a,b,t)
                                                {
                                                    var x = a[0] + (b[0]-a[0])*t;
                                                    var y = a[1] + (b[1]-a[1])*t;
                                                    return [x,y];  
                                                }
                                                function readByte(str, ofs) {
                                                    return str.charCodeAt(ofs);
                                                  }
                                                function readInt16(str, ofs) {
                                                    return (readByte(str, ofs) << 8) + readByte(str, ofs+1);
                                                  }
                                                function activePathIndex(){// returns -1 if no path active/selective
                                                   try{
                                                      var ref = new ActionReference();
                                                      ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
                                                      var desc = executeActionGet( ref );
                                                      return  desc.getInteger(charIDToTypeID("TrgP" ));
                                                   }catch(e){}
                                                };
                                                function decoFill(Name,PatID,BMODE,Opacity,useFillBoxFlag) {
                                                         if(BMODE.length> 4) {
                                                        var blendMode ="stringIDToTypeID(BMODE);";
                                                        }else{
                                                            var blendMode = "charIDToTypeID(BMODE);";
                                                            }
                                                    var desc16 = new ActionDescriptor();
                                                    desc16.putEnumerated( charIDToTypeID('Usng'), charIDToTypeID('FlCn'), charIDToTypeID('Ptrn') );
                                                        var desc17 = new ActionDescriptor();
                                                        desc17.putString( charIDToTypeID('Nm  '), Name.toString());
                                                        desc17.putString( charIDToTypeID('Idnt'), PatID.toString());
                                                    desc16.putObject( charIDToTypeID('Ptrn'), charIDToTypeID('Ptrn'), desc17 );
                                                    desc16.putPath( stringIDToTypeID('decoScriptFile'), new File( app.path +"/Presets/Deco/Path_Deco.jsx" ) );
                                                    desc16.putUnitDouble( charIDToTypeID('Opct'), charIDToTypeID('#Prc'), Number(Opacity) );
                                                    desc16.putEnumerated( charIDToTypeID('Md  '), charIDToTypeID('BlnM'), eval(blendMode));
                                                    try{
                                                        if (useFillBoxFlag) {
                                                    executeAction( charIDToTypeID('Fl  '), desc16, DialogModes.ALL )}
                                                        else {
                                                    executeAction( charIDToTypeID('Fl  '), desc16, DialogModes.NO )}
                                                    }catch(e){alert(e+" - "+ e.line);}
                                                };
                                                function savePatterns( file ) {
                                                    var desc = new ActionDescriptor();
                                                    desc.putPath( charIDToTypeID( "null" ), new File(file) );
                                                        var ref = new ActionReference();
                                                        ref.putProperty( charIDToTypeID( "Prpr" ), charIDToTypeID( "Ptrn" ) );
                                                        ref.putEnumerated( charIDToTypeID( "capp" ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ) );
                                                    desc.putReference( charIDToTypeID( "T   " ), ref );
                                                executeAction( charIDToTypeID( "setd" ), desc, DialogModes.NO );
                                                };
                                                function ReturnUniqueSortedList(ArrayName){
                                                var unduped = new Object;
                                                for (var i = 0; i < ArrayName.length; i++) { 
                                                unduped[ArrayName[i]] = ArrayName[i];
                                                }
                                                var uniques = new Array;for (var k in unduped) {
                                                   uniques.push(unduped[k]);}
                                                return uniques.sort();
                                                }
                                                

                                                 

                                                _____

                                                 

                                                If you could point me in the write direction to learn how to edit scripts and add the color random option I'd REALLY REALLY appreciate it !  Thanks so much !

                                                -Jodi

                                                 

                                                PS I really like your script of having smart objects follow a path ! Very cool !!

                                                • 27. Re: script for distributing smart object instances along path for testing
                                                  Chuck Uebele Adobe Community Professional & MVP

                                                  Richard Kain wrote those scripts, I believe.

                                                  • 28. Re: script for distributing smart object instances along path for testing
                                                    Jodi_Frye Level 3

                                                    Hi Chuck !   I just found the old post and the user profile of the person who created it is Yelnats1 but I can't find further info on this individual's profile so I'm not sure if it is in fact Richard Kain. Thanks though as maybe I can look him up and see if he's the author. Thank you !

                                                     

                                                    Edit; I've been playing with your fill script quite a bit lately as well Chuck...that very neat one you wrote way back when.. 

                                                    • 29. Re: script for distributing smart object instances along path for testing
                                                      Jodi_Frye Level 3

                                                      Chuck you responded to his post where he shares this script and you called him ' David ' ...  Any ideas ??

                                                      • 30. Re: script for distributing smart object instances along path for testing
                                                        Chuck Uebele Adobe Community Professional & MVP

                                                        Do you have a link to the discussion?

                                                        • 31. Re: script for distributing smart object instances along path for testing
                                                          Jodi_Frye Level 3

                                                          yup !

                                                          Additional scripted patterns

                                                           

                                                          What is a downer is the links on Radomir's write up on the deco engine are all dead links... the documentation at bottom of page for writing deco scripts and the links to other scripts are dead too. That's what happens when I dig into the past ;/

                                                          Adobe Research » Deco Scripted Patterns in Photoshop

                                                          1 person found this helpful
                                                          • 32. Re: script for distributing smart object instances along path for testing
                                                            Chuck Uebele Adobe Community Professional & MVP

                                                            David's last name is eluding me.

                                                            1 person found this helpful
                                                            • 33. Re: script for distributing smart object instances along path for testing
                                                              Jodi_Frye Level 3

                                                              That's fine Chuck. I'll try to figure it out.  I know there was much more info available back then on writing these deco scripts. Thanks so much !  

                                                              • 34. Re: script for distributing smart object instances along path for testing
                                                                pixxxel schubser MVP & Adobe Community Professional

                                                                Perhaps your link is the answer

                                                                 

                                                                davidjensen

                                                                2 people found this helpful
                                                                • 35. Re: script for distributing smart object instances along path for testing
                                                                  Jodi_Frye Level 3

                                                                  OMG how ????

                                                                      

                                                                      

                                                                   

                                                                  Thank you !!!!

                                                                  • 36. Re: script for distributing smart object instances along path for testing
                                                                    Chuck Uebele Adobe Community Professional & MVP

                                                                    Thanks, pixxxel schubser! That's it. Jensen.

                                                                    • 37. Re: script for distributing smart object instances along path for testing
                                                                      Chuck Uebele Adobe Community Professional & MVP

                                                                      Jodi, did you want to edit a deco script or make a script that places shapes, or other layers along a path?

                                                                      • 38. Re: script for distributing smart object instances along path for testing
                                                                        Jodi_Frye Level 3

                                                                        Well Chuck I really just wanted to add a color random option to the script that David wrote. The one I posted earlier. I like color variations when creating these paths. I like the way it's done in CC but I don't have that version now. I'm still using CS6.  I was hoping to find some documention on writing these scripts. They were posted a while back and the links I found are dead. After all this time I really didn't want to bother the original author. It's just for personal use.

                                                                        • 39. Re: script for distributing smart object instances along path for testing
                                                                          Chuck Uebele Adobe Community Professional & MVP

                                                                          It's always hard for me to dissect someone else's script. I'm not sure, but it doesn't look like David's used Radomir's deco fill API but used the generic Photoshop javascript. With Radomir's method, you could add the color variation easily. I'm not sure how you could go about that with David's script, or if you can. 

                                                                          1 person found this helpful
                                                                          1 2 Previous Next