Why use Get/SetParameter and Get/SetDParameter

Usually Cinema4D store settings for nodes and tools in a BaseContainer.
BaseContainer is very useful class that allow you to store different data type in easy way.
But you will notice there are some cases where Cinema don’t store parameter in BaseContainer, for example some of light and camera parameters are not reachable by Get/Set BaseContainer Methods.

So why? In most of cases this happen because the data is dependent from another node proprieties (for example object matrix) or the value have to be computed each time and is not useful to store it as value.
Anyhow the simplest way to Get/Set value for nodes or tools is to use GetParameter() or SetParameter() that will ensure the fact that BaseContainer based value will be stored in correct way and other non BaseContainer parameter will be properly handled.

Here a typical Get/Set call to BaseContainer:

		BaseDocument* doc = GetActiveDocument();
		if (doc)
		{
			BaseObject* op = doc->GetFirstObject();
			if (op)
			{
				BaseContainer* bc = op->GetDataInstance();
				if (!bc)
				{
					Real axisLen = bc->GetReal(ID_AXISLEN);
					// do some with axislen
					
					// set back the value to BaseContainer
					bc->SetReal(ID_AXISLEN, axisLen);
					//.....
				}
			}
		}

and here you can find the same call with Get/SetParameter:

		BaseDocument* doc = GetActiveDocument();
		if (doc)
		{
			BaseObject* op = doc->GetFirstObject();
			if (op)
			{
				GeData d; // this is Cinema4D generic data container
				op->GetParameter(DescID(ID_AXISLEN), d, DESCFLAGS_GET_0);
				Real axisLen = d.GetReal();
				// do some with axislen
				
				// set back the value to op
				op->SetParameter(DescID(ID_AXISLEN), GeData(axisLen), DESCFLAGS_SET_0);
				//.....
			}
		}

in the example you can see three main difference:
– Get/SetParameter use GeData that is the generic data container in cinema, it can hold all types including CustomDataType so you have to extract the correct data from it after retrieved;
– Get/SetParameter is called to the node so is not needed to get container from it
– Get/SetParameter use Descriptions

Also for your plugins is possible to handle parameters in this way if is needed, to achieve the result you have to use NodeData::GetDParameter() and NodeData::SetDParameter() during your plugin implementation.

The concept is to implement in GetDparameter() how the parameter have to be retrieved/calculated and in SetDParameter how the parameter should affect all the “linked values” when the user modify it.
Here a simple example where ID_AXISLEN parameter is the object’s z scale:

class MyObject : public ObjectData
{
	INSTANCEOF(MyObject,ObjectData)
	
public:

	virtual Bool Init(GeListNode *node)
	{
		return TRUE;
	}
	
	virtual Bool GetDParameter(GeListNode* node, const DescID& id, GeData& t_data, DESCFLAGS_GET& flags)
	{
		switch (id[0].id)
		{
			case ID_AXISLEN:
			{
				BaseObject* op = (BaseObject*)node;
				if (op)
					break;
				
				// get Object scale
				Vector opScale = op->GetAbsScale();
				
				// pass z component to t_data
				t_data = GeData(opScale.z);
				
				// don't forget to set flags
				flags |= DESCFLAGS_GET_PARAM_GET;
				break;
			}
		}
		return SUPER::GetDParameter(node, id, t_data, flags);
	}
	
	virtual Bool SetDParameter(GeListNode* node, const DescID& id, const GeData& t_data, DESCFLAGS_SET& flags)
	{
		switch (id[0].id)
		{
			case ID_AXISLEN:
			{
				BaseObject* op = (BaseObject*)node;
				if (op)
					break;
				
				// get Object scale
				Vector opScale = op->GetAbsScale();
				
				// pass z component form t_data
				opScale = Vector(opScale.x, opScale.y, t_data.GetReal());
				
				// set back the new scale to op
				op->SetAbsScale(opScale);
				
				// don't forget to set flags
				flags |= DESCFLAGS_SET_PARAM_SET;
				break;
			}
		}
		return SUPER::SetDParameter(node, id, t_data, flags);
	}
	
	static NodeData *Alloc(void) { return gNew MyObject; }
};
Avatar

Francesco Guazzi

My passion for computer graphics was born when I was 17. After studying for more then 10 years I worked as a independent 3D Artist for arch viz and product viz.Some years ago I became interested in the world of programming realizing some plugin for Cinema4D for my daily work.Since 2011 I work as a developer for Maxon Computer gmbh.