SplineCustomGui problems



  • On 04/08/2013 at 12:31, xxxxxxxx wrote:

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

    ---------
    Please help.
    I have a tag plugin.
    Inside this tag plugin I have a spline GUI. Which is being created from the .res file.
    I can create and edit the spline and it's points in this gizmo just fine. Using any of the sdk functions found in the "SplineData" page in the docs.

    However.
    I cannot figure out how use any of the sdk functions found in "SplineCustomGui" in the docs.
    These are the things I'm trying to use on my gizmo:

    class SplineCustomGui : public BaseCustomGui<CUSTOMGUI_SPLINE>  
    {  
    public:  
      void SetMessageFunctions(SplineControlMessages* pFuncs);  
      SplineData* GetSplineData(void);  
      Bool SetSpline(SplineData* pData);  
      void SetGridLineCountH(LONG l);  
      void SetGridLineCountV(LONG l);  
      LONG GetGridLineCountH() const;  
      LONG GetGridLineCountV() const;  
      void SetLabelText(String* strXMin  =  NULL, String* strXMax  =  NULL, String* strYMin  =  NULL, String* strYMax  =  NULL, String* strX  =  NULL, String* strY  =  NULL);  
      void SetCustomColor(Bool bSet =  FALSE, Vector col  =  Vector(0.0,0.0,0.0));  
      void GetScreenPosition(const Vector& v, LONG& x, LONG& y) const;  
      void GetValue(const LONG x, const LONG y, Vector& v) const;  
      Bool Command(LONG id, const BaseContainer& msg);  
    };
    

    Here is my code where I build my splineGUI:

    Bool SplineTag::Init(GeListNode *node)  
    {  
      BaseTag  *tag  = (BaseTag* )node;  
      BaseContainer *data = tag->GetDataInstance();  
      
      GeData d(CUSTOMDATATYPE_SPLINE, DEFAULTVALUE);                             //Stores the data gotten from SplineData  
      SplineData *spd = (SplineData* )d.GetCustomDataType(CUSTOMDATATYPE_SPLINE); //Creates an instance of the SplineData class  
      if (!spd) return FALSE;  
      
      spd->SetUserCallback(mySplineCallBack, NULL);             //Call to mySplineCallBack() to make it start running  
      
      CustomSplineKnot *knot1;   //The first spline knot  
      CustomSplineKnot *knot2;   //The second spline knot  
      
      spd->MakeLinearSplineLinear(2);  
      spd->SetRange(0.0, 100.0, 1.0, 0.0, 100.0, 1.0);         //Set up the spline's range options  
                                                       //Real xmin, Real xmax, Real xsteps, Real ymin, Real ymax, Real ysteps  
      
      //Set The first spline knot's position to 0,0,0  
      knot1 = spd->GetKnot(0);  
      knot1->vPos = Vector(0, 0, 0);  
      knot1->lFlagsSettings |= FLAG_KNOT_LOCK_X|ADD_KNOT_ADAPT_TANGENTS;  
      knot1->vTangentRight = Vector(5, 50, 0);  
      
      //Set The second spline knot's position to 100,100,0  
      knot2 = spd->GetKnot(1);  
      knot2->vPos = Vector(100, 100, 0);  
      knot2->lFlagsSettings |= FLAG_KNOT_LOCK_X|ADD_KNOT_ADAPT_TANGENTS;  
      knot2->vTangentLeft = Vector(-10, -10, 0);  
      
      data->SetData(MY_SPLINE, d);     //Apply the setting frpm memory to the spline GUI gizmo to update the spline  
      
      
    ////////////////// Up until this point. Everything is working as expected /////////////////////////////////  
      
      
      //Now lets try to access the splineGui itself and change it  
      //This is where things stop working  
      //What am I doing wrong?  
      SplineCustomGui *splGui = (SplineCustomGui* )data->GetCustomDataType(MY_SPLINE, CUSTOMDATATYPE_SPLINE); //NOTE: MY_SPLINE is the ID of my spline gui  
      splGui->SetGridLineCountV(22);            //Change the number of vertical grid lines  
      LONG gv = splGui->GetGridLineCountV();    //Get the number of vertical grid lines  
      GePrint(LongToString(gv));                //<--Always returns zero?!!  
      
      //None of the other SplineCustomGui functions work either  
      //What am I doing wrong?  
      
      
      return TRUE;  
    }
    

    How do we use this SplineCustomGui class?

    -ScottA



  • On 04/08/2013 at 16:31, xxxxxxxx wrote:

    In addition to not being able to change the gui directly with the SplineCustomGui class. I'm also finding all kinds of strange problems with trying change it using the various container options also.

    I've added a splineGUI to:
    -A tag plugin(using .res)
    -An object plugin (using a SubDialog and AddCustomGui())
    -A GeDialog plugin(using AddCustomGui())

    I've done this in both C++ & Python. And only some options are working. While many are not.
    Python Example:
    bc[c4d.SPLINECONTROL_GRID_V] = True           #Works properly. Depending if it's set to True or False
    bc[c4d.SPLINECONTROL_GRIDLINES_V] = 15     #Does not change the number of vertical lines at all
    etc...

    There's tons of these options that don't work. While the other ones work fine. Confused
    This is happening in both the .res implementation & the AddCustomGui() implementation of the splineGUI.

    I can create spline knots and edit them.
    But when it comes to editing the GUI itself. I'm not having much luck changing most of the options.
    Either through the SplineCustomGui class. Or with base container settings.

    -ScottA



  • On 06/08/2013 at 10:11, xxxxxxxx wrote:

    Since I'm not getting any replies. Does this mean that everyone else is also not able to use the SplineCustomGui class either?
    I've learned a few more things. But I still have several questions.

    While I can grab the SplineGUI gizmo using: SplineCustomGui *splGui = (SplineCustomGui* )data->GetCustomDataType(MY_SPLINE, CUSTOMDATATYPE_SPLINE);
    I cannot apply the SplineCustomGui class to it at all. It crashes C4D!!!
    However...I can apply the class to the gizmo if I use it in a dialog using: FindCustomGui(), rather than a tag's AM. Without C4D crashing.
    These are the results I get from the SplineCustomGui class when it's used in a GeDialog plugin:

        //The spline gui gizmo  
      SplineCustomGui *sGui;  
      sGui = (SplineCustomGui* )FindCustomGui(MYSPLINE, CUSTOMDATATYPE_SPLINE);  
      
      //The spline Gui's spline data  
      SplineData *spd = (SplineData* )data.GetCustomDataType(CUSTOMDATATYPE_SPLINE);  
      
      
      
      //Using the SplineCustomGui class  
      sGui->SetLayoutMode(2);                //Works: 0=none, 1=minimized, 2=maximized  
      LONG mode = sGui->GetLayoutMode();     //works  
      sGui->SetGridLineCountH(22);           //Does not work!  
      sGui->SetGridLineCountV(22);           //Does not work!  
      
      String strX = "Xvalues";  
      String strY = "Yvalues";  
      sGui->SetLabelText(NULL,NULL,NULL,NULL,&strX,&strY);  //Works  
      
      LONG w = sGui->GetWidth();             //Always Zero!?  
      LONG h = sGui->GetHeight();            //Always Zero!?  
      
      sGui->SetCustomColor(TRUE, Vector(255,0,0)); //Sets the spline color to red...R14++ only  
      
      sGui->SetData(data);                  //Applies any changes made to the spline  
      
      
      
    //////////////////////////////////////////////////////////////////////////////////////////  
    //These are the results I get from the GetScreenPosition() & GetValue() functions  
      
      Vector gspv = NULL;  
      LONG gspx = NULL;  
      LONG gspy = NULL;  
      sGui->GetScreenPosition(gspv, gspx, gspy);  
      //GePrint(LongToString(gspv.x) + "  "  \+ LongToString(gspv.y));   //prints  0  0       What does that mean?  
      //GePrint(LongToString(gspx));      //Prints 12 no matter what the spline looks like...What does that mean?  
      //GePrint(LongToString(gspy));      //Prints 90 no matter what the spline looks like...What does that mean?  
      
      Vector gvV = NULL;  
      LONG gvX = NULL;  
      LONG gvY = NULL;  
      sGui->GetValue(gvX,gvY,gvV);  
      //GePrint(LongToString(gvV.x) + "  "  \+ LongToString(gvV.y));     //Prints -5  112     What does that mean?  
      //GePrint(LongToString(gvX));     //Prints zero no matter what the spline looks like...What does that mean?  
      //GePrint(LongToString(gvY));     //Prints zero no matter what the spline looks like...What does that mean?
    

    As you can see.
    Some things work. And some things don't.

    Q1
    How do I change the number of Grid lines?

    Q2
    Why are the width & height values always zero?

    Q3
    How do I use the GetScreenPosition() & GetValue() functions properly?
    Do they work together as a team somehow?
    Right now they are giving me jibberish.

    -ScottA



  • On 06/08/2013 at 11:31, xxxxxxxx wrote:

    Hi Scott,

    Originally posted by xxxxxxxx

    While I can grab the SplineGUI gizmo using: SplineCustomGui *splGui = (SplineCustomGui* )data->GetCustomDataType(MY_SPLINE, CUSTOMDATATYPE_SPLINE);
    I cannot apply the SplineCustomGui class to it at all. It crashes C4D!!!

    You cannot access a custom GUI displayed in the AM. You can only cast the returned value to SplineData*.

    Originally posted by xxxxxxxx

    Q1
    How do I change the number of Grid lines?

    Q2
    Why are the width & height values always zero?

    I'll ask the developers.

    Originally posted by xxxxxxxx

    Q3
    How do I use the GetScreenPosition() & GetValue() functions properly?
    Do they work together as a team somehow?
    Right now they are giving me jibberish.

    GetScreenPosition() expects a spline vector with valid coordinates; in your code it's NULL. Then X and Y positions are assigned if the method executed successfully.
    GetValue() expects valid X and Y screen positions; in your code they're NULL. Then the spline vector value at these coordinates is set by the method.



  • On 06/08/2013 at 12:39, xxxxxxxx wrote:

    Thanks for the help Yannick,

    Originally posted by xxxxxxxx

    GetScreenPosition() expects a spline vector with valid coordinates; in your code it's NULL. Then X and Y positions are assigned if the method executed successfully.
    GetValue() expects valid X and Y screen positions; in your code they're NULL. Then the spline vector value at these coordinates is set by the method.

    Sorry for being so thick headed. But I don't see any way to actually get spline vectors?
    It would be wonderful if I could do this. Because what I'm trying to do is get the spline values. But right now I can only get the knots X&Y positions and their X&Y values using the SplineData class.
    Using these values I can then use CalcSpline() or Smoothstep() and get the values between knots.
    But this produces a straight linear value between the knots. Not the values of the actual spline.
     
    What I need is the spline's values. So that I can map them to things like object rotations.
    I'm basically trying to reproduce what the CMotion object does. Without the green line thingy that loops through the GUI.
    I was hoping that I could get the spline's values by using the GetScreenPosition() & GetValue() functions. But I can't figure out how to write them properly.

    -ScottA



  • On 06/08/2013 at 16:14, xxxxxxxx wrote:

    I think I've got  the GetScreenPosition() & GetValue() functions figured out now.
    If I'm understanding them correctly. They are just converters. And the spline plays no part at all in them.
    I had thought that they would only return a value if the spline was at the same place as the coords. But it looks like the spline plays no part at all in these.
    They just convert from screen values to spline values. And vice versa.

    If I'm understanding this correctly.
    You first use GetValue() to grab and convert the screen positions. Then use the vector result from that to convert it back to spline positions if desired.

        //Converts Screen values into spline Values  
      Vector gvV = NULL;                 //The Vector value that will be filled in by the GetValue() function later on  
      LONG gvX = 10;                     //The Screen position X=10  
      LONG gvY = 10;                     //The Screen position Y=10  
      sGui->GetValue(gvX,gvY,gvV);       //Ouputs a vector value which gets inserted into variable gvV  
      //GePrint(LongToString(gvV.x) + "  "  \+ LongToString(gvV.y));     //Prints 0  99          
       
      //Converts spline values into screen position values  
      LONG gspx = NULL;  
      LONG gspy = NULL;  
      sGui->GetScreenPosition(gvV, gspx, gspy);  //Outputs two LONG values for X&Y. And inserts them into variables gspx & gspy  
      GePrint(LongToString(gspx) +"  " +  LongToString(gspy));  //Prints 10 10
    

    So I'm still left with the problem of no way to get the spline's values. Not just it's knot values.
    I don't see how these functions would help. But maybe I'm missing something?

    -ScottA



  • On 07/08/2013 at 00:15, xxxxxxxx wrote:

    Yes, SplineCustomGui::GetScreenPosition() and SplineCustomGui::GetValue() are just converters.

    To get a spline value you have to call SplineData::GetPoint().
    This method evaluates and returns the spline point value at the given X coordinate.



  • On 07/08/2013 at 08:29, xxxxxxxx wrote:

    Howdy,

    Originally posted by xxxxxxxx

    ... Q1
    How do I change the number of Grid lines?...

    That's done in your tag's .res file:

    GROUP
    {
    	COLUMNS 1;
    	
    	SPLINE MY_CURVE // MY_CURVE would be the defined ID in the tag's .h description file
    	{ 
    		SHOWGRID_H; 
    		SHOWGRID_V; 
      
    		GRIDSIZE_H 8; 
    		GRIDSIZE_V 8; 
      
    		HAS_PRESET_BTN; 
      
    		MINSIZE_H 120;
    		MINSIZE_V 80; 
      
    		EDIT_H; 
    		EDIT_V; 
      
    		LABELS_H; 
    		LABELS_V; 
      
    		HAS_ROUND_SLIDER;
      
    		X_MIN 0; 
    		X_MAX 1.00; 
      
    		Y_MIN 0; 
    		Y_MAX 1.00; 
      
    		X_STEPS 0.1; 
    		Y_STEPS 0.1;
    	}	
    }
    

    Take a look at the SDK documentation in:
    **  Index : Parameter descriptions : Description resource : SPLINE (description element)**

    ... for the description parameters you can set. If you want to do it programmatically through your code, you probably need to do that in TagData::GetDDescription()

    EDIT :
    Oooops, sorry I missed one of your posts. 😊

    Adios,
    Cactus Dan



  • On 07/08/2013 at 09:08, xxxxxxxx wrote:

    I tried those Dan. But they don't work for me in R13.
    In a dialog scenario. Only a few of them (SHOWGRID_H; SHOWGRID_V;) do work OK.
    In a tag plugin scenario. It's even worse...Only MINSIZE_H; MINSIZE_H; seem to work.
    It's wacky. 😵

    @Yannick,
    GetPoint() only works when it's used in the InitValues() method of my plugin. And that's not good.
    I need it to update when the user changes the spline.
    If I try to use GetPoint() in the Command() method or the Message() methods. I returns crazy long jibberishy looking values from it....or just plain zero's as the result.

    Do I maybe need to use some sort of callback to poll the spline's points?
    There is: GetUserCallback() & SetUserCallback() in the docs. But I have no idea how to use them.

    -ScottA

    *Edit*
    I just tried using GetPoint() in my Tag plugin version. And it seems to work fine in the Execute() method. And updates properly if the user changes the spline. Which is good, because I really wanted to use a tag for this anyway. Not a GeDialog plugin.
    But I'd still like to know how to poll the splines values in a GeDialog because that might be handy to do.

    I have to say that this is all very, very confusing.
    There's different rules for the Spline GUI when used in a dialog vs. using it in a tag plugin.
    And none of the gui gizmo editing code in either the SplineCustomGui class, or .res file flags, seem to work properly at all.
    I've been bouncing back and fourth between these two types of plugins to try to figure out what which version can & can't do. And it's been very frustrating.
    None of this is documented very well. And I feel like Alice falling down the rabbit hole.


Log in to reply