GetDataInstance to Set/GetParameter [SOLVED]

On 26/11/2015 at 22:05, xxxxxxxx wrote:

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

It seems like MAXON is recommending the use of SetParameter() && GetParameter() over the usual way of doing things with GetDataIntsance() and the resulting BaseContainer.

I'd like to bring some of my own code up to date (since a few plugins are still using the legacy API, which obviously won't fly with the R17 SDK). What I can't seem to figure out is the following things:

  1. What is the replacement for Get/SetUInt32() and Get/SetUInt64()? Both Get/SetParameter() seem to expect a GeData object as the second argument, but GeData doesn't seem to handle the unsigned versions of Int32/Int64?

  2. How do I handle object links through Get/SetParameter()? With the old method of going through the BaseContainer object, there was a SetLink() and GetLink() function that you could call which handled all of that. I see some reference to a BaseLink class in c4d_gedata.h, but there's no examples of how to use this.

Come to think of it, there's almost zero examples anywhere of how to use Set/GetParameter(), even though one of the stickies on this forum quite literally says "Please use GetParameter/SetParameter"... I've gone through the C++ SDK examples on github, and a lot of them are still using GetDataInstance(), and the few things that do use Get/SetParameter() don't actually show me what the equivalents are if I'm trying to migrate away from using GetDataInstance()...


On 27/11/2015 at 02:02, xxxxxxxx wrote:


one should use GetParameter() and SetParameter() to edit the parameters of other entities. This is because you cannot know if another entity stores its data really in its BaseContainer or not. Using SetParameter() for example will invoke SetDParameter() on the other element and there the other element can decide how to handle this request.

So when you edit the data of your own plugin classes you know where the data is stored so you can safely use the BaseContainer. If you edit the parameters of other objects, use SetParameter() and GetParameter().

SetParameter() and GetParamter() are there to edit the parameters of elements. Since there is no unsigned int parameter type (only DA_LONG and DA_LLONG), GeData does not handle unsigned int datatypes explicitly.

Object links are simple handled by creating a BaseLink object, storing it in a GeData object and handing it over to SetParameter(). And in return you can get the BaseLink object or the linked object from a GeData object used with GetParameter() :

// This example reads the object link of the given Instance Object.  
GeData data;  
if(instanceObject->GetParameter(DescID(INSTANCEOBJECT_LINK), data, DESCFLAGS_GET_0))  
  BaseList2D* linkedEntity = data.GetLink(doc);  
  if(linkedEntity && linkedEntity->IsInstanceOf(Obase))  
  BaseObject* linkedObject = static_cast<BaseObject*>(linkedEntity);  
  if (linkedObject)  
    GePrint("Linked Object: " + linkedObject->GetName());  
// This example sets the "Reference Object" parameter of the given Instance Object.  
AutoAlloc<BaseLink> link;  
GeData data;  
instanceObject->SetParameter(DescID(INSTANCEOBJECT_LINK), data, DESCFLAGS_SET_0);  

best wishes,

On 27/11/2015 at 08:13, xxxxxxxx wrote:

Thank you for the reply.

I have a couple more questions, if you don't mind:

  1. What is the difference between DescID() and DescLevel()? I see your code is using DescID() with Get/SetParameter(), but I've also seen code that uses DescLevel() instead (notably in the CPP SDK examples on github).

  2. How would I set an object link field to nothing using SetParameter()? With the base containers, it was possible to set a link to nothing using SetLink(nullptr). Is it safe to simply pass an empty GeData object to SetParameter(), or do I have to create an empty BaseLink first?


On 30/11/2015 at 01:28, xxxxxxxx wrote:


the DescID contains the ID of an object parameter. It is composed of several DescLevel elements. A parameter can contain sub-parameters. With the right description ID level, you can directly target the sub-parameters:

// set top level  
op->SetParameter(DescID(DescLevel(ID_BASEOBJECT_REL_POSITION, DTYPE_VECTOR, 0)), GeData(Vector(100, 200, 300)), DESCFLAGS_SET_0);  
// set sublevel  
op->SetParameter(DescID(DescLevel(ID_BASEOBJECT_REL_ROTATION, DTYPE_VECTOR, 0), DescLevel(VECTOR_X, DTYPE_REAL, 0)), GeData(1.0), DESCFLAGS_SET_0);  

To reset a BaseLink parameter it seems save to hand over an empty GeData object.

Best wishes,