• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

detect groups in pageitems and cycle through items in each group

New Here ,
Aug 14, 2011 Aug 14, 2011

Copy link to clipboard

Copied

Hi,

I can use some help with a script I'm working on. The script basically creates a new layer based on an objects fill color and then moves the item to the new layer.

What I can't figure out is how to check if a pageItem is a Group and if so, cycle through all objects within the group. What I have so far (snippit) is:

var doc = app.activeDocument; var LayerName = "0"; var MyArray = new Array; for ( j=0; j < Counter; j++ )     {     CurrentItem = doc.pageItems;     if (CurrentItem.typename != "GroupItem" && CurrentItem.typename != "CompoundPathItem" && CurrentItem.parent.typename != "GroupItem" && CurrentItem.parent.typename != "CompoundPathItem")        {          LayerName = ConstructLayerNameBasedOnFillColor( CurrentItem );         CurrentItem.move( app.activeDocument.layers.getByName( LayerName ), ElementPlacement.PLACEATBEGINNING );        }       else        {          if (CurrentItem.typename == "GroupItem") //  seems to be wrong as it also returns true for an item within the group         {          myArray = [];             for ................ // cycle through each item within the group              {               LayerName = ConstructLayerNameBasedOnFillColor( CurrentGroupItem );               MyArray.push(LayerName);              }          LayerName = GetMostCommonColor(MyArray);          ................. // move the group (including all items within the group) to layer LayerName           }        }     }

The part I need some help with is:

1:  if (CurrentItem.typename == "GroupItem") //  seems to be wrong as it also returns true for an item within the group 2:     { 3:     myArray = []; 4:      for ................ // cycle through each item within the group 5:         { 6:          LayerName = ConstructLayerNameBasedOnFillColor( CurrentGroupItem ); 7:          MyArray.push(LayerName); 8:         } 9:     LayerName = GetMostCommonColor(MyArray); 10:     ................. // move the group (including all items within the group) to layer LayerName

11:    }

line 1: how to check if the pageItem is a group

line 4: cycle through all the items within the group

line 10: move the group to a new layer

Any help is appreciated.

TOPICS
Scripting

Views

2.3K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Aug 17, 2011 Aug 17, 2011

Have you tried running the loop backwards in case the index gets messed up.

 m=0; m < CurrentItem.pageItems.length-1; m-- 

Votes

Translate

Translate
Adobe
Community Expert ,
Aug 16, 2011 Aug 16, 2011

Copy link to clipboard

Copied

Hi,
if you have 3 pageItems and these are in same group.

alert (app.activeDocument.pageItems.length);

There are only 3 items in the Document but this one line scipt return 4(items).
One is GroupeItem and others are page Items. (and origin pageItems parent is GroupItem.)
So you should check and move only groupItems to target layer.

if (app.activeDocument.pageItems[0].typename=="GroupItem") {
    app.activeDocument.pageItems[0]

         .moveToBeginning(app.activeDocument.layers[0])
    }

You can move Items to specific layer using "moveToBeginnin()" method like prevoius script.

Ten.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Aug 17, 2011 Aug 17, 2011

Copy link to clipboard

Copied

Your example works for moving to group to the destination layer but I still struggle with how to detect the most common color within the group. My current attempt results in an endless loop, but even when it works it has a lot of redundancy in it. That shouldn't be a problem with small drawings but as my files contain over 50.000 objects it really slows the script down.

My current code (note that some functions are replaced by dummies to keep overview)

var doc = app.activeDocument; var Counter = doc.pageItems.length; var LayerName = "dummy"; var MyArray = new Array; function LayerExists(FindLayer) {   var layerCount = doc.layers.length;   var FindIt = 0;    for ( j=0; j < layerCount; j++ )    {     if ( doc.layers.name == FindLayer ) { FindIt = 1; };    }   return FindIt; } function ConstructLayerNameBasedOnFillColor() {   var myLayerName = "dummy";   if ( LayerExists(myLayerName) == 0 )      {       var NewLayer = doc.layers.add()       NewLayer.name = myLayerName;      }   return myLayerName;      } function GetMostCommonColor() {   return "dummy"; } for ( j=0; j < Counter; j++ )     {     CurrentItem = doc.pageItems;           if (CurrentItem.typename != "GroupItem" && CurrentItem.typename != "CompoundPathItem" && CurrentItem.parent.typename != "GroupItem" && CurrentItem.parent.typename != "CompoundPathItem") // no need to create layers for objects within grouped items        {       LayerName = ConstructLayerNameBasedOnFillColor(CurrentItem);         CurrentItem.move( doc.layers.getByName( LayerName ), ElementPlacement.PLACEATBEGINNING );        }             if (CurrentItem.typename == "GroupItem")        {      myArray = [];      for ( m=0; m < CurrentItem.pageItems.length; m++ )          {              LayerName = ConstructLayerNameBasedOnFillColor( CurrentItem.pageItems );           MyArray.push(LayerName);               }      LayerName = GetMostCommonColor(MyArray);         CurrentItem.moveToBeginning(doc.layers.getByName( LayerName ) );        }     }

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 17, 2011 Aug 17, 2011

Copy link to clipboard

Copied

Too many object... How about that deletes pathItems smaller than the defined size before you run it?

Ten

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Aug 17, 2011 Aug 17, 2011

Copy link to clipboard

Copied

It's not about the amount of items, correct, over 50.000 items is a lot of objects for Illustrator but that is what you get when you export detailed GIS maps to A0 / Arch E Illustrator format. And if you know how to avoid the pitfalls it's even workable.

For this script by the way I'm testing with a small file with only 28 items (some pathitems / groups, compound paths, text items and symbols). The problem is not the amount of items but that this script gets in an endless loop (even with 28 items).

By trial and error I've found that the problem is within this part:

if (CurrentItem.typename == "GroupItem")        {         myArray = [];         for ( m=0; m < CurrentItem.pageItems.length; m++ )          {           LayerName = ConstructLayerNameBasedOnFillColor( CurrentItem.pageItems );           MyArray.push(LayerName);            }         LayerName = GetMostCommonColor(MyArray);         CurrentItem.moveToBeginning(doc.layers.getByName( LayerName ) );        }

and then especially in the "for ( m=0; m...." loop. What I don't understand is why this loop is infinite.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 17, 2011 Aug 17, 2011

Copy link to clipboard

Copied

Have you tried running the loop backwards in case the index gets messed up.

 m=0; m < CurrentItem.pageItems.length-1; m-- 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 17, 2011 Aug 17, 2011

Copy link to clipboard

Copied

if you have the following group

"layer 1"

- Group               // pageItem[0]

     - pathItem1     // pageItem[1]

     - pathItem2     // pageItem[2]

and you move out pathItem[1] to your "dummy" layer, being the top most layer. you'll get this

"dummy"

     - pathItem1     // pageItem[1]

"layer 1"

     - Group               // pageItem[0]

          - pathItem2     // pageItem[2]

...so the staking order gets messed up, you'll have to either

- put the pageItems to move in an array, and after your original for...next is done, loop thru the items in the array to move to the "dummy" layer

or

- loop backwards, and move your items to a layer at the bottom of the staking order

"layer 1"

     - Group               // pageItem[0]

               - pathItem1     // pageItem[1]

"dummy"

     - pathItem2     // pageItem[2]

Edit: Hi Larry, I took too long compose

Message was edited by: CarlosCanto

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 17, 2011 Aug 17, 2011

Copy link to clipboard

Copied

Good morning. I examined this code last night and found a problem.
When you call your function, global variable "j" is overrided by local variable. You must define variables to local in function like below:

function LayerExists(FindLayer)
{
  var layerCount = doc.layers.length;
  var FindIt = 0; 
  for (
var j=0; j < layerCount; j++ )
   {
    if ( doc.layers.name == FindLayer ) { FindIt = 1; };
   }
  return FindIt;
}


Ten

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Aug 19, 2011 Aug 19, 2011

Copy link to clipboard

Copied

Hi Ten,

Your correct, what a dumb mistake. The script is still not what I need but I get there step by step.

thanks,

Michel

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Aug 18, 2011 Aug 18, 2011

Copy link to clipboard

Copied

And how about simply replace LayerExists and ConstructLayerNameBasedOnFillColor two functions with

function ConstructLayerNameBasedOnFillColor (/*arguments*/) {

     var myLayerName = "dummy";

     try {

          doc.layers.getByName(myLayerName);

     } catch (e) {

          doc.layers.add().name = myLayerName;

     }

     return myLayerName ;     

}

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Aug 19, 2011 Aug 19, 2011

Copy link to clipboard

Copied

LATEST

Hi Moluapple,

You're solution will be quicker than checking all layer names for each object over and over again, thanks for pointing out.

Michel

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines