14 Replies Latest reply on Aug 12, 2015 11:55 AM by Silly-V

    Help with cleaning up array of pageItems, please.

    williamadowling Level 4

      Hey folks.

       

      I have a question that only loosely pertains to illustrator, as I think I'm just missing something really obvious in basic JS logic..

       

      I've written a script to create artboards for me that fit tight to the outside of many pageItems. In the first iteration, I wrote the script to look only for groupItems because I was assuming my production artists were doing things properly. Turns out, many of them 'walk to the beat of a different drummer', if you will. So I've decided to give up on changing their habits and take this as an exercise in self improvement with regards to scripting unpredictability.

       

      Now I'm rewriting the script to work with any pageItem. The problem I'm running into is the exclusion of a pageItem that is either- A: Completely contained within another object, or B: Shares left && || top && || right && || bottom coordinates (eg. object a has bounds 5, 5, 10, -10 and object b has bounds 5, 4, 9, -9).

       

      So far I have a function written to sort through the pageItems and sort them into rows (within a certain tolerance). After i determine all pageItems that are in a particular row, I want to loop that row to check for any items that are completely contained within another object, or share some bounds as the example above. The problem I'm running into is how to properly and efficiently do this check.. I've done this successfully when I'm only looking for something completely contained within, like this:

       

      var array = [(all pageItems of given row are pushed here)]
      
      for(a=array.length-1;a>-1;a--){
           var curObj = array[a];
           var L = curObj.left;
           var T = curObj.top;
           var R = L + curObj.width;
           var B = T - curObj.height;
           for(b=array.length-1;b>-1;b--){
                var compareObj = array[b];
                var CL = compareObj.left;
                var CT = compareObj.top;
                var CR = CL + compareObj.width;
                var CB = CT - compareObj.height;
                if(CL > L && CT < T && CR < R && CB > B){
                     array.splice(b,1);
                }
           }
      }
      
      
      

       

      This part works fine, but only because it returns false when a=b (since when a=b it's comparing the same object, so if I include >= or <=, it splices every object from the array and nothing happens).

       

      So, my question is, how do I set up that second loop to ignore curObj? My first inclination is to simply splice the curObj before I start the second loop and set the compareObj variable. But there's a good chance that object needs to be compared later.

       

      Sorry if that's confusing.. i've been pulling my hair out trying to wrap my head around this (probably really simple) issue.

       

      **EDIT**

       

      I made a quick visualization for what i'm looking to do. In the attached screenshot I want to loop through this row of objects and splice the black boxes out of the array while leaving the gray boxes.

       

      Screen Shot 2015-08-12 at 8.58.55 AM.jpg

        • 1. Re: Help with cleaning up array of pageItems, please.
          CarlosCanto Adobe Community Professional & MVP

          The issue may be in Splicing, why don't you push objects into a different array?

          • 2. Re: Help with cleaning up array of pageItems, please.
            williamadowling Level 4

            Because after I've ascertained the "container objects" as i've come to call them (the gray boxes in the example) i want to remove everything that falls inside of these. At the end of the script, I use this array to create the artboards via docRef.fitArtboardToSelectedArt();

             

            Once i've determined that an object is inside of another object, I want the script to forget about it all together.

            • 4. Re: Help with cleaning up array of pageItems, please.
              Silly-V Adobe Community Professional

              I think your issue is that you had some crazy crackpot helping you out with this in the first place.

              However, I was able to do something like

              1.           if(CL == L && CT == T && CR == R && CB == B){ 
              2.                continue
              3.           }

              Which ignores the object when it's the same object- is that what you need?

              *Of course be ware of objects having identical coords, one on top of the other precisely- that'll fail.

              • 5. Re: Help with cleaning up array of pageItems, please.
                williamadowling Level 4

                haha. he was no crackpot i assure you.

                 

                I think that might work.. However, i don't always want to ignore something just because it has the same bounds.. I only want to ignore the curObj from loop A.

                 

                The reason for this is, sometimes I'll have a clipping mask that is the exact same size as my "container object" (ie. the shirt body. See screenshot. the clipping mask on the left would fit directly over the shirt on  the right, and the clip mask is made with the body of the shirt, so the bounds are identical.)

                 

                I still want to splice that clipping mask out of the array, otherwise i get 2 artboards in the same spot.

                 

                Screen Shot 2015-08-12 at 10.07.39 AM.jpg

                • 6. Re: Help with cleaning up array of pageItems, please.
                  Silly-V Adobe Community Professional

                  Hey, if the problem is artboards in the same spot, can you just make sure to not put any artboards into the same spot where a previous one already exists? This would negate the splicing issue.

                  • 7. Re: Help with cleaning up array of pageItems, please.
                    williamadowling Level 4

                    that looks great, Carlos. However I'm not sure it will work for me. Because some of the objects i need the script to ignore, could be the exact same size as the selection marquee in your script. Or they could share just 1, 2 or 3 bounds with the remaining boundary contained inside. Your version only finds things completely within the compare object (selection marquee). That part I've already solved.

                     

                    And since I need the script to work on any number between 5 and 10,000 pageItems in the document, i need the script to intuitively find each piece within a row that should be used to compare the rest of the pageItems to. Then I need to ignore that pageItem while I compare the rest of them, but it needs to remain in the array because the odds are, that object will later need to be compared to a different pageItem.

                    • 8. Re: Help with cleaning up array of pageItems, please.
                      williamadowling Level 4

                      I had originally tried to do it this way, Vasily.. But then i ran into issues with the script trying to create too many artboards before it tried to rectify duplicate artboards.

                       

                      However, I think i see what you're saying about preventing an artboard from being created if an artboard already exists with those same bounds, but I'm not sure how to work the logic of that. I would need to keep a growing list of artboard bounds (as each artboard is created, i'd push the bounds to an existing array), and compare each new possible artboard to that list to determine whether to create an artboard..

                       

                      so something like...

                       

                      var currentRow = [page items of current row];

                      var artboardBounds = [];

                       

                      for(a=0;a<currentRow.length;a++){

                           var bounds = currentRow[a].visibleBounds;

                           var left = bounds[0];

                           var top = bounds[1];

                           var right = bounds[2];

                           var bot = bounds[3];

                           if(artboardBounds.length>0){

                                for(b=0;b<artboardBounds.length;b++){

                                     var cbounds = artboardBounds[b];

                                     var cleft = cbounds[0];

                                     var ctop = cbounds[1];

                                     var cright = cbounds[2];

                                     var cbot = cbounds[3];

                                     if(cleft >= left && ctop <= top && cright <= right && cbot >= bot){

                                          docRef.artboards.add(

                                     }

                                }

                           }

                      }

                       

                      sorry i stopped writing that because i got lost and it seemed really clunky. Since this method could create an artboard for each individual pageItem, then have to go back and remove that artboard after it found something that fits around it..

                       

                      currently, I'm just looping through an array that has already been verified as "items i want an artboard around". And since i need to use docRef.fitArtboardToSelectedArt(); (due to the clipping mask issues we've discussed in the past) i want to minimize the amount of artboards that are created, since fit to selected art seems to app.redraw() (sort of) and takes a while.

                       

                      One thought I had was to loop through the row and just find the largest item, push that into a different array, splice it from the currentRow array, then compare it's bounds to the remainder of currentRow. Anything that is contained within (or has identical bounds) will be spliced (making future comparisons faster since there will be less items to compare).

                       

                      Let me poke around down that road and see what I can do.

                      • 9. Re: Help with cleaning up array of pageItems, please.
                        Silly-V Adobe Community Professional

                        I was thinking that at the point where you are right about to place the artboard, it checks the existing (doesn't have to be a manually-made array, could just be document.artboards)

                         

                        function artboardExists(bounds){

                            var left = bounds[0];

                            var top = bounds[1];

                            var right = bounds[2];

                            var bot = bounds[3];

                            for(var b=0;b<document.artboards.length;b++){

                                  var cbounds = document.artboards[b].artboardRect;

                                  var cleft = cbounds[0];

                                  var ctop = cbounds[1];

                                  var cright = cbounds[2];

                                  var cbot = cbounds[3];

                                  if(cleft == left && ctop == top && cright == right && cbot == bot){

                                      return true;

                                  }

                            }

                             return false;

                        }

                        for(a=0;a<currentRow.length;a++){

                            var bounds = currentRow[a].visibleBounds;

                            if(!artboardExists(bounds)){

                                  docRef.artboards.add();

                             }

                        }

                        • 10. Re: Help with cleaning up array of pageItems, please.
                          williamadowling Level 4

                          Again though, that only handles artboards that are exactly the same size, and since the currentRow array will have tons of pageItems only sorted by left coordinate, a lot of artboards would be created that were too small. Then i would need to go back and remove them after a larger artboard was created around the smaller one.

                           

                          lets look back to the example i posted earlier with the black/gray boxes. I attached a new copy of that screenshot with numbers so it's easier to reference.

                           

                          the pageItems in the currentRow array would be sorted from left to right. So as i loop through that array using the bounds of each pageItem to create an artboard, it will do whatever pageItem is farthest to the left. In the screenshot, the black box labeled 2 would get an artboard created first (since the artboard around gray box 3 doesn't exist yet). Then when the artboard for 3 is created, the artboard around 2 would need to be removed. Does that make sense?

                           

                          Since it takes time to create and subsequently remove an artboard, it makes more sense to me to have the cleanest possible array before even attempting to create the artboards. That way i know that before an artboard is ever created, only the pageItems that should get an artboard are in the array. No extra artboards need be created or subsequently removed.

                           

                          I want to curate the array such that 2 5 and 7 are removed before any artboards are created and my array is left simply [1, 3, 5, 7] giving the most efficient artboard creation possible. (keep in mind that the screenshot is an incredibly simplified version and each "container object" or shirt piece could have hundreds of smaller pageItems on top of it that should not get an artboard.

                           

                          Screen Shot 2015-08-12 at 11.23.15 AM.jpg

                          • 11. Re: Help with cleaning up array of pageItems, please.
                            williamadowling Level 4

                            why why why why why why why why why on earth is artwork that protrudes outside of the bounds of a clipping mask included in the "visibleBounds" of said clipping mask.

                             

                            the very nature of the clipping mask is that it makes INVISIBLE anything that's outside of that clipping mask.

                            • 12. Re: Help with cleaning up array of pageItems, please.
                              Silly-V Adobe Community Professional

                              Can you by any means sort the pageItems bounds array to get the biggest shape in a 'cell' ?

                              I think you actually said this in a previous msg here.

                              • 13. Re: Help with cleaning up array of pageItems, please.
                                williamadowling Level 4

                                I'm not sure what you mean by the "biggest shape in a 'cell'".

                                 

                                I know we've talked about visibleBounds and clipping masks on here.. but it occurred to me that searching for the biggest item could lead to unsatisfactory results because a clipping mask may be larger than the shirt body. although i suppose that may still be fine if I am using fitArtboardToSelectedArt at the end...

                                 

                                idk. i've been separated from the scripting for a while because most of our production art staff was let go. so i've been back doing the grunt work for quite a while. now that i have some time to get back into this.. i feel like my brain just isn't comprehending the basic stuff anymore. every time i think i've had an epiphany, i get all the way through writing the block of code that I thought was the solution to my problem, only to realize that it either didn't solve my problem, or it was just moronic on it's face.

                                 

                                I need a drink.

                                • 14. Re: Help with cleaning up array of pageItems, please.
                                  Silly-V Adobe Community Professional

                                  So, what's the deal with the people not grouping things properly? That sounds like the cause of this whole issue, if you made them a script that groups everything and saves the file and command them to only save files that way, it would prevent this, right?