huge problem with GetDDescription() [SOLVED]



  • On 06/05/2015 at 19:39, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   15+ 
    Platform:   Windows  ;   
    Language(s) :     C++  ;

    ---------
    this problem "can be solved" , but I don't know how Hug

    I have a MaterialData plugin, most of its description are dynamic "using GetDDescription"

    it is a node based Material "CustomDataType" , with its GeUserArea.
    each node "from my custom nodes" , got its own attributes, stored inside its class, like data type, data name, data value, connections , ....

    when the user selects a node, I mark this node.
    in GetDDescription() , I get the marked node, loop over its data, check their type, add the Descriptions dynamically.

    when I modify any value from the node, it is stored in the class, restored also using Set/GetDParameter()

    so far so good, dynamic descriptions, values are fine, and here comes a nightmare problem!!
    if I animate any description "for example in node 1" , it also animates the same description in all other nodes "the index of the description"

    note: kndData is a CustomDataType subclass
    here is the stripped portion of GetDDescription:

    			for(Int32 i = 0; i < kndData->nodes[kndData->selectedNode].getInputCount(); ++i)
    			{
    				++ids;
    				//wire connected
    				if(kndData->nodes[kndData->selectedNode].getInputWireId(i) >= 0)
    					continue;
      
    				Int32 idt = kndData->nodes[kndData->selectedNode].getInputDataType(i);
    				switch(idt)
    				{
    				case NODE_BOOL:
    					cid = DescLevel(ids, DTYPE_BOOL, 0);
    					if (!singleid || cid.IsPartOf(*singleid, nullptr))// important to check for speedup c4d!
    					{
    						BaseContainer dt = GetCustomDataTypeDefault(DTYPE_BOOL);
    						std::string dName = kndData->nodes[kndData->selectedNode].getInputDataName(i);
    						String dtName(dName.c_str());
    						dt.SetString(DESC_SHORT_NAME, dtName);
    						dt.SetString(DESC_NAME, dtName);
    						dt.SetBool(DESC_ANIMATE, DESC_ANIMATE_ON);
    						if (!description->SetParameter(cid, dt, DescLevel(Tbaselist2d)))
    							return true;
    					}
    					break;
    				case NODE_FLOAT:
    					cid = DescLevel(ids, DTYPE_REAL, 0);
    					if (!singleid || cid.IsPartOf(*singleid, nullptr))// important to check for speedup c4d!
    					{
    						BaseContainer dt = GetCustomDataTypeDefault(DTYPE_REAL);
    						std::string dName = kndData->nodes[kndData->selectedNode].getInputDataName(i);
    						String dtName(dName.c_str());
    						dt.SetString(DESC_SHORT_NAME, dtName);
    						dt.SetString(DESC_NAME, dtName);
    						dt.SetBool(DESC_ANIMATE, DESC_ANIMATE_ON);
    						if (!description->SetParameter(cid, dt, DescLevel(Tbaselist2d)))
    							return true;
    					}
    					break;
    				case NODE_INT:
    					cid = DescLevel(ids, DTYPE_LONG, 0);
    					if (!singleid || cid.IsPartOf(*singleid, nullptr))// important to check for speedup c4d!
    					{
    						BaseContainer dt = GetCustomDataTypeDefault(DTYPE_LONG);
    						std::string dName = kndData->nodes[kndData->selectedNode].getInputDataName(i);
    						String dtName(dName.c_str());
    						dt.SetString(DESC_SHORT_NAME, dtName);
    						dt.SetString(DESC_NAME, dtName);
    						dt.SetBool(DESC_ANIMATE, DESC_ANIMATE_ON);
    						if (!description->SetParameter(cid, dt, DescLevel(Tbaselist2d)))
    							return true;
    					}
    					break;
    				case NODE_COLOR:
    					cid = DescLevel(ids, DTYPE_COLOR, 0);
    					if (!singleid || cid.IsPartOf(*singleid, nullptr))// important to check for speedup c4d!
    					{
    						BaseContainer dt = GetCustomDataTypeDefault(DTYPE_COLOR);
    						std::string dName = kndData->nodes[kndData->selectedNode].getInputDataName(i);
    						String dtName(dName.c_str());
    						dt.SetString(DESC_SHORT_NAME, dtName);
    						dt.SetString(DESC_NAME, dtName);
    						dt.SetBool(DESC_ANIMATE, DESC_ANIMATE_ON);
    						dt.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_COLOR);
    						if (!description->SetParameter(cid, dt, DescLevel(Tbaselist2d)))
    							return true;
    					}
    					break;
    				case NODE_VECTOR:
    				case NODE_POINT:
    				case NODE_NORMAL:
    					cid = DescLevel(ids, DTYPE_VECTOR, 0);
    					if (!singleid || cid.IsPartOf(*singleid, nullptr))// important to check for speedup c4d!
    					{
    						BaseContainer dt = GetCustomDataTypeDefault(DTYPE_VECTOR);
    						std::string dName = kndData->nodes[kndData->selectedNode].getInputDataName(i);
    						String dtName(dName.c_str());
    						dt.SetString(DESC_SHORT_NAME, dtName);
    						dt.SetString(DESC_NAME, dtName);
    						dt.SetBool(DESC_ANIMATE, DESC_ANIMATE_ON);
    						dt.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_VECTOR);
    						if (!description->SetParameter(cid, dt, DescLevel(Tbaselist2d)))
    							return true;
    					}
    					break;
    				case NODE_CLOSURE:
    				case NODE_VOLUME:
    					continue;
    					break;
    				case NODE_STRING:
    					cid = DescLevel(ids, DTYPE_STRING, 0);
    					if (!singleid || cid.IsPartOf(*singleid, nullptr))// important to check for speedup c4d!
    					{
    						BaseContainer dt = GetCustomDataTypeDefault(DTYPE_STRING);
    						std::string dName = kndData->nodes[kndData->selectedNode].getInputDataName(i);
    						String dtName(dName.c_str());
    						dt.SetString(DESC_SHORT_NAME, dtName);
    						dt.SetString(DESC_NAME, dtName);
    						dt.SetBool(DESC_ANIMATE, DESC_ANIMATE_ON);
    						dt.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_STRING);
    						if (!description->SetParameter(cid, dt, DescLevel(Tbaselist2d)))
    							return true;
    					}
    					break;
    				default:
    					break;
    				}
    			}
    


  • On 06/05/2015 at 20:00, xxxxxxxx wrote:

    I got a solution "but a really bad one" , which is:do a large enum over all nodes with their inputs
    node A:input a, input b, input c
    node B:input a, input b

    so enum will be (0,1,2 for node A), (3,4 for node B)
    this is a maintenance disaster though, I'm up to any better solution.



  • On 11/05/2015 at 11:10, xxxxxxxx wrote:

    Hello,

    you cannot "animate any description". You only can animate parameters of objects. So when you add a description and you animate the parameter, the object (in this case the material) stores the animation for the given ID in a CTrack. So if you use the same ID, it is the same parameter and thus the same CTrack. The Description class is just a tool used to communicate between an Cinema 4D entity and the GUI element drawing the parameters.

    So if you use custom "nodes" and you want to animate these nodes but these nodes are not based on standard Cinema 4D classes, you have to build your own animation system.

    Best wishes,
    Sebastian



  • On 11/05/2015 at 15:28, xxxxxxxx wrote:

    ok, so far I find the solution, but one related question:
    what is the possible ids range? "I will create a unique ID system, so I need a large range, may be 16bit range".



  • On 12/05/2015 at 01:13, xxxxxxxx wrote:

    Hello,

    in the end the data is stored in the object's BaseContainer. A BaseContainer uses a Int32 for the ID which is a signed int.

    best wishes,
    Sebastian



  • On 16/05/2015 at 21:28, xxxxxxxx wrote:

    thanks Sebastian for the help, I have solved the problem now with a unique IDs, you can mark this as solved.


Log in to reply