Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Read MoGraph Selection from Effector plugin

    SDK Help
    0
    4
    407
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H
      Helper
      last edited by

      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

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        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.

        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          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

          1 Reply Last reply Reply Quote 0
          • H
            Helper
            last edited by

            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

            1 Reply Last reply Reply Quote 0
            • First post
              Last post