Skip navigation
Currently Being Moderated


Jan 5, 2012 11:48 AM

I'm having a hard time understanding the way MatchingArtSet and AIArtSpec work together. I understand if use the following:


AIArtSpec selectedSpecs[] = { { kAnyArt , kArtSelected , kArtSelected } };

sAIArtSet->MatchingArtSet( selectedSpecs , 1, artSet );


I get an art set that contains all the selected objects. Great.


What I don't understand is the behavior of the other AIArtUserAttr options. What I am trying to do specifically, is gather an art set of all the selected art, ignoring any art inside of a selected group.


I have tried various combinations of kArtSelectedTopLevelGroups, kArtSelectedLeaves, kArtFullySelected, all with no luck. The art set that is returned usually contains 0 items, or all the items. The docs on selecting matching specs are somewhat confusing.


Am I supposed to use different options for the first and second?


I have tried:


{ kAnyArt , kArtSelected , kArtSelectedTopLevelGroups }, etc, etc.


I am certainly open to using the art set "logic" functions to remove objects from the set of all selected objects, but I can't seem to get a set of just the selected leaf objects either.


Anyone have any experience with matching art?

  • Currently Being Moderated
    Jan 5, 2012 2:38 PM   in reply to btemp

    Once you have your art set of selected art, how about just removing the art that is part of a group (i.e. has something other than a layer group as a parent). Maybe:


    ai::int32 artSetSize;

    sAIArtSet->CountArtSet( artSet, &artSetSize );

    AIArtHandle art, parent;

    for ( indexArtSet = artSetSize - 1; indexArtSet >= 0; --indexArtSet ) {

        error = sAIArtSet->IndexArtSet( artSet, indexArtSet, &art );

        ASBoolean parentLayerGroup;

        sAIArt->GetArtParent( art, &parent );

        if ( parent ) {

            sAIArt->IsArtLayerGroup( parent, &parentLayerGroup );

            if ( !parentLayerGroup ) {

                sAIArtSet->RemoveArtFromArtSet( artSet, art );




    Mark as:
  • Currently Being Moderated
    Jan 6, 2012 1:19 AM   in reply to btemp

    Just take a look at AIArt.h file. AIArtUserAttr enum is described in that file.

    There are some explanations about what you are looking for.



    Mark as:
  • Currently Being Moderated
    Jan 6, 2012 5:52 AM   in reply to btemp

    The fields whichAttr and attr can be used to narrow the match by specifying

    user attributes to include in the search. These attributes are boolean

    values stored as bit flags in an object attributes variable.

    Pass the desired user attribute for whichAttr. Pass 0 for attr if objects

    without the state are desired, or the attribute mask for attr if objects with

    it are desired. If whichAttr is 0 (no attributes selected), only the object type

    is compared.


    AIMatchingArtSpec spec;

    AIArtHandle **unselectedPaths, **allLockedArt, **allGroups;

    long numMatches;

    // get a list of unselected paths

    spec.type = kPathArt;

    spec.whichAttr = kArtSelected;

    spec.attr = 0;

    error = GetMatchingArt( &spec, 1, &unselectedPaths, &numMatches );

    // get a list of locked objects

    spec.type = kAnyArt;

    spec.whichAttr = kArtLocked;

    spec.attr = kArtLocked;

    error = GetMatchingArt( &spec, 1, &allLockedArt, &numMatches );

    // get a list of groups, selected or not

    spec.type = kGroupArt;

    spec.whichAttr = 0;

    error = GetMatchingArt( &spec, 1, &allGroups, &numMatches );





    This should be helpful!



    Mark as:
  • Currently Being Moderated
    Jan 6, 2012 8:09 AM   in reply to btemp

    I'm not sure to fully understand what you are trying to do with this attributes.


    I have just take a look a  AIArt.h for more details about those values.

    Here it is what I have found:



      /** Matches only fully selected top level objects and not their children; valid only for matching.*/

      kArtSelectedTopLevelGroups                    = 0x00000040,

      /** Matches only leaf selected objects and not their containers; valid only for matching; see also \c kArtSelectedTopLevelGroups */

      kArtSelectedLeaves                                        = 0x00000080,

      /** Matches only top level selected objects that have a stroke or fill; valid only for matching; see also \c kArtSelectedTopLevelGroups */

      kArtSelectedTopLevelWithPaint           = 0x00000100, // Top level groups that have a stroke or fill, or leaves



    you should something like this:



    spec.type = kAnyArt;

    spec.whichAttr = kArtSelectedLeaves;      // mask bits

    spec.attr = kArtSelectedLeaves;

    error = GetMatchingArt( &spec, 1, &.., &.. );



    or like that:



    spec.type = kAnyArt;

    spec.whichAttr = kArtSelectedTopLevelGroups;    //mask bits

    spec.attr = kArtSelectedTopLevelGroups;

    error = GetMatchingArt( &spec, 1, &.., &.. );






    spec.type = kAnyArt;

    spec.whichAttr = kArtSelectedTopLevelGroups l kArtSelectedLeaves; // pipe char between value, mask bits

    spec.attr = kArtSelectedTopLevelGroups l kArtSelectedLeaves;

    error = GetMatchingArt( &spec, 1, &.., &.. );



    Attr = the flag in the same positions as the mask bits indicating whether that attribute is on or off.

    Mark as:
  • Currently Being Moderated
    Jan 6, 2012 8:15 AM   in reply to btemp

    Have you ever tried using GetUserAttr or SetUserAttr methods?

    This is exactly the same logic.

    Mark as:
  • Currently Being Moderated
    Jan 6, 2012 8:43 AM   in reply to btemp

    For all kind of objects, if you are only looking for leaf selected object, I would use this:


    All kind of objects           whichAttr: leaf selected object            value: keep in mind, this is mask stuff. by using kArtSelectedLeaves you will set the right bit to 1.

    { kAnyArt ,                               kArtSelectedLeaves ,                                    kArtSelectedLeaves }




    By aware of setting the right bit(s) to one. Otherwise this won't work.

    Mark as:
  • Currently Being Moderated
    Jan 6, 2012 10:05 AM   in reply to btemp

    AIArtSetSuite Struct Reference says this (note the italicized part):


    Selection while matching: kArtSelectedTopLevelGroups, kArtSelectedLeaves, and kArtSelectedTopLevelWithPaint are used only with AIMatchingArtSuite::GetMatchingArt. These values cause an error in AIArtSuite::SetArtUserAttr(). They are mutually exclusive; you can specify only one, and they cannot be combined with other flags.

    Mark as:
  • Currently Being Moderated
    Jan 6, 2012 11:02 AM   in reply to btemp

    Based on that, I would guess that the first one is equivalent to:

    { kAnyArt , kArtSelected , kArtSelected }

    And including kArtSelectedTopLevelGroups isn't actually having any effect.


    That's correct. If you're looking to combine things I think you'd do it like you specified for:


    { kAnyArt , kArtSelected | kArtSelectedTopLevelGroups , kArtSelected | kArtSelectedTopLevelGroups }


    I'm not sure though. I believe this one says "selected art that is also a selected top-level group". That said, it didn't seem to do what we'd expect.


    Also, note that kArtSelectedTopLevelGroups & kArtSelectedLeaves are apparently mutually exclusive, according to the documentation of AIArtUserAttr.


    If you want to do something like A or B, you'd create two different specs, add them to an array (size 2 in this case) and pass the array in instead of just one (plus set size to 2 obviously). I think that means "match art that meets any of the specs I specify".

    Mark as:
  • Currently Being Moderated
    Jan 6, 2012 1:59 PM   in reply to btemp

    >"The selection attributes differ only for Get and Match operations, not for Set operations."


    I believe they're just saying that kArtSelected and kArtFullySelected act the same when used with Set (fully selecting an object), but differently when used with Get or Match.

    Mark as:

More Like This

  • Retrieving data ...

Bookmarked By (0)

Answers + Points = Status

  • 10 points awarded for Correct Answers
  • 5 points awarded for Helpful Answers
  • 10,000+ points
  • 1,001-10,000 points
  • 501-1,000 points
  • 5-500 points