Spline data and guis [SOLVED]

On 27/02/2015 at 03:31, xxxxxxxx wrote:

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

Hi folks,

previously I had made my own spline gui that worked off the back of an object I could use and access without the need for the gui itself. So, the gui was just a user area that was drawn off the back of the spline object, which could be changed between at the users discretion. In an effort to try and make the interface as much the same as Cinema itself, I'm trying to go back to implementing the SplineData and SplineCustomGui in the way I had made my own spline curve gui.

But I'm a little confused over the sdk spline curve container itself. It looks like just a plain gui element with a container - I can't see how to store a 'curve' object in memory. Is this not possible with the sdk? Or is there another sdk object that could help with this?


On 01/03/2015 at 22:03, xxxxxxxx wrote:

Hi WickedP,

I'd like to help you, but I don't know what you're actually talking about, as you're describing something only you created and understand.  If I generalize your statement "I'm trying to go back to implementing X in the way I had made my own Y", I'd have to know what Y is before I could have any idea how to describe X, no matter what the subjects Y and X would be. 

If you really are just seeking help on the SDK spline curve container, what code are you exactly talking about?  I did a search for 'spline curve container' and didn't find anything specific, so I'd just need a bit more info to get started on helping you out. :slightly_smiling_face:

Joey Gaspe
SDK Support Engineer

On 01/03/2015 at 23:11, xxxxxxxx wrote:

Hi Joey,

I'll leave out my custom object for the moment, otherwise it might just confuse things!

Now, this is what I see in the sdk:
a customgui spline gui, which has it's own container to hold curve/point data.

This is what I'm wanting to do:
I want to hold a curve-spline-object container in memory, that I can use without the gui (i.e. use it in memory), but which can also be sent to a spline gui for drawing and editing.

In other words, I want to hold a "spline-curve" data container. I then want to be able to choose one of the spline data containers to send to the spline gui for drawing and editing.

So, I don't want one spline gui with one container times a thousand. What I want is to hold any number of spline curve containers in memory (a thousand..), which I can use without the gui, but which can also be sent to the gui for user display and editing.

Does that make any more sense?


EDIT: Now hang on a second, I might have found what I'm after..

On 02/03/2015 at 00:34, xxxxxxxx wrote:

Hi Joey,

I've spent almost the entire weekend fumbling about wondering how I should approach this, and I've just gone back into the sdk and have seen that the SplineData has an Alloc() there. I hadn't seen that previously, so I was left wondering how on Earth I could hold a spline container if I couldn't make one myself!

But now I can Alloc a new SplineData container, and then spline_gui->SetSpline() on the gui element to make the spline gui draw the new spline container link.

My apologies Joey, this one's solved!


On 02/03/2015 at 00:44, xxxxxxxx wrote:

Ok, now I've got another issue. I can switch between the spline containers in the gui display, but if I edit one, change, then change back, I've lost the spline I edited. What's the trick here?


On 02/03/2015 at 12:02, xxxxxxxx wrote:

Hi WP,

From the bottom up:

You probably want to call GetSplineData(), but when?  You likely have to receive GUI update messages and process them, but where?  You have to use SetUserCallback() from your SplineData object to register a callback function with the following declaration and it has to process the SPLINE_CALLBACK_DRAW id value, and code it the following way:

static Bool SplineDrawCallback(Int32 id, const void* d)  
  // Potentially process other messages  
  const SplineDataCallbackDraw *pData = (const SplineDataCallbackDraw* )d;  
  SplineData *spline = pData->pGUI->GetSplineData();  
  if (!spline)  
    return false;  
    // Your code here  

Please let me know if that's what you needed!

Joey Gaspe
SDK Support Engineer

On 03/03/2015 at 03:15, xxxxxxxx wrote:

Hi Joey,

I've been using the dialog's Message() function and catching the spline gui's id to get anything that the spline gui does. The messages are caught. I thought of the GetSplineData() as well, and tried it in the message function previously, but that didn't seem to do anything either. I've tried implementing the call back above but haven't got anything working yet. I'm not sure how to call it. I get tripped up here:

"SplineGui *SplGui" ...etc...   
SplineData *MySplineD = ...;   
// I'm not sure what two arguments go in the following line:   
MySplineD->SetUserCallback(..what goes here?..,SplGui->GetData());   

I've seen these callbacks before. I thought I'd used one previously on something else, but can't find it. What is the purpose of them?


On 03/03/2015 at 08:01, xxxxxxxx wrote:

Hi WP,

A simplified definition of a callback function is a function that will be called when certain events need to be processed by customized code adapted to the application, usually from a closed source compiled SDK.  It's a slightly more primitive variation of the message processing methods you state you already implement.  You have to register the callback function, following its variable return and parameter definition, as the code that will call it will assume you followed it exactly.  Here's a more thorough definition from Wikipedia:

Wikipedia link to callback function definition

The way you register the spline drawing callback function in this case is the following.  The first argument is the function name, since that's the way you pass a function pointer in C and C++.  The second has always been nullptr in the few example cases I found.

MySplineD->SetUserCallback(SplineDrawCallback, nullptr);

BTW, if you're not sure about the more general concepts surrounding callbacks, in addition to the Wikipedia article link above, the general C / C++ programming feature being used is called function pointers.

Joey Gaspe
SDK Support Engineer

On 03/03/2015 at 22:59, xxxxxxxx wrote:

This one seems a little odd to me - most likely because I'm not use to the idea of a callback function.

I've managed to get it working the way I need it to, but by using the spline gui's CopyTo() function. I was trying to use the call back, and I did get it 'going', but I couldn't get it to directly edit the splinedata held in memory. It would always revert back to the original splinedata if I changed to another spline, then back again. Because of this behaviour, it looks to me like the spline gui only edits it's own splinedata container? So when the user calls splinegui->SetSpline(MySpline_d), the gui element is actually copying the data from the passed reference, instead of using the reference's direct data container. I find this a little strange - I would have thought it'd be better to just use the passed reference as it's container source, given this is what the user is passing in as an argument?

I'd be interested in seeing a fully functional routine using the callback method if anyone has one at some stage. One where the user can switch between two splinedata objects in memory. I can't see though, how that would solve the missing link because the data the callback gives (tested via GePrint's) seems to come directly from the spline gui object's data, and not the splinedata in memory (even though that's the one using the callback!).

Baring-in-mind I may not have gotten the callback working properly, but I do find this one a little strange. But, then again, maybe I shouldn't be so miffed - it is the coding world after all...


On 11/03/2015 at 09:30, xxxxxxxx wrote:


I'm going to set this topic to solved, but will leave it open for further postings.  Since you got it to work the way you need, I find it redundant to post how to do it with a callback function.

Joey Gaspe
SDK Support Engineer