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

ideas for updating doc.groupItems.length

Participant ,
Mar 21, 2024 Mar 21, 2024

Copy link to clipboard

Copied

I'm trying to detect corrupt compoundPathsItems (those with groupItems within them) I'm asking here before I'm going the SDK route. I've seen different solutions to this here:

Solved: Dealing with Compound Paths made of Groups - Adobe Community - 8826626

 

My simple idea to do this blazingly fast is to:

1. count doc.groupItem.length

2. duplicate the compoundPathItem

3. check if the doc.groupItem.length has increased.

 

Simple. The problem is that it ut doesn't update the groupItem count after the duplication. redraw() doesn't have an effect. The only thing I found so far to update the count is to:

 item.selected = true; // select something
 doc.selection = null; // deselect everything

Maybe you guys have some trix up your sleaves?

 

Thanks!

TOPICS
Scripting

Views

170

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 , Mar 21, 2024 Mar 21, 2024

oh ok, try this

 

var idoc = app.activeDocument;

alert(checkIfCorrupt (idoc.compoundPathItems[0]));

function checkIfCorrupt(item) {
  var doc = app.activeDocument;
  var itemCpy = item.duplicate(item, ElementPlacement.PLACEAFTER);
  
  // Update groupItem count.
  itemCpy.translate(10,10);

  //item.selected = true;
  //doc.selection = null;

  for (var i = 0; i < doc.groupItems.length; i++) {
    if (doc.groupItems[i].parent == itemCpy) {
        itemCpy.remove();
      // Return true if corr
...

Votes

Translate

Translate
Adobe
Community Expert ,
Mar 21, 2024 Mar 21, 2024

Copy link to clipboard

Copied

from all the wonderfull workarounds in the link you posted, I would go with 

 

1. checking all groupItem's parent

2. if parent == compoundPath, problem item

3. release, ungroup, remake

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
Participant ,
Mar 21, 2024 Mar 21, 2024

Copy link to clipboard

Copied

Hi, I tried all the workarounds in that thread, they are very slow I'm afraid. It takes about 10 seconds on my documents.

 

My idea is superfast but I'm looking for a better method to "update" the groupItem count.

 

Selecting/deselecting works but feels a bit clitchy/hacky maybe there's a better way.

 

function findByComparing(item) {
  var doc = app.activeDocument;
  var preNum = doc.groupItems.length;
  var itemCpy = item.duplicate(item, ElementPlacement.PLACEAFTER);

  // update groupItems count
  item.selected = true;
  doc.selection = null;
  
  if (preNum - doc.groupItems.length != 0) {
    itemCpy.remove();
    return true;
  } else {
    itemCpy.remove();
    return false;
  }
}

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 ,
Mar 21, 2024 Mar 21, 2024

Copy link to clipboard

Copied

oh ok, try this

 

var idoc = app.activeDocument;

alert(checkIfCorrupt (idoc.compoundPathItems[0]));

function checkIfCorrupt(item) {
  var doc = app.activeDocument;
  var itemCpy = item.duplicate(item, ElementPlacement.PLACEAFTER);
  
  // Update groupItem count.
  itemCpy.translate(10,10);

  //item.selected = true;
  //doc.selection = null;

  for (var i = 0; i < doc.groupItems.length; i++) {
    if (doc.groupItems[i].parent == itemCpy) {
        itemCpy.remove();
      // Return true if corrupt
      return true;
    }
  }
  itemCpy.remove();
}

 

** I would move the copy to the very top of the document to check GroupItems[0] parent instead of looping thru all group items in the document

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 ,
Mar 21, 2024 Mar 21, 2024

Copy link to clipboard

Copied

it seems you updated your code, but the idea is the same, use the translate trick to force a refresh

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
Participant ,
Mar 21, 2024 Mar 21, 2024

Copy link to clipboard

Copied

Thanks, that's what I was looking for. translate() feels alot better than select/deselect.  Moving stuff towards the top when iterating is also very clever.

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 ,
Mar 23, 2024 Mar 23, 2024

Copy link to clipboard

Copied

Hi @CarlosCanto and @iLLMonkey I have been annoyed by this for a long time and have benefitted from your solutions! For my own benefit—and maybe others?—I have synthesized your ideas and also added option to fix the corrupt CompoundPathItems. As always, there will be complex cases where it fails, but for most cases it will be a good fix I think.

- Mark

/**
 * Function to test if a CompoundPathItem is corrupted by internal GroupItems,
 * ie. if a document fragment with grouped PathItems was "compounded".
 * Also has the option to fix it.
 * @discussion https://community.adobe.com/t5/illustrator-discussions/ideas-for-updating-doc-groupitems-length/m-p/14505679
 */
(function () {

    var doc = app.activeDocument,
        allCompoundPaths = doc.compoundPathItems,
        counter = 0;

    for (var i = allCompoundPaths.length - 1; i >= 0; i--)
        if (compoundPathHasInternalGroups(doc, allCompoundPaths[i], true))
            counter++;

    alert('Fixed ' + (counter ? counter : 'no') + ' bad compound path items.');

})();

/**
 * Returns true when a CompoundPathItem `item`
 * is corrupted by internal GroupItems, and
 * has the option to fix it using `doFix`.
 * @author iLLMonkey - idea to check doc.groupitems.length to instantly measure bad groups in item
 * @author CarlosCanto - idea to refresh doc.groupItems and access doc.groupItems[0]
 * @author m1b - code to fix CompoundPathItems, and structure.
 * @version 2024-03-23
 * @param {Document} doc - an Illustrator Document.
 * @param {CompoundPathItem} item - an Illustrator CompoundPathItem.
 * @param {Boolean} [doFix] - wether to fix the bad compound path item (default: false).
 * @returns {Boolean} - whether the item is/was corrupted with internal group items.
 */
function compoundPathHasInternalGroups(doc, item, doFix) {

    var g = doc.groupItems.length;

    var dup = item.duplicate(item, ElementPlacement.PLACEBEFORE);
    dup.left += 1;

    var badGroupCount = doc.groupItems.length - g,
        isBad = badGroupCount > 0;

    if (isBad && doFix) {

        // move item to beginning of document, so group items are first
        item.move(doc, ElementPlacement.PLACEATBEGINNING);

        for (var g = badGroupCount - 1; g >= 0; g--) {

            // we can use doc.groupItems[g] because `item` is the first page item
            // page item, and any bad internal groups will be the first groups in document

            if (item !== doc.groupItems[g].parent)
                continue;

            // rescue path items
            rescuePathItemsFromBadGroup(doc.groupItems[0], item);

            // clean up
            doc.groupItems[0].remove();

        }

        // clean up
        item.move(dup, ElementPlacement.PLACEAFTER)

    }

    // clean up
    dup.remove();

    // return true when the item has/had bad group(s) inside
    return isBad;

    /**
     * Moves path items out of `badGroup` (recursively)
     * and puts them into `destination` container.
     * @author m1b
     * @param {GroupItem} badGroup - an Illustrator GroupItem.
     * @param {container} destination - an Illustrator pathItem container, eg. CompoundPathItem.
     */
    function rescuePathItemsFromBadGroup(badGroup, destination) {

        // rescue the bad groups path items
        for (var i = badGroup.pageItems.length - 1; i >= 0; i--) {

            if ('GroupItem' === badGroup.pageItems[i].constructor.name)
                rescuePathItemsFromBadGroup(badGroup.pageItems[i], destination);

            if ('PathItem' === badGroup.pageItems[i].constructor.name)
                badGroup.pageItems[i].move(destination, ElementPlacement.PLACEATEND);

        }

    };

};

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 ,
Mar 23, 2024 Mar 23, 2024

Copy link to clipboard

Copied

LATEST

awesome, thanks for putting this together Mark

 

 

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