Loading SDK ExampleDataType into plugins

On 15/08/2013 at 11:04, xxxxxxxx wrote:

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

How do we load the C++ SDK ExampleDataType gizmo into our plugins?
It has multiple gizmos in it. So I don't know what type to assign to it in my plugin's .res file.


CONTAINER myObject  
  NAME myObject;  
  INCLUDE Obase;  
         //Here are some examples of loading custom gizmos that work   
         //SPLINE MY_GUI   {}                            Works  Loads the spline custom gui  
         //REAL MY_GUI     {CUSTOMGUI REALSLIDER;}    Works  Loads the slider custom gui(REAL type)    
         //LONG MY_GUI     { CUSTOMGUI LONGSLIDER; }    Works  Loads the slider custom gui(LONG type)  
         //Trying to load the C++ SDK ExampleDataType gizmo  
         LONG MY_GUI     { CUSTOMGUI CUSTOMDATATYPE_EXAMPLE; }  <//<----- Wrong!!!!  
         LONG MY_GUI     { CUSTOMGUI ExampleDataType; }         <//<----- Wrong!!!!  

How do load this thing?


On 15/08/2013 at 11:14, xxxxxxxx wrote:

shouldn't it be something like that ? after all it is a custom datatype not just a custom gui.
isn't the SDK datatype composed of a string value and other stuff ?

ExampleDataType MYGUI {}

On 15/08/2013 at 11:37, xxxxxxxx wrote:

Yeah. I tried those ones too. But they don't work for me either:
ExampleDataType MYGUI {}

I've tried a lot of various combinations. But I just can't find the magic combination.


#Edit- In case anyone is wondering. I do have MYGUI listed in the .h and .str files.
         So that shouldn't be the problem.

On 15/08/2013 at 11:53, xxxxxxxx wrote:

I just thought of something.

Since this is a gizmo that is being created from scratch. I wonder if I need to maybe use some kind of #include or #define someplace in my plugin's code in order for the plugin to load it?


On 15/08/2013 at 12:08, xxxxxxxx wrote:

i just tried it and it does work.

ExampleDataType MYGUI {}

you have either not installed the SDK or you header file is not defined properly. a str file is only necessary if you use the NAME keyword (e.g. the CONTAINER element or dialog resource elements ). so you might want to define 'not working'. for me the (object) plugin is loading its gui properly, but then the GetDenabling / Message is throwing some errors, as i did just use an older plugin and replaced a string type element, so that those methods do raise type errors, as the element is not anymore of type string.

On 15/08/2013 at 12:33, xxxxxxxx wrote:

Hi Scott,

as the name implies, the "ExampleDataTypeClass" example from the SDK
implements a datatype , not a graphical user interface. Ferdinand
is right, it should be

