Get/SetDParameter + CUSTOMDATATYPE_SPLINE [SOLVED]



  • On 21/06/2015 at 00:13, xxxxxxxx wrote:

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

    ---------
    as the title says, got a single problem.
    data read/write seems ok, as I can change the data as needed, BUT I can't animate the data "shows orange dot instead of red dot",  "all other standard data types like float/int/vector,.. are working ok"

    what am I missing?

      
    //SetDParameter
    myData = t_data;
    flags |= DESCFLAGS_SET_PARAM_SET;
    //setting parameter  
    /*some private code for setting parameter */
    return MaterialData::SetDParameter(node, id, t_data, flags);  
      
    //GetDParameter
    t_data = myData;
    flags |= DESCFLAGS_GET_PARAM_GET;  
    return MaterialData::GetDParameter(node, id, t_data, flags);
    

    I remember a similar problem happend with Vectors "the solution was using a macro which is setting t_data with id[1].id data, my problem here is HOW to get this id[1].id data???"

    an old thread which got the Vectors "solved" problem,
    https://plugincafe.maxon.net/topic/8709/11406_show-subchannels-from-getddescription-solved&KW=vector



  • On 02/07/2015 at 08:48, xxxxxxxx wrote:

    Hi Mohamed,

    I'm sorry, but I don't fully understand. Normally you don't have to do anything special with a spline datatype in a description, in order to get keyframes working.
    I tried it here in the simple_material example and it just worked.

    In the video you posted in the other thread, I saw you are trying to use it in the left column of the Material editor. So I tried this in the simple_material example, too. No problem, either.

    I did not implement anything in Get/SetDParameter() for my tests.

    Perhaps there's some detail I'm missing? Or can you post some more code?



  • On 02/07/2015 at 09:21, xxxxxxxx wrote:

    without Get/SetDParamter() everything is fine, except initial values are black.
    Init() can't be used here "as values are added dynamically, so Init() is useless"

    how my paramters are created:
    user interacts with GeUserArea
    parameter is added inside GeUserArea
    GeUserArea notifies CustomDataType
    this CustomDataType is a Description inside the MaterialData plugin

    example:
    user rightclick->add Diffuse BSDF-> it will create a Diffuse BSDF node in the user area with the initial values "for example white color"
    then these data will get read through Get/SetDParameter(), if I don't use those Get/SetDParamter() initial values are always 0.
    what should I do? "I wish to avoid Get/SetDParamter() as they make a headache"



  • On 03/07/2015 at 06:08, xxxxxxxx wrote:

    Can you post some code? If you want to keep it secret, you could also send it to sdk_support or via PM.
    I'd also be interested in the Get/SetDParameter() implementation, that broke the keyframes.



  • On 03/07/2015 at 07:42, xxxxxxxx wrote:

    sure, here is some code:
    in MaterialData:

      
    Bool SevenPhotonsMaterial::GetDParameter(GeListNode* node, const DescID& id, GeData& t_data, DESCFLAGS_GET& flags)
    {
    	BaseContainer* data = ((BaseMaterial* )node)->GetDataInstance();
    	GeData knd(SEVENPHOTONS_NODE_CUSTOMDATATYPE, iSnodeDataType(m_type));
    	data->GetParameter(SEVENPHOTONS_MAT_NODE, knd);
    	iSnodeDataType* kndData = static_cast<iSnodeDataType*> (knd.GetCustomDataType(SEVENPHOTONS_NODE_CUSTOMDATATYPE));
      
    	if(id[0].id == SEVENPHOTONS_MAT_PREVIEW)
    	{
    		return GetDParameterPreview(data, (GeData* )&t_data, flags, SEVENPHOTONS_MAT_PREVIEW, updatecount, (BaseMaterial* )node);
    	}
    	else if(kndData->selectedNode > 0)
    	{
    		if(kndData->nodes[kndData->selectedNode].getInternalCount() > 0)
    		{
    			for(Int32 i = 0; i < kndData->nodes[kndData->selectedNode].getInternalCount(); ++i)
    			{
    				Int32 ids = kndData->nodes[kndData->selectedNode].getInternalID(i);
      
    				if(id[0].id == ids)
    				{
    					if(kndData->nodes[kndData->selectedNode].getInternalDataType(i) & SEVENPHOTONS_NODE_ANYTHREE)
    					{
    						Vector vdata = (kndData->nodes[kndData->selectedNode].getInternalData(i)).GetVector();
    						HandleDescGetVector(id, vdata, t_data, flags);
    					}
    					else if(kndData->nodes[kndData->selectedNode].getInternalDataType(i) == SEVENPHOTONS_NODE_CURVE)
    					{
    						t_data = kndData->nodes[kndData->selectedNode].getInternalData(i);
    						flags |= DESCFLAGS_GET_PARAM_GET;
    					}
    					else
    					{						
    						t_data = kndData->nodes[kndData->selectedNode].getInternalData(i);
    						//data->SetString(ids, kndData->nodes[kndData->selectedNode].getName());
    						flags |= DESCFLAGS_GET_PARAM_GET;
    					}
    					return MaterialData::GetDParameter(node, id, t_data, flags);
    				}
    			}
    		}
      
    		if(kndData->nodes[kndData->selectedNode].getInputCount() > 0)
    		{
    			for(Int32 i = 0; i < kndData->nodes[kndData->selectedNode].getInputCount(); ++i)
    			{
    				Int32 ids = kndData->nodes[kndData->selectedNode].getInputID(i);
    				//wire connected
    				if(kndData->nodes[kndData->selectedNode].getInputWireId(i) >= 0)
    					continue;
      
    				if(id[0].id == ids)
    				{
    					if(kndData->nodes[kndData->selectedNode].getInputDataType(i) & SEVENPHOTONS_NODE_ANYTHREE)
    					{
    						Vector vdata = (kndData->nodes[kndData->selectedNode].getInputData(i)).GetVector();
    						HandleDescGetVector(id, vdata, t_data, flags);
    					}
    					else
    					{						
    						t_data = kndData->nodes[kndData->selectedNode].getInputData(i);
    						//data->SetString(ids, kndData->nodes[kndData->selectedNode].getName());
    						flags |= DESCFLAGS_GET_PARAM_GET;
    					}
    					return MaterialData::GetDParameter(node, id, t_data, flags);
    				}
    			}
    		}
    	}
      
    	return MaterialData::GetDParameter(node, id, t_data, flags);
    }
      
    Bool SevenPhotonsMaterial::SetDParameter(GeListNode* node, const DescID& id, const GeData& t_data, DESCFLAGS_SET& flags)
    {
    	BaseContainer* data = ((BaseMaterial* )node)->GetDataInstance();
    	GeData knd(SEVENPHOTONS_NODE_CUSTOMDATATYPE, iSnodeDataType(m_type));
    	data->GetParameter(SEVENPHOTONS_MAT_NODE, knd);
    	iSnodeDataType* kndData = static_cast<iSnodeDataType*> (knd.GetCustomDataType(SEVENPHOTONS_NODE_CUSTOMDATATYPE));
      
    	updatecount++;
      
    	if(id[0].id == SEVENPHOTONS_MAT_PREVIEW)
    	{
    		return SetDParameterPreview(data, &t_data, flags, SEVENPHOTONS_MAT_PREVIEW);
    	}
    	else if(kndData->selectedNode > 0)
    	{
    		//if(id[0].id == ++ids)
    		//{
    		//	kndData->nodes[kndData->selectedNode].setName(t_data.GetString());
    		//	kndData->nodes[kndData->selectedNode].adjustSNode(false);
    		//	data->SetParameter(SEVENPHOTONS_MAT_NODE, GeData(SEVENPHOTONS_NODE_CUSTOMDATATYPE, *kndData));
    		//	return MaterialData::SetDParameter(node, id, t_data, flags);
    		//}
    		if(kndData->nodes[kndData->selectedNode].getInternalCount() > 0)
    		{
    			for(Int32 i = 0; i < kndData->nodes[kndData->selectedNode].getInternalCount(); ++i)
    			{
    				Int32 ids = kndData->nodes[kndData->selectedNode].getInternalID(i);
      
    				if(id[0].id == ids)
    				{
    					if(kndData->nodes[kndData->selectedNode].getInternalDataType(i) & SEVENPHOTONS_NODE_ANYTHREE)
    					{
    						Vector vdata = (kndData->nodes[kndData->selectedNode].getInternalData(i)).GetVector();
    						HandleDescSetVector(vdata, id, vdata, t_data, flags);
    						kndData->nodes[kndData->selectedNode].setInternalData(i, GeData(vdata));
    					}
    					else if(kndData->nodes[kndData->selectedNode].getInternalDataType(i) == SEVENPHOTONS_NODE_CURVE)
    					{
    						kndData->nodes[kndData->selectedNode].setInternalData(i, t_data);
    						flags |= DESCFLAGS_SET_PARAM_SET;
    					}
    					else
    					{						
    						kndData->nodes[kndData->selectedNode].setInternalData(i, t_data);
    						flags |= DESCFLAGS_SET_PARAM_SET;
    					}
    					data->SetParameter(SEVENPHOTONS_MAT_NODE, GeData(SEVENPHOTONS_NODE_CUSTOMDATATYPE, *kndData));
    					return MaterialData::SetDParameter(node, id, t_data, flags);
    				}
    			}
    		}
      
    		if(kndData->nodes[kndData->selectedNode].getInputCount() > 0)
    		{
    			for(Int32 i = 0; i < kndData->nodes[kndData->selectedNode].getInputCount(); ++i)
    			{
    				Int32 ids = kndData->nodes[kndData->selectedNode].getInputID(i);
    				//wire connected
    				if(kndData->nodes[kndData->selectedNode].getInputWireId(i) >= 0)
    					continue;
      
    				if(id[0].id == ids)
    				{
    					if(kndData->nodes[kndData->selectedNode].getInputDataType(i) & SEVENPHOTONS_NODE_ANYTHREE)
    					{
    						Vector vdata = (kndData->nodes[kndData->selectedNode].getInputData(i)).GetVector();
    						HandleDescSetVector(vdata, id, vdata, t_data, flags);
    						kndData->nodes[kndData->selectedNode].setInputData(i, vdata);
    					}
    					else
    					{						
    						kndData->nodes[kndData->selectedNode].setInputData(i, t_data);
    						flags |= DESCFLAGS_SET_PARAM_SET;
    					}
    					data->SetParameter(SEVENPHOTONS_MAT_NODE, GeData(SEVENPHOTONS_NODE_CUSTOMDATATYPE, *kndData));
    					return MaterialData::SetDParameter(node, id, t_data, flags);
    				}
    			}
    		}
    	}
      
    	return MaterialData::SetDParameter(node, id, t_data, flags);
    }  
    

    tell me which portions you want, as I guess GeUserArea and CustomDataType portions are not needed here.

    I will post more code soon if needed.



  • On 04/07/2015 at 09:54, xxxxxxxx wrote:

    I noticed that if I remove Get/SetDParamter() , I can't access the modified data, so I have to use them.



  • On 10/07/2015 at 09:09, xxxxxxxx wrote:

    Hi Mohamed,

    terribly sorry, this took so long. I have to admit, I went down the wrong road all the way to the end, before I realized, I took the wrong branch. My fault!
    In Germany we say: Shooting yourself into your own knee. 😉

    Also I have no clean example code to post here, yet. But before entering my weekend, I still wanted to provide you some infos.

    Basically you were right in the beginning with your assumption, that it's similar to handling a vector. Unfortunately there's no macro nor any defines for the CUSTOMGUI_SPLINE.
    Here's how you do it manually:
    After checking, that your spline got addressed (id[0].id == your spline id), you need to check if id[1].id.
    If it is zero, t_data is of type CUSTOMDATATYPE_SPLINE. So you get a complete updated spline.
    If it is unequal zero, then you need to handle the "subchannels".
    If the id[1].id is greater 10000, you can use this:

    Int32 knotIdx = (id[1].id - 11100) / 100;
    Int32 partIdx = id[1].id - (11100 + (knotIdx * 100));
    

    knotIdx can be used directly with GetKnot().
    partIdx decodes as follows:
    0: position x
    1: position y
    2: left tangent x
    3: left tangent y
    4: right tangent x
    5: right tangent y

    I hope this helps. On Monday I will probably post some more code. Also there are more subchannels (that's why > 10000).



  • On 10/07/2015 at 09:54, xxxxxxxx wrote:

    great
    about decoding partIdx, is this bit masks? (1 << 0, 1 << 1, ...) or just Int32 values?
    also waiting for all subchannels, the same for Gradient "as it is very similar, it has its post though"

    thanks for the help Andreas.



  • On 10/07/2015 at 22:46, xxxxxxxx wrote:

    Hi Mohamed,

    no, it's not a bit mask, just integer. And the data you get is of type Float.



  • On 28/07/2015 at 17:45, xxxxxxxx wrote:

    Hi Andreas,

    I tried to fix the spline Get/SetDParameter, but this is a nightmare...
    there are a lot of unknown description ids "not shown by show sub-channels"

    any idea how to iterate over all sub channels and set/get as required?
    here is what I did so far, works fine to some extent "tangents and point count are making a problem, if you animate point count the behavior is undefined"

      
    inline void HandleDescGetSpline(const DescID &tid, SplineData *curve, GeData &t_data, DESCFLAGS_GET &flags)
    {
    	Int32 knotIdx = (tid[1].id - 11100) / 100;
    	Int32 partIdx = tid[1].id - (11100 + (knotIdx * 100));
      
    	CustomSplineKnot* knot = curve->GetKnot(knotIdx);
    	switch(partIdx)
    	{
    	default:
    	case 0:
    		t_data.SetFloat(knot->vPos.x);
    		flags |= DESCFLAGS_GET_PARAM_GET;
    		break;
    	case 1:
    		t_data.SetFloat(knot->vPos.y);
    		flags |= DESCFLAGS_GET_PARAM_GET;
    		break;
    	case 2:
    		t_data.SetFloat(knot->vTangentLeft.x);
    		flags |= DESCFLAGS_GET_PARAM_GET;
    		break;
    	case 3:
    		t_data.SetFloat(knot->vTangentLeft.y);
    		flags |= DESCFLAGS_GET_PARAM_GET;
    		break;
    	case 4:
    		t_data.SetFloat(knot->vTangentRight.x);
    		flags |= DESCFLAGS_GET_PARAM_GET;
    		break;
    	case 5:
    		t_data.SetFloat(knot->vTangentRight.y);
    		flags |= DESCFLAGS_GET_PARAM_GET;
    		break;
    	}
    }
      
    inline void HandleDescSetSpline(const DescID &tid, SplineData *curve, const GeData &t_data, DESCFLAGS_SET &flags)
    {
    	Int32 knotIdx = (tid[1].id - 11100) / 100;
    	Int32 partIdx = tid[1].id - (11100 + (knotIdx * 100));
      
    	CustomSplineKnot* knot = curve->GetKnot(knotIdx);
    	switch(partIdx)
    	{
    	default:
    	case 0:
    		knot->vPos.x = t_data.GetFloat();
    		flags |= DESCFLAGS_SET_PARAM_SET;
    		break;
    	case 1:
    		knot->vPos.y = t_data.GetFloat();
    		flags |= DESCFLAGS_SET_PARAM_SET;
    		break;
    	case 2:
    		knot->vTangentLeft.x = t_data.GetFloat();
    		flags |= DESCFLAGS_SET_PARAM_SET;
    		break;
    	case 3:
    		knot->vTangentLeft.y = t_data.GetFloat();
    		flags |= DESCFLAGS_SET_PARAM_SET;
    		break;
    	case 4:
    		knot->vTangentRight.x = t_data.GetFloat();
    		flags |= DESCFLAGS_SET_PARAM_SET;
    		break;
    	case 5:
    		knot->vTangentRight.y = t_data.GetFloat();
    		flags |= DESCFLAGS_SET_PARAM_SET;
    		break;
    	}
    }  
    
      
    						else if(kndData->nodes[mnode].getInternalDataType(i) == SEVENPHOTONS_NODE_CURVE)
    						{
    							if(id[1].id == 0)
    							{
    								kndData->nodes[mnode].setInternalData(i, t_data);
    								data->SetParameter(DescID(id[0].id), t_data);
    								flags |= DESCFLAGS_SET_PARAM_SET;
    							}
    							else if(id[1].id == 1000)
    							{
    								//kndData->nodes[mnode].setInternalData(i, GeData(1.f));
    								//data->SetParameter(DescID(id[0].id, id[1].id), GeData(1.f));
    								//flags |= DESCFLAGS_SET_PARAM_SET;
    							}
    							else
    							{
    								//SplineData *curve = (SplineData* )t_data.GetCustomDataType(CUSTOMDATATYPE_SPLINE);
    								SplineData *curve = (SplineData* )(kndData->nodes[mnode].getInternalData(i)).GetCustomDataType(CUSTOMDATATYPE_SPLINE);
    								HandleDescSetSpline(id, curve, t_data, flags);
    							}
    						}  
    
      
    						else if(kndData->nodes[mnode].getInternalDataType(i) == SEVENPHOTONS_NODE_CURVE)
    						{
    							if(id[1].id == 0)
    							{
    								t_data = GeData(CUSTOMDATATYPE_SPLINE, *(kndData->nodes[mnode].getInternalData(i)).GetCustomDataType(CUSTOMDATATYPE_SPLINE));
    								flags |= DESCFLAGS_GET_PARAM_GET;
    							}
    							else if(id[1].id == 1000)
    							{
    								//t_data.SetFloat(1.f);
    								//flags |= DESCFLAGS_GET_PARAM_GET;
    							}
    							else
    							{
    								SplineData *curve = (SplineData* )(kndData->nodes[mnode].getInternalData(i)).GetCustomDataType(CUSTOMDATATYPE_SPLINE);
    								HandleDescGetSpline(id, curve, t_data, flags);
    							}
    						}  
    


  • On 25/08/2015 at 08:56, xxxxxxxx wrote:

    By now, there's an example on GitHub, demonstrating this.



  • On 25/08/2015 at 10:09, xxxxxxxx wrote:

    thanks Andreas, is it the same?



  • On 26/08/2015 at 08:53, xxxxxxxx wrote:

    To explain Mohamed's question: We were in direct communication and he received the example before it got published on GitHub.
    @Mohamed: Yes, it's basically the same.


Log in to reply