make UserData in C++



  • On 02/09/2013 at 21:14, xxxxxxxx wrote:

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

    ---------
    Hi

    Is it possible to add User Data (as in the User Data tab of the Attributes window) to an object that is created in my code? I guess you use GetDynamicDescription to access existing User Data.

    Thanks

    Peter



  • On 03/09/2013 at 01:02, xxxxxxxx wrote:

    Exactly. You can use DynamicDescription::Alloc(), passing the user-data's description as a
    BaseContainer, to append a new user-data parameter. The description ID of the new parameter
    will be returned.



  • On 04/09/2013 at 13:34, xxxxxxxx wrote:

    Thanks NiklasR

    I am currently trying to find example code and wading through the docs to find how to actually do this.
    My understanding is a bit nebulous at this point.

    Peter



  • On 04/09/2013 at 13:50, xxxxxxxx wrote:

    Bool AddShaderField(BaseObject* op) {
        String name = GeLoadString(IDS_SHADERCOLLECTION_ADDSHADERDEFAULTNAME);
        Bool success = RenameDialog(&name);

    // Break if the rename dialog was canceled.
        if (!success) {
            return TRUE;
        }

    // Create a cusotm datatype container.
        BaseContainer container = GetCustomDataTypeDefault(DTYPE_BASELISTLINK);
        container.SetString(DESC_NAME, name);
        container.SetString(DESC_SHORT_NAME, name);
        container.SetLong(DESC_CUSTOMGUI, CUSTOMGUI_TEXBOX);

    // Obtain the object's user-data description.
        DynamicDescription* desc = op->GetDynamicDescription();
        if (!desc) {
            MessageDialog(GeLoadString(IDS_SHADERCOLLECTION_ADDSHADERDDERROR, __FILE__, LongToString(__LINE__)));
            return FALSE;
        }

    // Create a new UserData entry.
        desc->Alloc(container);
        return TRUE;
    }



  • On 04/09/2013 at 16:56, xxxxxxxx wrote:

    Thanks. That made it much clearer. The ways of the SDK are often very mysterious to me.

    Peter



  • On 04/09/2013 at 21:16, xxxxxxxx wrote:

    And  promptly a new question pops up.

    How can I create groups? Or, actually I did create a group like this:

                        bc = GetCustomDataTypeDefault(DTYPE_GROUP);
                        bc.SetString(DESC_NAME, "General");
                        bc.SetString(DESC_SHORT_NAME, "General");
                        bc.SetBool(DESC_GUIOPEN, TRUE);
                        bc.SetBool(DESC_TITLEBAR, TRUE);
                        desc->Alloc(bc);
    

    But how to I move my other data into the group?
    Do you use DESC_PARENTGROUP, DESC_PARENTID?



  • On 05/09/2013 at 07:59, xxxxxxxx wrote:

    Small example without any error checking stuff:

    //This example creates a group UserData item  
    //Then it creates a Real type userData item as a child of the group  
      
      BaseDocument *doc = GetActiveDocument();  
      BaseObject *obj = doc->GetActiveObject();  
      
      DynamicDescription* dd = obj->GetDynamicDescription();  
      
      BaseContainer groupContainer;  
      dd->FillDefaultContainer(groupContainer, DTYPE_GROUP, "New Group");  
      DescID groupID = dd->Alloc(groupContainer);  
      dd->Set(groupID, groupContainer, obj);  
      
      BaseContainer realContainer;  
      dd->FillDefaultContainer(realContainer, DTYPE_REAL, "New Real");  
      GeData dataID;  
      dataID.SetCustomDataType(CUSTOMDATATYPE_DESCID, groupID);  
      realContainer.SetData(DESC_PARENTGROUP, dataID);  
      DescID realID = dd->Alloc(realContainer);  
      dd->Set(realID, realContainer, obj);
    

    -ScottA



  • On 06/09/2013 at 13:56, xxxxxxxx wrote:

    Great. That works although I am not sure I would have come up with it. In retrospect it looks logical.

    Thanks

    Peter



  • On 09/09/2013 at 15:38, xxxxxxxx wrote:

    And here we go again. I find DynamicDescription dramatically confusing because references to it are all over the place in the documentation. I understand groups now but I am stuck at how to implement a Popup menu. I suppose you use DTYPE_POPUP to make a container for the menu and use DESC_CYCLE to populate it?



  • On 10/09/2013 at 01:30, xxxxxxxx wrote:

    With "Popup menu", do you mean a Cycle field? The elements in a Cycle field are described using a
    BaseContainer. Take a look at the documentation of the Description class, all IDs are listed up there
    with quite good description.

    BaseContainer cycle;
    cycle.SetString(0, "Cycle Value 0");
    cycle.SetString(1, "Cycle Value 1");
    itemdesc->SetContainer(DESC_CYCLE, cycle);
    

    Best,
    -Niklas



  • On 10/09/2013 at 08:19, xxxxxxxx wrote:

    The popup button doesn't seem to work like the ComboButton Nik.
    It's either broken. Or the the way we populate it with entries is different.

    Example that adds a UD ComboButton to the active object:

        BaseObject *obj = doc->GetActiveObject();  
      if (!obj) return FALSE;  
      
      //Create a list of ComboButton values  
      BaseContainer names;  
      names.SetString(0,"Scott");  
      names.SetString(1,"Nicklas");  
      
      BaseContainer bc = NULL;  
      bc.SetString(DESC_NAME, "My Combo");  
      bc.SetString(DESC_SHORT_NAME, "My Combo");  
      bc.SetLong(DESC_CUSTOMGUI, CUSTOMGUI_CYCLEBUTTON);  //<--- put CUSTOMGUI_POPUP here and it no longer works!!!  
      bc.SetContainer(DESC_CYCLE, names);  
      
      //Get the object's master UD container that holds all the UserData entries  
      DynamicDescription *dd = obj->GetDynamicDescription();  
      if(!dd) return FALSE;  
      
      //Create a new UserData entry using the container values above  
      dd->Alloc(bc);  
      SendCoreMessage(COREMSG_CINEMA, BaseContainer(COREMSG_CINEMA_FORCE_AM_UPDATE)); //Refresh the AM to see the changes in real time  
      EventAdd();
    

    -ScottA


Log in to reply