Read MoGraph Selection from Effector plugin



  • On 23/06/2013 at 02:58, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   R14 
    Platform:      
    Language(s) :     C++  ;

    ---------
    I can't find a way to read in the MoGraph selection from an EffectorData plugin. I probably miss
    something obvious, any hints are appreciated. :)

    -Niklas



  • On 23/06/2013 at 05:08, xxxxxxxx wrote:

    i don't think effectors contain a pointer / reference to a selection, as that would cause

    problems for setups where one effector is targeting multiple generator objects.

    long story short:

    1. create a generator with a selection.
    2. assign an effector to the generator and restrict it to the selection.
    3. duplicate the generator.
    4. rename the selection tag on the duplicate.

    the effector will stop working on the duplicate setup after step four. effectors do not do
    anything with selections themselves i think, they just do carry arround the name string. 
    a generator object does relate to that name string when passing the modata to effector 
    methods.

    so you have either to stick with the selection name string provided by the effectors 
    description or you rely on  the modata passed to the effector methods, as it will contain 
    sort of the selection info.



  • On 23/06/2013 at 12:08, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    i don't think effectors contain a pointer / reference to a selection, as that would cause

    problems for setups where one effector is targeting multiple generator objects.

    long story short:

    1. create a generator with a selection.
    2. assign an effector to the generator and restrict it to the selection.
    3. duplicate the generator.
    4. rename the selection tag on the duplicate.

    the effector will stop working on the duplicate setup after step four. effectors do not do
    anything with selections themselves i think, they just do carry arround the name string. 
    a generator object does relate to that name string when passing the modata to effector 
    methods.

    so you have either to stick with the selection name string provided by the effectors 
    description or you rely on  the modata passed to the effector methods, as it will contain 
    sort of the selection info.

    Well, they contain the name of the MoGraph selection tag which can be grabbed from the MoGraph
    generator object in ModifyPoints(). I couldn't find the selection info in the MoData array. But after
    taking another deep look into the c4d_baseeffector.h header, I found the
    MSG_GET_MODATASELECTION message! 🙂

        // Find the MoGraph selection tag.
        BaseTag* moTag = NULL;
        String moTagName = bc->GetString(ID_MG_BASEEFFECTOR_SELECTION);
        if (moTagName.Content()) moTag = gen->GetFirstTag();
        while (moTag) {
            if (moTag->IsInstanceOf(Tmgselection) && moTag->GetName() == moTagName) {
                break;
            }
            moTag = moTag->GetNext();
        }
      
        // Retrieve the BaseSelect from the MoGraph selection tag.
        BaseSelect* moSelection = NULL;
        if (moTag && moTag->IsInstanceOf(Tmgselection)) {
            GetMGSelectionMessage data = {0};
            moTag->Message(MSG_GET_MODATASELECTION, &data);
            moSelection = data.sel;
        }
    

    Thanks for your answer though, I appreciate your effort.

    Best,
    -Niklas



  • On 23/06/2013 at 12:25, xxxxxxxx wrote:

    I have this very heavily commented Mograph selection example in my notes.
    And I found it to be very useful.

    -The indices of the selected clones are stored in a BaseSelect object in the MoGraph Selection tag.   
    -In C++ the selection is accessed with BaseTag::Message().  
    -The result is sent to a GetMGSelectionMessage struct, which contains a single BaseSelect member.  
      
    #include "..\..\..\resource\_api\c4d_baseeffectordata.h"  
      
      
      BaseObject *obj = doc->SearchObject("Cloner");       //The cloner object  
      if(!obj) return FALSE;  
      
      BaseTag *moSelTag = obj->GetTag(Tmgselection,0);    //Look for a moselection tag starting from the first tag  
      if(!moSelTag) return FALSE;      
        
      AutoAlloc<BaseSelect> bs;                            //Create an empty BaseSelect      
      GetMGSelectionMessage msm = GetMGSelectionMessage(); //Create a struct to hold the tag data  
      moSelTag->Message(MSG_GET_MODATASELECTION, &msm);    //Grab the data from the tag and save it in the struct  
      msm.sel->CopyTo(bs);                                 //Copy it to the BaseSelect variable  
      
      LONG count = bs->GetCount();                         //Gets how many clones are currently selected  
      GePrint(LongToString(count));  
      
      //Loops through the BaseSelection's index#'s for the selected clones   
      LONG seg=0,a,b;    
      while (bs->GetRange(seg++,&a,&b))          //While searching through the selection's range of elements  
      {  
        for (LONG i=a; i<=b; ++i)                //if an element is true(the clone is selected)   
         {  
           GePrint(LongToString(i));             //Print the BaseSelect index# for the selected clone  
         }  
      }  
      
      //LONG tgl = bs->Toggle(0);                //Toggle the first moselection tag's element on/off  
      bs->CopyTo(msm.sel);                       //Update the struct to reflect the changes made with BaseSelect   
    

    -ScottA


Log in to reply