7 Replies Latest reply on Jan 20, 2017 2:54 AM by arteangelus

    Photoshop Script similar to Illustrator Blend Tool for Paths?

    arteangelus Level 1

      Hello,

       

      For learning purposes I would like to create intersection path(s) between subpaths of a mainpath using extendscript.

      screenshot.png

      I guess I have to find difference of each points' coordinates and draw a new line using these information. (Actually it would be much more better if it has step options like in Illustrator Blend Tool.) But since I am beginner (learning scripting) I got confused with arrays. It is being an array inside an array.

       

      I tried two ways, none of them is completed. Since there is no certain point number for subpaths those array should be inside for loops I suppose

       

      Please help;

      Here is my hopeless tryout...

       

      #target photoshop
      app.bringToFront();
      displayDialogs = DialogModes.NO; // Don't Display Dialog
      
      
      if(documents.length==0){
         alert("Please open a document and add path in order to run this script")
      }else{ 
      
      
      var doc = app.activeDocument;
      if (doc.pathItems.length == 0) {alert ('Please add one path');}
      else {
          
              if (doc.pathItems[0].name == "Work Path") {
              // Convert Work Path to Path
              doc.pathItems[0].name = "Path"
              }
      targetpath = doc.pathItems.getByName('Path');
      var subpathscount = targetpath.subPathItems.length; // Count of subpaths
      
      
      // First Path
      function extractSubPathInfo1(pathObj){  
          var pathArray1 = new Array();
          var pl2 = pathObj.subPathItems.length;  
          for(var s1=0;s1<pl1;s1++){  
              var pArray = new Array();  
                for(var i1=0;i1<pathObj.subPathItems[0].pathPoints.length;i1++){  
                   pArray1[i1] = new PathPointInfo;  
                   pArray1[i1].kind = pathObj.subPathItems[0].pathPoints[i1].kind;  
                   pArray1[i1].anchor = pathObj.subPathItems[0].pathPoints[i1].anchor;  
                   pArray1[i1].leftDirection = pathObj.subPathItems[0].pathPoints[i1].leftDirection;  
                   pArray1[i1].rightDirection = pathObj.subPathItems[0].pathPoints[i1].rightDirection;  
                };  
              pathArray1[pathArray.length] = new Array();  
              pathArray1[pathArray.length - 1] = new SubPathInfo();  
              pathArray1[pathArray.length - 1].operation = pathObj.subPathItems[0].operation;  
              pathArray1[pathArray.length - 1].closed = pathObj.subPathItems[0].closed;  
              pathArray1[pathArray.length - 1].entireSubPath = pArray1;  
          };  
          return pathArray1;  
      };
      
      
      // Second Path
      function extractSubPathInfo2(pathObj){  
          var pathArray2 = new Array();
          var pl2 = pathObj.subPathItems.length;  
          for(var s2=0;s2<pl2;s2++){  
              var pArray2 = new Array();  
                for(var i2=0;i2<pathObj.subPathItems[1].pathPoints.length;i2++){  
                   pArray2[i2] = new PathPointInfo;  
                   pArray2[i2].kind = pathObj.subPathItems[1].pathPoints[i2].kind;  
                   pArray2[i2].anchor = pathObj.subPathItems[1].pathPoints[i2].anchor;  
                   pArray2[i2].leftDirection = pathObj.subPathItems[1].pathPoints[i2].leftDirection;  
                   pArray2[i2].rightDirection = pathObj.subPathItems[1].pathPoints[i2].rightDirection;  
                };  
              pathArray2[pathArray2.length] = new Array();  
              pathArray2[pathArray2.length - 1] = new SubPathInfo();  
              pathArray2[pathArray2.length - 1].operation = pathObj.subPathItems[1].operation;  
              pathArray2[pathArray2.length - 1].closed = pathObj.subPathItems[1].closed;  
              pathArray2[pathArray2.length - 1].entireSubPath = pArray2;  
          };  
          return pathArray2;  
      };
      
      firstpathpointcount = targetpath.subPathItems[0].pathPoints.length;
      secondpathpointcount= targetpath.subPathItems[1].pathPoints.length;
      var firstpathrightdirectionarray= new Array();
      var firstpathleftdirectionarray = new Array();
      
      var a0xy =  new Array();
      var a0x =  new Array();
      var a0y =  new Array();
      
      var a1xy =  new Array();
      var a1x =  new Array();
      var a1y =  new Array();
      
      var a2xy =  new Array();
      var a2x =  new Array();
      var a2y =  new Array();
      
      a0xy.push(targetpath.subPathItems[0].pathPoints[0].leftDirection);
      a0x=  a0xy[0].toString().split(",")[0];
      a0y=  a0xy[0].toString().split(",")[1];
      
      a1xy.push(targetpath.subPathItems[0].pathPoints[1].leftDirection);
      a1x=  a0xy[0].toString().split(",")[0];
      a1y=  a0xy[0].toString().split(",")[1];
      
      a2xy.push(targetpath.subPathItems[0].pathPoints[2].leftDirection);
      a2x=  a0xy[0].toString().split(",")[0];
      a2y=  a0xy[0].toString().split(",")[1];
      
      var b0xy =  new Array();
      var b0x =  new Array();
      var b0y =  new Array();
      
      var b1xy =  new Array();
      var b1x =  new Array();
      var b1y =  new Array();
      
      var b2xy =  new Array();
      var b2x =  new Array();
      var b2y =  new Array();
      
      b0xy.push(targetpath.subPathItems[1].pathPoints[0].leftDirection);
      b0x=  b0xy[0].toString().split(",")[0];
      b0y=  b0xy[0].toString().split(",")[1];
      
      b1xy.push(targetpath.subPathItems[1].pathPoints[1].leftDirection);
      b1x=  b1xy[0].toString().split(",")[0];
      b1y=  b1xy[0].toString().split(",")[1];
      
      b2xy.push(targetpath.subPathItems[1].pathPoints[2].leftDirection);
      b2x=  b2xy[0].toString().split(",")[0];
      b2y=  b2xy[0].toString().split(",")[1];
      
      alert (b0x - a0x);
      

       

       

       

       

       

       

       

      }

      }

        • 1. Re: Photoshop Script similar to Illustrator Blend Tool for Paths?
          Chuck Uebele Adobe Community Professional & MVP

          Scripting paths if PS is a bit of a pain. What is your final result you want by creating these blended paths in PS. I might be easier to use IA and import them into PS. I was playing around with paths in IA and PS. I wanted to do some scripting of shapes in PS, but the ability to script the paths the way I wanted was too difficult or just didn't work. I ended up creating the paths in IA, the converting the paths coordinates into an XML file that I redrew in PS as shape layers that I could then apply color to based on a reference layer in PS.

          1 person found this helpful
          • 2. Re: Photoshop Script similar to Illustrator Blend Tool for Paths?
            arteangelus Level 1

            Hello Chuck,

             

            Thank you for your answer and example;

             

            But still I want to learn;

             

            I have changed my previous script slightly (still not working). Would anyone please check and tell me what am I doing wrong ?

             

            Thank you,

            Best Regards.

             

            Here is my updated not working script ;

             

            #target photoshop
            app.bringToFront();
            displayDialogs = DialogModes.NO; // Don't Display Dialog
            
            
            if(documents.length==0){
               alert("Please open a document and add path in order to run this script")
            }else{ 
            
            
            var doc = app.activeDocument;
            if (doc.pathItems.length == 0) {alert ('Please add one path');}
            else {
                
                    if (doc.pathItems[0].name == "Work Path") {
                    // Convert Work Path to Path
                    doc.pathItems[0].name = "Path"
                    }
            targetpath = doc.pathItems.getByName('Path');
            var subpathscount = targetpath.subPathItems.length; // Count of subpaths
            
            
            var l1x = [];
            var l1y = [];
            var l2x = [];
            var l2y = [];
            var r1x = [];
            var r1y = [];
            var r2x = [];
            var r2y = [];
                            
            // Second Path
            function extractSubPathInfo(pathObj){
                // Path 1
                    
                var pl = pathObj.subPathItems.length;  
                
                for(var s=0;s<pl;s++){  
                                    var pathArray = new Array();
                                    
                      for(var i=0; i<pathObj.subPathItems[0].pathPoints.length;i++){
                            var pArray1 = new Array();  
                            var pArray2 = new Array();  
                            var pArray3 = new Array();
            
                           
                           var leftdifference = new Array();
                           var rightdifference = new Array();
                          
                          // Sub Path 1
                         pArray1[i] = new PathPointInfo;  
                         pArray1[i].kind = pathObj.subPathItems[0].pathPoints[i].kind;  
                         pArray1[i].anchor = pathObj.subPathItems[0].pathPoints[i].anchor;  
                         pArray1[i].leftDirection = pathObj.subPathItems[0].pathPoints[i].leftDirection;  
                         pArray1[i].rightDirection = pathObj.subPathItems[0].pathPoints[i].rightDirection;
                         // Sub Path 2
                         pArray2[i] = new PathPointInfo;  
                         pArray2[i].kind = pathObj.subPathItems[1].pathPoints[i].kind;  
                         pArray2[i].anchor = pathObj.subPathItems[1].pathPoints[i].anchor;  
                         pArray2[i].leftDirection = pathObj.subPathItems[1].pathPoints[i].leftDirection;  
                         pArray2[i].rightDirection = pathObj.subPathItems[1].pathPoints[i].rightDirection;
                         
                         // New Path Info
                         pArray3[i] = new PathPointInfo;  
                         pArray3[i].kind = pathObj.subPathItems[1].pathPoints[i].kind;  
                         pArray3[i].anchor = pathObj.subPathItems[1].pathPoints[i].anchor;
                         
                         // Left
                         l1x[i] = pArray1[i].leftDirection.toString().split(",")[0];
                         l1y[i] = pArray1[i].leftDirection.toString().split(",")[1];
                         l2x[i] = pArray2[i].leftDirection.toString().split(",")[0];
                         l2y[i] = pArray2[i].leftDirection.toString().split(",")[1];
                         alert (l1x[i]);
                         // Right
                         r1x[i] = pArray1[i].leftDirection.toString().split(",")[0];
                         r1y[i] = pArray1[i].leftDirection.toString().split(",")[1];
                         r2x[i] = pArray2[i].leftDirection.toString().split(",")[0];
                         r2y[i] = pArray2[i].leftDirection.toString().split(",")[1];
                         
                         leftdifference[i] = l1x[i] - l2x[i];
                         rightdifference[i] = r2x[i] - r2x[i];
                         pArray3[i].leftDirection = leftdifference[i];
                         pArray3[i].rightDirection = rightdifference[i];
                         
                      };
                  
                    var midpathArray = new Array();
                    midpathArray[pathArray.length] = new Array();  
                    midpathArray[pathArray.length - 1] = new SubPathInfo();  
                    midpathArray[pathArray.length - 1].operation = pathObj.subPathItems[0].operation;  
                    midpathArray[pathArray.length - 1].closed = pathObj.subPathItems[0].closed;  
                    midpathArray[pathArray.length - 1].entireSubPath = pArray3;  
                };  
                return midpathArray;  
                
            };  
            
            
            //a0xy.push(targetpath.subPathItems[0].pathPoints[0].leftDirection);
            //a0x=  a0xy[0].toString().split(",")[0];
            
            
            for(var spath=0;spath < subpathscount;spath++){ 
            var myPathInfo = extractSubPathInfo(targetpath,spath);
            newpathname = "New_Path_" + spath;
            var myPathItem = app.activeDocument.pathItems.add(newpathname, myPathInfo);
            }
            }
            }
            
            • 3. Re: Photoshop Script similar to Illustrator Blend Tool for Paths?
              c.pfaffenbichler Level 9

              A Path’s info is not just an Array (edit: at least I think so), so you would have to go the other way on creation.

               

              The following would work via DOM but AM code is usually faster (for an example see Re: Script for Transfering paths between documents?.. help ):

              ////// function to collect path-info as text //////

              function collectPathInfo (myDocument, thePath) {

              var originalRulerUnits = app.preferences.rulerUnits;

              app.preferences.rulerUnits = Units.POINTS;

              var theArray = [];

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

                theArray[b] = [];

                for (var c = 0; c < thePath.subPathItems[b].pathPoints.length; c++) {

                var pointsNumber = thePath.subPathItems[b].pathPoints.length;

                var theAnchor = thePath.subPathItems[b].pathPoints[c].anchor;

                var theLeft = thePath.subPathItems[b].pathPoints[c].leftDirection;

                var theRight = thePath.subPathItems[b].pathPoints[c].rightDirection;

                var theKind = thePath.subPathItems[b].pathPoints[c].kind;

                theArray[b][c] = [theAnchor, theLeft, theRight, theKind];

                };

                var theClose = thePath.subPathItems[b].closed;

                theArray = theArray.concat(String(theClose))

                };

              app.preferences.rulerUnits = originalRulerUnits;

              return theArray

              };

              ////// function to create path from array with one array per point that holds anchor, leftdirection, etc, 2010 //////

              function createPath (theArray, thePathsName) {

              var originalRulerUnits = app.preferences.rulerUnits;

              app.preferences.rulerUnits = Units.POINTS;

              lineSubPathArray = new Array ();

              if (theArray[theArray.length - 1].constructor != Array) {var numberOfSubPathItems = theArray.length - 1}

              else {var numberOfSubPathItems = theArray.length};

              for (var b = 0; b < numberOfSubPathItems; b++) {

                var lineArray = new Array ();

                for (c = 0; c < (theArray[b].length - 2); c++) {

                lineArray[c] = new PathPointInfo;

                if (!theArray[b][c][3]) {lineArray[c].kind = PointKind.CORNERPOINT}

                else {lineArray[c].kind = theArray[b][c][3]};

                lineArray[c].anchor = theArray[b][c][0];

                if (!theArray[b][c][1]) {lineArray[c].leftDirection = theArray[b][c][0]}

                else {lineArray[c].leftDirection = theArray[b][c][1]};

                if (!theArray[b][c][2]) {lineArray[c].rightDirection = theArray[b][c][0]}

                else {lineArray[c].rightDirection = theArray[b][c][2]};

                };

                lineSubPathArray[b] = new SubPathInfo();

                lineSubPathArray[b].closed = theArray[b][theArray[b].length - 2];

                lineSubPathArray[b].operation = theArray[b][theArray[b].length - 1];

                lineSubPathArray[b].entireSubPath = lineArray;

                };

              var myPathItem = app.activeDocument.pathItems.add(thePathsName, lineSubPathArray);

              app.preferences.rulerUnits = originalRulerUnits;

              return myPathItem

              };

              1 person found this helpful
              • 4. Re: Photoshop Script similar to Illustrator Blend Tool for Paths?
                c.pfaffenbichler Level 9
                I guess I have to find difference of each points' coordinates and draw a new line using these information. (Actually it would be much more better if it has step options like in Illustrator Blend Tool.)

                The issue may be more complicated if you consider that the subPathItems may have varying numbers of PathPoints.

                1 person found this helpful
                • 5. Re: Photoshop Script similar to Illustrator Blend Tool for Paths?
                  arteangelus Level 1

                  Thank you c.pfaffenbichler

                  I have found one video but unfortunately download link is not available.

                  That's actually what I am trying to do, and may be even further it can be added mid path numbers, incremental step options and etc. (like illustrator blend tool.)

                  As a non programmer it's really tough for me but on the other hand I'm curious to learn how to do it. So anyone interested in find a way I would gladly appreciate it.

                   

                  • 6. Re: Photoshop Script similar to Illustrator Blend Tool for Paths?
                    c.pfaffenbichler Level 9

                    Have you been able to track down the line creator Script?

                    In the video the two subPathItems seems to have the same number of PathPoints and I would like to know if and how it handles different numbers of PathPoints.

                    • 7. Re: Photoshop Script similar to Illustrator Blend Tool for Paths?
                      arteangelus Level 1

                      Hello,

                      Still could not find it unfortunately,

                      I guess path points should be equal in both splines.

                      And also there is a script using similar thing.( I suppose)

                      Perspective Tools for Photoshop CS6+ (1.2 update) - YouTube