8 Replies Latest reply on Jan 8, 2013 7:50 AM by mrmoka

    doc.pathItems return only selected layer path, not all.

    mrmoka

      Trying to iterate through all pathItems in specific document, and could not get any success.

      Just this small script will return "1" only if I select layer with actual path. Otherwise will be alway 0.

      But I need to get ALL pathItems from the document.

       

      CS5 Extended (v12.1 x64).

      Mac OS X 10.7.5

       

      Here is test code:

      #target photoshop
      app.bringToFront();
      if (app.documents.length > 0) {
          var doc = app.activeDocument;
      
          var res = "pathItems.length:\n";
          res += doc.pathItems.length;
      
          Window.alert(res);
      }
      

       

      What am I doint wrong?

      Iteration still will occur only on one pathItem, the one is manually selected in Photoshop.

      Selecting manually all layers wont make any difference.

       

      King Regards,

      Max

        • 1. Re: doc.pathItems return only selected layer path, not all.
          c.pfaffenbichler Level 9

          app.activeDocument.pathItems.length gets the number of pathItems of the document + the Vector Mask if the activeLayer has one.

          To determine the number of Vector Masks in a documente I guess you would have to work through the Layers.

          • 2. Re: doc.pathItems return only selected layer path, not all.
            Muppet Mark Level 5

            You script works as I would expect here… you don't need Window. btw

            • 3. Re: doc.pathItems return only selected layer path, not all.
              c.pfaffenbichler Level 9

              I adapted some code I have gotten from by Paul Riggott and it should get the number of Vecor Masks.

               

              // get number of vector masks;
              // adapted from code by paul riggott;
              // 2012, use it at your own risk;
              #target photoshop
              app.bringToFront();
              main();
              function main(){
              if(!documents.length) return;
              var vectorMasks = linkLayers();
              alert (vectorMasks.length);
              };
              function linkLayers(){
              var vectorMasks = new Array;
                 var ref = new ActionReference(); 
                 ref.putEnumerated( charIDToTypeID('Dcmn'), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') ); 
                 var count = executeActionGet(ref).getInteger(charIDToTypeID('NmbL')) +1; 
                 var Names=[];
              try{
                  activeDocument.backgroundLayer;
              var i = 0; }catch(e){ var i = 1; };
                 for(i;i<count;i++){ 
                     if(i == 0) continue;
                      ref = new ActionReference(); 
                      ref.putIndex( charIDToTypeID( 'Lyr ' ), i );
                      var desc = executeActionGet(ref);
                      var layerName = desc.getString(charIDToTypeID( 'Nm  ' ));
                      var Id = desc.getInteger(stringIDToTypeID( 'layerID' ));
                      if(layerName.match(/^<\/Layer group/) ) continue;
                      if(desc.getBoolean(stringIDToTypeID("hasVectorMask")) == true) {vectorMasks.push(i)};
                        };
              return vectorMasks
              };
              
              • 4. Re: doc.pathItems return only selected layer path, not all.
                mrmoka Level 1

                That makes sence based on what is going on. While documentation says a bit different:

                The collection of PathItem objects in a document.

                No mention about activeLayer.

                 

                Manage to do it. First try was to iterate through layers and activate them and then go through pathItems, but It didn't went well straight away, so I had to change the way of iterating though layers.

                Here is full code:

                It finds folder called "countries", then runs through each layer, pretending that they all are pathItems, and activates them, after activating generates data.

                var doc = app.activeDocument;

                var res = 'result' + "\n";

                var firstPath = true;

                var countries = doc.layers.getByName("countries");

                 

                var searching = true;

                var layerInd = 0;

                while(searching) {

                    if (countries.layers.length > layerInd) {

                        doc.activeLayer = countries.layers[layerInd];

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

                            var layer = doc.pathItems[l];

                            //res += layer.name + "\n";

                            if (firstPath) {

                                firstPath = false;

                            } else {

                                res += ",\n";

                            }

                            res += layer.name.substr(0, layer.name.length - 12) + ':[';

                            var firstSubPath = true;

                            for(var p = 0; p < layer.subPathItems.length; ++p) {

                                var subPath = layer.subPathItems[p];

                                if (!firstSubPath) {

                                    res += ',';

                                }

                                firstSubPath = false;

                                res += '[';

                                for(var i = 0; i < subPath.pathPoints.length; ++i) {

                                    var point = subPath.pathPoints[i];

                                    if (i != 0) {

                                        res += ',';

                                    }

                                    res += Math.round(point.anchor[0]) + ',' + Math.round(point.anchor[1]);

                                }

                                res += ']';

                            }

                            res += ']';

                        }

                        ++layerInd;

                    } else {

                        searching = false;

                    }

                }

                It is a bid messy and API is not stable at all, is CS6 situation better that CS5?

                • 5. Re: doc.pathItems return only selected layer path, not all.
                  c.pfaffenbichler Level 9

                  Sorry, I guess I have misinterpreted your original post.

                  What exactly are you after – all subPathItems in a specific PathItem or all PathItems in a document or …?

                  Could you please post a screenshot to illustrate what you are after?

                  • 6. Re: doc.pathItems return only selected layer path, not all.
                    mrmoka Level 1

                    I am after listing all layers in specific folder, and this folder contains only pathItems. So task was to iterate through layers, and generate JSON arrays with coordinates of path points.

                    I've already managed to do so, check the code at the top in post #4.Re: doc.pathItems return only selected layer path, not all.

                     

                    Your previous comment that pointed to activeLayer - was the key to solve the problem of access. As based on documentation it is obvious for me that doc.pathItems - should give access to all path items, but not to related to activeDocument.

                     

                    King Regards,

                    Max

                    • 7. Re: doc.pathItems return only selected layer path, not all.
                      c.pfaffenbichler Level 9

                      As based on documentation it is obvious for me that doc.pathItems - should give access to all path items, but not to related to activeDocument.

                      Did you mean activeLayer instead of activeDocument?

                       

                      I think you are not right as far as the Document Object Model goes.

                      A Layer in a Group for example is not listed in activeDocument.layers because it is filial to the Group (which in turn may be filial to the Document or another Group).

                      Similarly a Vector Mask is filial to the Layer or Group it masks and appears in the Paths Panel only if the Layer is selected.

                      With Action Manager code this may be different, but when using the DOM one has to accept some limitations in exchange for more easily readable code.

                      1 person found this helpful
                      • 8. Re: doc.pathItems return only selected layer path, not all.
                        mrmoka Level 1

                        c.pfaffenbichler wrote:

                         

                        As based on documentation it is obvious for me that doc.pathItems - should give access to all path items, but not to related to activeDocument.

                        Did you mean activeLayer instead of activeDocument?

                        Yep, my mistake, activeLayer.

                         

                        The problem here, is that accessing pathItems happens through Document, but not layer. And that confuses a lot.

                        It is not said in documentation, that pathItems is information from layer that is currently active.

                        Design wise, I would have pathItems from Layer, rather than from Document, as it in fact relates to Layer. But ONLY to active one. Even better should be that Document.activeLayer - should be proxy and have method pathItems. But not Document it self.

                        As by design, it is expected to iterate through pathItems the same way as you iterate through layers.

                         

                        Regardsing layers that they are hierarchy based - yep, they can be "folders" and contain another "folders" or layers.