CONTAINER myObject {
    NAME myObject;
    INCLUDE Obase;
           ExampleDataType MY_GUI { }

See the source code in the SDK:

class ExampleDataTypeClass : public CustomDataTypeClass
	INSTANCEOF(ExampleDataTypeClass, CustomDataTypeClass)
    /* ... */
	virtual const CHAR* GetResourceSym()
		return "ExampleDataType";
    /* ... */

On 15/08/2013 at 12:49, xxxxxxxx wrote:

Like I said....I've already tried that Nik. And it does not work for some reason.

I have a working ObjectData plugin with a couple of gizmos in it that work fine.
Now I'm trying to add the C++ SDK ExampleDataType gizmo to it.
Using this in the .res file does not work: ExampleDataType MY_GUI { }

C4D says it can't read that line in the .res file...Then C4D crashes.


On 15/08/2013 at 12:52, xxxxxxxx wrote:

Do you have the cinema4dsdk compiled and does it load in Cinema? This is the only reason I can think of by now.

On 15/08/2013 at 13:14, xxxxxxxx wrote:

AFAIK. Everything is set up and working just fine.
I've never had any issues with it before.

As an experiment. I tried adding ExampleDataType MY_GUI { } to the Odoublecircle.res file.
Because we all have that same plugin.
It doesn't work there either.
When using the plugin C4D complains that it can't read that line in the .res file.

Are you telling me that you can do this and it works for you?


On 15/08/2013 at 13:52, xxxxxxxx wrote:

Yes, I do.

CONTAINER Ocontainer {
    NAME Ocontainer;
    INCLUDE Obase;
    // ...
    GROUP Obaselist {
            SEPARATOR { LINE; }
            ExampleDataType TESTPARAM { }
#ifndef Ocontainer_H
#define Ocontainer_H
    enum {
        Ocontainer = 1029700,
        // ...
        TESTPARAM = 24234,
#endif // Ocontainer_H

Last chance is that you could have missed to add "MY_GUI" to "res/description/myObject.h".


On 15/08/2013 at 14:19, xxxxxxxx wrote:

The problem must be my computer then.
I'm overdue for a system format anyway.

Thanks guys.

On 15/08/2013 at 14:26, xxxxxxxx wrote:

Could you upload a ZIP file with all your files in it? Plugin binary and resource files should be
enough, no need for the source code.


On 15/08/2013 at 15:28, xxxxxxxx wrote:

I'm using the same files you already have Nik. The double circle example.
It's ok though. After I rebooted my machine it started working.
My machine gets flaky like this when I've installed and un-installed too many things.
I can tell it needs a formatting.

I do have another question for you though. Or a comment really.
I created a custom slider GUI using your tristate example. And it works just fine.
However. When the scene file is saved and re-opened. The gizmo slider is re-set back to zero and not where it was when it was saved.
The C++ ExampleDataType example is written differently than your example. It uses Read(), Write(), CopyTo() to save the data.
I'm guessing that this is why the gizmos saves it's current state.
So I was going to try and use that example to see if I could get my custom slider to save it's settings. And that's how I got into this mess with not being able to load the gizmo in my plugins.

So that's where I am currently with my custom slider.
It works...But it resets itself back to zero when opened from a saved file.
Maxon's  ExampleDataType example does not show how to create a slider gizmo. But it does show Read(), write(), CopyTo().
So I'm trying to use your code...And their code...to figure it out.


On 16/08/2013 at 03:06, xxxxxxxx wrote:

Interesting. Well, at least it works now!

However. When the scene file is saved and re-opened. The gizmo slider is re-set back to zero and not where it was when it was saved.
The C++ ExampleDataType example is written differently than your example. It uses Read(), Write(), CopyTo() to save the data.

The ExampleDataType is not a custom GUI! It is a datatype, just like LONG, String, Real, BaseTime
or whatever. A GUI is what displays the data visually to the user.

This is the internal actual representation of a value of an ExampleDataType value:

class iExampleDataType : public iCustomDataType<ExampleDataType>
	friend class ExampleDataTypeClass;
		LONG		ldata;
		String	sdata;
		Vector  vdata;
			ldata = 0;

It consists of a LONG value, a String value and a Vector value.

Now that you have the datatype, you need something to display it to the user. This is where
custom GUIs come into place! However in this particular example, why should you take the effor
to write your own CustomGuiData plugin if the only thing necessary is to represent the three
values with interfaces that are already there?

_GetDescription() loads a description resource files which describes the three parameters of
the datatype. Since there is no specific custom GUI for the ExampleDataType, Cinema will fall
back on using the interface _GetDescription() creates.


On 16/08/2013 at 08:16, xxxxxxxx wrote:

I'm starting to slowly get the idea how it all works.
Last night I created two more custom data types from notes I've had saved from years ago.

//iCustomGui is the the base class for custom GUIs
class MyCustomGui : public iCustomGui

//CustomGuiData is a class for creating custom GUIs for data types
class MyFloatGui : public CustomGuiData

The reason I'm trying to make my own custom slider is because I want to "style" my own gizmos. Instead of being stuck with the ones that Maxon provides.
If I can get a basic slider working properly. Then I can use that as my base code for making other kinds of gizmos. Like slider wheels, and other interesting looking interfaces. Instead of the boring horizontal sliders.
I could style them to be whatever I want them to look like. And s**ce up my plugins.


-LoL. The forum software does not allow the word(s.p.i.c.e) :joy:

On 17/08/2013 at 10:20, xxxxxxxx wrote:

Sorry to jump in on this one ScottA,

but I simply cannot get the example Niklas has posted to show up in my plugin (whereas the DataType example from the SDK does).

This is what I'm going in circles with in my GetDDescription() :

               cid = DescLevel(ID_TAB_HOME_GROUP_CUSTOMGUI_EXAMPLE, DTYPE_NONE, 0);   
               if(!id_Home || cid.IsPartOf(*id_Home,NULL))   
                    BaseContainer bc = GetCustomDataTypeDefault(ID_MY_CUSTOMGUI);   
                         bc.SetLong(DESC_SCALEH, TRUE);   
                    bc.SetString(DESC_NAME, "The Custom UA Gui");   
                    bc.SetString(DESC_SHORT_NAME, "The Custom UA Gui");   
                    if(!description->SetParameter(cid, bc, DescLevel(ID_TAB_HOME_GROUP_GUI_EXAMPLE))) return TRUE;   

The only difference is I'm not using an external res file.

Is there something different about displaying a CustomGuiData vs CustomDataTypeClass? I'm quite at a loss with this one..

How is the CustomGuiData attached to another plugin's GetDDescription()?


On 17/08/2013 at 12:35, xxxxxxxx wrote:

I had some troubles getting the dynamic loading code to work too.
This is how I'm doing it in my ObjectData plugin:

//This is how to load a custom GUI into a plugin using the GetDDescription() method  
//This lets us add them dynamically with code. Instead of statically from the .res file  
Bool MyObject::GetDDescription(GeListNode* node, Description* description, DESCFLAGS_DESC& flags)  
  if(!description->LoadDescription(node->GetType())) return FALSE;  
  #define CUSTOMGUI_TRISTATE 1030913  //<--Important!! We need to have this here so the compiler can find the Custom GUI   
  DescID triCid = DescLevel(1,DTYPE_LONG,0);           //We will load the tristate GUI into the first description level(much like loading UD entries into levels)  
  BaseContainer bc;  
  bc = GetCustomDataTypeDefault(DTYPE_LONG);  
  if (!description->SetParameter(triCid,bc,DescLevel(ID_OBJECTPROPERTIES))) return FALSE;  
  //Make sure you comment out this flags line of code if you don't use the GetDDescription() method  
  //Or else your resources will not load properly from your .res file  
  return TRUE;  


On 17/08/2013 at 13:10, xxxxxxxx wrote:

Oh... I think that was the way I was initially trying to add the CustomDataTypeClass... I was trying them out the wrong way 'round!

Thanks Scott, all displaying now.