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

ideas for updating doc.groupItems.length

Participant ,
Mar 21, 2024 Mar 21, 2024

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
833
Translate
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
...
Translate
Adobe
Community Expert ,
Mar 21, 2024 Mar 21, 2024

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

Translate
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

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;
  }
}
Translate
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

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

Translate
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

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

Translate
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

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.

Translate
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

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);

        }

    };

};
Translate
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
LATEST

awesome, thanks for putting this together Mark

 

 

Translate
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