Updating userdata gradient hangs cinema

On 09/12/2016 at 05:16, xxxxxxxx wrote:

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

---------
I want to update the userdata gradient.
Getting the information is ok, but updating and wrting back the knots is not ok.
Cinema 4d hangs!

obj->GetParameter(dscID, d, DESCFLAGS_GET_0);   //Get the info of this specific UD item and store the values in "d"
Gradient* gd = (Gradient* )d.GetCustomDataType(CUSTOMDATATYPE_GRADIENT);
  
Int32 kcnt = UDfloorGradientKnots.GetCount();		//knots previous stored
  
gd->FlushKnots();	
  
for (i=0; i<kcnt; i++) {	
  eFKnot = UDfloorGradientKnots[i];
  knot.col = eFKnot.col;
  knot.pos = eFKnot.pos;					
  gd->SetKnot(i, knot);	
}   
  
d.SetCustomDataType(CUSTOMDATATYPE_GRADIENT, *gd);
obj->SetParameter(dscID, d, DESCFLAGS_SET_0);	      	         //here cinema hangs!
EventAdd();

On 09/12/2016 at 14:45, xxxxxxxx wrote:

Since we are heading into the weekend and the support guys will be gone for a couple of days.
I'll post my solution for you.

//This code changes the color of the knots in a UserData based gradient gizmo  
  
Bool MyPlugin::Execute(BaseDocument *doc)  
{  
  BaseObject *obj = doc->GetActiveObject();  
  if (!obj) return false;  
  
  //Get the object's master UD container that holds all the UserData entries  
  DynamicDescription *dd = obj->GetDynamicDescription();  
  if (!dd) return FALSE;  
  
  //Get the gradient gizmo from the UD manager  
  GeData d;  
  Int32 gizmoID = 1;  //The ID# assigned to the UD entry in the UD manager  
  DescID udEntry(DescLevel(ID_USERDATA, DTYPE_SUBCONTAINER, 0), DescLevel(gizmoID));  
  obj->GetParameter(udEntry, d, DESCFLAGS_GET_0);  
  
  //For safety reasons we should check that the gizmo is a gradient type gizmo  
  if (d.GetType() != CUSTOMDATATYPE_GRADIENT)  
  {  
      GePrint("Wrong Data type");  
      return false;  
  }  
  
  Gradient *gd = (Gradient* )d.GetCustomDataType(CUSTOMDATATYPE_GRADIENT);  
  
  //Get the number of knots  
  Int32 kcnt = gd->GetKnotCount();  
  //GePrint(String::IntToString(kcnt));   
  
  //We need to delete(flush) all of the knots to change them (yes..this is stupid...But that's how it's changed)  
  //So we first need to grab and store the current knots data in a list  
  maxon::BaseArray<GradientKnot> knots;  
  for(int i=0; i<kcnt; i++)  
  {  
      GradientKnot knot = gd->GetKnot(i);  
      Vector col = knot.col;  
      Float32 pos = knot.pos;  
      knots.Append(knot);  
  }  
  
  //Delete the existing knots  
  gd->FlushKnots();  
  
  //Use the stored knot values to re-create them with a different color value  
  for(int i=0; i < knots.GetCount(); i++)  
  {  
      if(i==0) knots[i].col = Vector(1,0,0);  //Set the first knot color to red  
      else knots[i].col = Vector(0, 1, 0);    //Set the rest of the knot's colors the green  
  
      gd->InsertKnot(knots[i]);  
      gd->SetKnot(i, knots[i]);  
  }  
  
  //Update the object to reflect the changes  
  obj->SetParameter(udEntry, d, DESCFLAGS_SET_0);    
   
  EventAdd();  
  
  return true;  
}

-ScottA

On 10/12/2016 at 07:22, xxxxxxxx wrote:

Hi ScottA,

Thanks again for your support.
I did remove "gd->SetKnot(i, knot);", I do not think it is needed and indeed it also works without it.

-Pim