Obtaining free DescId



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 20/11/2008 at 04:22, xxxxxxxx wrote:

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

    ---------
    Hello,

    I am adding user data from one object to another via a dynamic description (ddTarget). Works fine, if I use an existing descId:

    > ddTarget->Set(descId , \*bcSource, target);

    But how can I create a new DescID for that purpose so already existing user data in "target" will not be overridden?

    I tried

    > \> DescLevel descLevel(0); \> DescID descId(descLevel); \>

    but that doesn't work.

    Best regards
    Marcel-André



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 20/11/2008 at 10:54, xxxxxxxx wrote:

    Each DescID needs a unique ID (not as in a PluginID but as unique within the DescIDs being used for the type).

    DescLevel descLevel(0) has an ID of 0. No good. Description ID's are recommended to start at 1000 or 2000 for shaders (as described in the docs under Description Resource).

    If you need to have flexible DescID ID values, you'll need to set aside a range of values and track the last one used with its own static DescID in the .h/.res file.

    For example, in the .h file, you have a static DescID to track the dynamic user data IDs:

    mytype.h
    --------
    enum
    {
         IDC_MYBUTTON = 1000,
         ...
         // My UserData IDs use ID range 5000+
         IDC_LASTUSERDATA = 1500,
         IDC_DUMMY
    };

    mytype.res
    ----------
    CONTAINER Oippbase
    {
         NAME     Oippbase;
         INCLUDE Obase;

    GROUP     ID_OBJECTPROPERTIES
         {
              ...
              LONG IDC_LASTUSERDATA { HIDDEN; ANIM OFF; }
              ...
         }
         ...
    }

    // In the type class header or cpp file
    const LONG MUD_IDSTART = 5000L;

    You initialize IDC_LASTUSERDATA to MUD_IDSTART. Now, everytime a new UserData is added, you get the value of IDC_LASTUSERDATA to use as the UserData's ID, increment the value and set IDC_LASTUSERDATA to the new value. To Get/Set the value, simply get the BaseContainer of your type using:

    BaseContainer* bc = (static_cast<BaseList2D*>(node))->GetDataInstance();
    LONG lud = bc->GetLong(IDC_LASTUSERDATA);
    ...
    ++lud;
    bc->SetLong(IDC_LASTUSERDATA, lud);



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 21/11/2008 at 06:50, xxxxxxxx wrote:

    Hello Robert,

    your solution didn't exactly match my problem but I figured it out. Thanks for the reply anyway.

    I needed to get a DescID that is not used by any other user data created by the user in a normal object (like a cube). As I have to add user data via code after the user does, I cannot track DescIDs because I don't know the ID of the last user data item.

    Here is my solution to retrieve this very data:

    > DynamicDescription\* ddTarget = target->GetDynamicDescription(); \> DescID newId = DescID(); \> DescID currentId; \> const BaseContainer\* bcTarget; \> \> void\* handle = ddTarget->BrowseInit(); \> while (ddTarget->BrowseGetNext(handle, &currentId;, &bcTarget;)) \> { \> if (currentId.GetDepth() > 1) \> { \>     //retrieve the highest id and save it into newId \>     if (currentId[1].id > currentId[1].id) \>     { \>       newId = DescID(ID_USERDATA, currentId[1].id); \>     } \> } \> } \> ddTarget->BrowseFree(handle); \> \> // increment newId by 1 to get an unused id for user data \> if (newId != DescID()) newId = DescID(ID_USERDATA, newID[1].id + 1); \>



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 07/01/2009 at 00:51, xxxxxxxx wrote:

    Ok, after a little bit more in depth research I think I found the "official" way to obtain the next free DescID:

    > DynamicDescription\* dd = object->GetDynamicDescription(); \> BaseContainer descriptionParameters; \> dd->FillDefaultContainer(descriptionParameters, DTYPE_STRING, "New User Data"); \> DescID newId = dd->Alloc(descriptionParameters); \> dd->Set(newId, descriptionParameters, obj);

    Where newId is the next free DescID.
    By the way: The documentation for DynamicDescription states the Set function is declared as following:

    > Bool Set(const DescID& descid, const BaseContainer& datadescription);

    while the actual api implementation is:

    > Bool Set(const DescID& descid, const BaseContainer& datadescription, BaseList2D\* bl);

    Does anyone know what the BaseList2D parameter is used for?

    cheers
    Macm


Log in to reply