17 Replies Latest reply: Jan 6, 2012 1:59 PM by DayForce RSS

    MatchingArtSet

    btemp Community Member

      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?

        • 1. Re: MatchingArtSet
          DayForce Community Member

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

                  }

              }

          }

          • 2. Re: MatchingArtSet
            btemp Community Member

            That's a good idea. I actually came up with another way to solve my specific problem.

             

            I still don't follow how these art specs are supposed to work though. kArtSelected is obvious, but the other options seem pretty interesting if it were clearer how to use them.

            • 3. Re: MatchingArtSet
              Toto RoToTO

              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.

               

              Thomas.

              • 4. Re: MatchingArtSet
                btemp Community Member

                I guess I'm not being clear what I'm trying to figure out. Specifically, in an AIArtSpec, if I want to use it for matching art, what are the second and third parameters  "attr" and "whichattr" used for?

                • 5. Re: MatchingArtSet
                  Toto RoToTO Community Member

                  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!

                  Regards,

                  Thomas.

                  • 6. Re: MatchingArtSet
                    btemp Community Member

                    That's really helpful actually.

                     

                    I don't understand why I'm seeing the following behavior though:

                     

                    I create a document with 3 rectangles on it and group them together. So my art tree looks like:

                     

                    Layer -> Group -> Obj1, Obj2, Obj3

                     

                    I select all objects.

                     

                    Then I use

                    { kAnyArt , kArtSelectedLeaves , kArtFullySelected }

                     

                    I would understand this to give me either the group object, as it is a fully selected leaf of the Layer object. Or I would expect it to give me the 3 rectangles as they are fully selected leaves of the Group object. Or I would even understand if it gave me all 4 objects as they are all fully selected leaves of something.

                     

                    What I actually get is just Obj1. This doesn't make any sense to me at all.

                    • 7. Re: MatchingArtSet
                      Toto RoToTO Community Member

                      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, &.., &.. );

                       

                       

                      or:

                       

                       

                      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.

                      • 8. Re: MatchingArtSet
                        Toto RoToTO Community Member

                        Have you ever tried using GetUserAttr or SetUserAttr methods?

                        This is exactly the same logic.

                        • 9. Re: MatchingArtSet
                          btemp Community Member

                          It looks from the header, that

                           

                          attr = 1

                           

                          is the same as

                           

                          attr = kArtSelected

                           

                          Based on that, I would expect

                           

                          { kAnyArt , kArtSelectedLeaves , kArtFullySelected }

                           

                          to search All Art Types for Selected Leaf objects that are Fully Selected. In practice, what I've been getting is only 1 object. From what I've been able to piece together, it seems to be the first object in the tree that matches, the rest are ignored. I have seen this behavior with kArtSelectedTopLevelGroups as well.

                           

                          Using the same tree as above,   Layer -> Group -> Obj1, Obj2, Ob3    ,    selecting all again, and using

                           

                          { { kAnyArt , kArtSelectedLeaves , kArtSelectedLeaves } }

                           

                          Returns 0 items. Baffling.


                          • 10. Re: MatchingArtSet
                            Toto RoToTO Community Member

                            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.

                            • 11. Re: MatchingArtSet
                              btemp Community Member

                              Ok... now I'm getting somewhere. The bitwise OR stuff seems to be getting closer, but I'm still having trouble getting the results I'm looking for.

                               

                              Same tree as before:   Layer -> Group -> Obj1, Obj2, Ob3

                               

                              Using this:

                              { kAnyArt , kArtSelected , kArtSelected | kArtSelectedTopLevelGroups }

                              Returns all 5 objects.

                               

                              This:

                              { kAnyArt , kArtSelected | kArtSelectedTopLevelGroups , kArtSelected | kArtSelectedTopLevelGroups }

                              Returns 0 objects.

                               

                              This:

                              { kAnyArt , kArtSelected , kArtSelectedTopLevelGroups }

                              Returns 0 objects.

                               

                              This:

                              { kAnyArt , kArtSelectedTopLevelGroups , kArtSelectedTopLevelGroups }

                              returns 0 objects.

                               

                              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.

                               

                              edit:

                               

                              Using

                              { kAnyArt , kArtSelectedLeaves , kArtSelectedLeaves }

                              as you suggested above, also returns 0 objects.

                               

                              { kAnyArt , kArtSelectedLeaves , kArtSelected }

                              Returns 1 object, Obj1.

                               

                              { kAnyArt , kArtSelectedLeaves , kArtSelected | kArtSelectedLeaves }

                              Returns 0 objects.

                               

                              { kAnyArt , kArtSelected , kArtSelected | kArtSelectedLeaves }

                              Returns all 5 objects.



                              • 12. Re: MatchingArtSet
                                DayForce Community Member

                                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.

                                • 13. Re: MatchingArtSet
                                  btemp Community Member

                                  I thought you had something there. When I started with this, I had read that in the docs and thought "I'm not using SetArtUserAttr, this should work for me."

                                   

                                  Then you posted this, I read it again, and realized I'm using MatchingArtSet, not GetMatchingArt. Problem solved, right? But then I switched my code around to use GetMatchingArt instead, and I'm getting the same results as before.

                                   

                                  { kAnyArt , kArtSelectedLeaves , kArtSelectedLeaves }

                                  Returns 0 matches.

                                  • 14. Re: MatchingArtSet
                                    A. Patterson Community Member

                                    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".

                                    • 15. Re: MatchingArtSet
                                      btemp Community Member

                                      You would think, huh? But I can't figure any way to actually include kArtSelectedTopLevelGroups. I tried every permutation of that I could think of, and the only way I got any matches was

                                       

                                      { kAnyArt , kArtSelected , kArtSelected | kArtSelectedTopLevelGroups }

                                       

                                      Which, as we've stated, seems to be equivalent to just using

                                       

                                      { kAnyArt , kArtSelected , kArtSelected }

                                       

                                      At this point, I'm not even trying to combine things, I'm just trying to figure out how to use kArtSelectedTopLevelGroups and kArtSelectedLeaves. Everything I've thought of, or anyone has suggested has not given the results I would expect.

                                      • 16. Re: MatchingArtSet
                                        btemp Community Member

                                        There's also this cryptic line in the docs:

                                         

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

                                         

                                        Any thoughts on that one?

                                        • 17. Re: MatchingArtSet
                                          DayForce Community Member

                                          >"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.