Starting C++ SDK Tutorial
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 15/01/2003 at 05:38, xxxxxxxx wrote:
ok, it seems to be that no one is really interested to take part developing a good tutorial. Nevertheless I'll try to start the tutorial with this thread and hope you all help me, when I get stuck. Here is a small description what and how it has to be done (IMHO)
PluginIdea
Scale-Tool
Goal:
- scales objects of a group but keeps the position of each object
- scales position of objects but keeps the object's size
1. Step
- Prepair C++ SDK and api
- Get PluginID
- Start with a clean Project
- Compile and rund a "Hello World" Plugin
2. Step
- Print current object info (name, id, type)
- Print current object's hierachie
- Print current object's and hierachie plus all global possitions
- Print all selected object's name + name of all select objects hierachie
3. Step
- create AM dialog with X,Y,Z Tag (selectable), a Slider and some checkboxes
X
Y !-----------------------------------! [1 <>]
Z
[] Use Hierachie
exclude:
() Position
() Size4. Step
- scale current object based on the slider
- scale only selected axis
- scale all selected objects + hierachie depending on "use hierachie"
- scale position keep size
- keep position scale size
Further Development:
- easy scale input one size calculates the others
- moving one object of a group, point, poligon or edge let the others follow in a chooseable relation
Any comments?
Sneaker -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 15/01/2003 at 12:49, xxxxxxxx wrote:
ill help you as best i can , just email me and ill spill the beans
PAul -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 18/01/2003 at 13:15, xxxxxxxx wrote:
Thanks Paul, with your help verery thing is possible!
As I wrote before, I'm not an experienced C++ programmer. That's why I want to start with very basic things. Actually I'm not able to write a Plugin, but I will be and document the steps here. I cannot teach anybody how to write code, but hopefully I'm able to put some stones (rocks) out of the way.
I'm usually using VisualStudio.net and the SDK works with it, but here I'll use VS6 only.
ok let's start with Lesson 1A) Prepair C++ SDK and api
-------------------------------------
There are currently wrong packed files on the windows version of Cinema 8.001 and 8.012.
These files must be corrected before start writing a C++ Plugin.
Here is a comment from Philip Losch:
"Due to a distribution error in V8.000 - V8.012 the line endings of nearly *all* text files (*.cpp *.h *.res *.str) got screwed up. It's probably best to do a search for all those files and use a text editor capable of batchprocessing that'll correct the line endings."
yamato found out:
"the problem is, that all cpp and h files from the c4d api have line endings with "0x0d" only, and not "0x0d 0x0a" as usual."
ok, a programmer should be able to write a program in his favorit programming language to correct the files. yamato offers a program, I can offer a Perl script to do this. (Tipp: "0x0d 0x0a" == "\n" in Perl and maybe in C, too)
more info:
https://developers.maxon.net/forum/topic/929
https://developers.maxon.net/forum/topic/941-------------------------------------
Next download the SDK from Plugincafe <[URL-REMOVED]> and maybe download the helpfiles, too <[URL-REMOVED]> (right click + save)
After that it's a good practice to make a backup of your current pluginfolder (..\Maxon\CINEMA_4D_R8\Plugins), and empty it. Unzip the SDK into the plugin folder. Now there should be only the cinema4dsdk, which pervent you from getting in trouble with other plugins.- Now!
Open ..\Maxon\CINEMA_4D_R8\Plugins\cinema4dsdk.dsw with DeveloperStudio - Add ..\Maxon\CINEMA_4D_R8\Resource\_api_lib\_api_v8.dsp to your Project "Menu/Project/Insert Project to Workspace" or just drag it into MSDEV
- Set dependency to: cinema4dsdk depends on _api_v8 "Menu/Project/Dependencies"
- Set active project to cinema4dsdk-Win32Release "Menu\Build\Set Active Configuration"
Everything is now ready for a first compilation and linking. Hit "Menu\Build\Rebuild All"
If there are errors check the above steps, else open Cinema and see if your new compiled sdk works.
-------------------------------------
Any comments?
Sneaker
[URL-REMOVED] @maxon: This section contained a non-resolving link which has been removed.
- Now!
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 22/01/2003 at 13:22, xxxxxxxx wrote:
ok, sorry I wanted to post this in a daily order, but I'm too busy at the moment.
Today there's just a short explanation about Plugin IDs.
"Plugin IDs 1000001-1000010 are reserved for development. You may use these freely to test scripts, but must request an ID in order to release them. "
Every plugin loaded from Cinema needs a unique ID that it can be referenced. If you try to load 2 plugins with the same ID Cinema refuses to load the 2. plugin. For your own plugin you need to get a unique plugin ID.more here:
[URL-REMOVED]
[URL-REMOVED]Sneaker
[URL-REMOVED] @maxon: This section contained a non-resolving link which has been removed.
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 24/01/2003 at 06:24, xxxxxxxx wrote:
Hi Sneaker,
I did a BCC tutorial some time ago but had to stop working on it because of compatibility issues in R8. Well, I would like to participate, but haven't done much at last. Do you plan to set up a web page for this?
There are some topics I would add: SDK-Setup for a stand-alone library and some facts to the internal calling mechanisms.
Ciao,
Marcus -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 24/01/2003 at 13:30, xxxxxxxx wrote:
Yes, of course, a web page will follow after the tutorial is done here in plugincafe. There are too many things I don't know right now and hope that someone helps me when i got stuck.
You're very welcome.
What do you mean with "SDK-Setup for a stand-alone library "?
greetings
Sneaker -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 24/01/2003 at 14:15, xxxxxxxx wrote:
Hi Sneaker.
With "SDK-setup for a stand-alone library" I mean that I copy all API files from ...\Resources\... to my specific (from Cinema isolated) project-directory and build the static library in this place. There are some reasons for that:
- If you update your Cinema it might change the API. If you're just in a project, compatibility issues might arise.
- The former SDK was an own package not integrated into the Cinema directory structure. Because I'm a friend of modular solutions, I prefer the old way to the integrated package.
- Then there was a practical reason: I had to correct the line endings of the source files but I didn't want to replace the original ones. So I had to move them to a new place anyway.BTW: For the last point I've written a tool that converts between UNIX and DOS style line-endings and corrects that way the SDK-line-endings. It is also able to convert the tabulators to spaces (not everybody uses the same tab-sizes...).
For the tutorial I think a modular approach should be used, because this way you can add the topics as your time allows. There will be always something to explain...
The first plugin should be a simpel "Hello world." Then there should be some dialog tests just to get the feet wet. I've written a spline-align COFFEE expression I would like to port to the C++-SDK. And I usually write my tutorials in HTML. I've some Arcor web space where I can set up a simple page if you like.
Ciao,
Marcus -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 25/01/2003 at 12:27, xxxxxxxx wrote:
that all sounds really good, and when you look at the 2. reply of that thread, you'll see a "Hello World" is planned.
Web space is no problem, but I want to finish the tutorial and then use this to make it. And of course translate it to German.
greets,
Sneaker -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 28/01/2003 at 16:00, xxxxxxxx wrote:
this is sounds very interesting and useful... keep it up, and post everything on a website somewhere when you've got those tutorials done. i'm sure i'm not the only one who's been befudled by the sdk and could do with all the help and guidance they can get.
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 29/01/2003 at 14:59, xxxxxxxx wrote:
hi I'm back.
here comes the next part: A clean Project.
Before I start I have to thank Marcus Spranger for his great support.
He's really pushing me forward. Actually he's doing the tutorial and I try to
understand and then post it here :o))).
Marcus did a superb easy to use template for Visual C++ V7.
I tried to do the same for V6, but I think V6 isn't as flexible as V7.
(Please help if someone knows a better way)
first here are the files:
V7: http://www.sneaker3.de/Tutorials/Cpp-SDK/empty.vcproj
V6: http://www.sneaker3.de/Tutorials/Cpp-SDK/empty.dsp
Installation:
It's a good idea to make a second installation of Cinema, where you develop your plugins. (You don't collide with other plugins and if a Cinema update is available, you don't have to worry about api changes.)
Now create a folder under plugins (MyPlugins), where you develop your plugins. Here is a good place to have the template.
No! don't open it with VC for now. The template ist made for a deeper folder level.
Let's make a folder in MyPlugins called Hello. This should look like this so far:
CINEMA_4D_R8
-Plugins
--MyPlugins
---HelloCopy empty.* into "Hello"
Rename empty.* to Hello.*
For V7 everything necessary is done - cool huh!
V6 needs some additional changes:
open Hello.dsp with Notepad, replace all "empty" with "Hello" and save it. Close Notepad.
Now we're ready to open the files with VC. VC6 complains to create and open a Workspace instead, that's ok.
Check the active configuration and set it to Hello - Release.
Create a File Hello.cpp and add the following code (from Marcus) :#include "c4d.h" /** * This function is called by the API initialization mechanism * when Cinema4D loads the plugin. */ Bool PluginStart() { GePrint ("Hello World :))))))"); return TRUE; } /** * This function is called by Cinema4D-API when it unloads the plugin. */ void PluginEnd(void) { } /** * This function is used for low-level message passing. */ Bool PluginMessage(LONG id, void *data) { switch (id) { case C4DMSG_PRIORITY: GePrint ("C4DMSG_PRIORITY has been sent"); break; case C4DMSG_OS: GePrint ("C4DMSG_OS has been sent"); break; case C4DPL_STARTACTIVITY: GePrint ("C4DPL_STARTACTIVITY has been sent"); break; case C4DPL_ENDACTIVITY: GePrint ("C4DPL_ENDACTIVITY has been sent"); break; default: GePrint (LongToString (id) + " has been sent"); } return FALSE; }
Build Hello.cdl. It should work directly. If not, please check everything what have been discussed before (api, dependencies, actice configuration etc..)
The template is made for a precompiled api/lib.
Else open Cinema and have a look at the Console (Menu/Window/Console) - surprise it worked without a PluginId.
Homework: Read the code and understand what's going on :o). The SDK files may help. I'll do the same.Marcus thank you very much.
Sneaker
PS: here is Hello.zip:
http://www.sneaker3.de/Tutorials/Cpp-SDK/Hello.zipPPS: If someone knows a better way for the V6 template please help
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 30/01/2003 at 01:56, xxxxxxxx wrote:
Hi folks.
What we did to create the templates: We simply took the project file of the SDK-examples, removed all file entries and adapted the directory/file options. In VC7 you can use macros for this, so you don't have to touch these options anymore. It would be great if there is a Mac user who could do the same for the Macintosh-SDK.
By the way: An explanation of the initialization mechanism will follow soon - it has just to be translated. A second more elaborated Hello-World (using a message box and string resources) will follow too. And yes we've got a first example plugin with some usability in the pipeline. Into this we will also look in detail.
Happy hacking. Ciao,
Marcus -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 05/02/2003 at 16:48, xxxxxxxx wrote:
Hi,
I've written up a tutorial describing how to go about isolating a single plugin from the SDK, so that you can use it as a base framework for building your own plugins. This also includes some explanation of what various the files are for in a plugin.I was originally going to post it here, but then it got long, so I've put it on my website instead.
Goto www.astrofish.com and pick option 4 (Tutorial).
Anyway, hope it's useful to someone.
Any Mac users who look at it - I'd appreciate it if you'd let me know whether my pre-built 'xdl' file actually works on a Mac, since it was built on a PC...
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 06/02/2003 at 14:45, xxxxxxxx wrote:
Hi Steve,
thanks a lot for your efforts. Your tutorial is great for people looking for a fast entry into SDK programming.
Thumbs up. Ciao,
MarcusPS: I have done some work on describing the API structure, but due to time constraints don't make much progress. At the weekend I hope to find some time for the tutorials.
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 06/02/2003 at 23:55, xxxxxxxx wrote:
Hi Marcus,
it's incredible, but you just post the nearly same I wanted to post today.
I'm really busy at the moment and hope to find more time on Sunday to go on with the tutorial.
Steve, it's good to have more ways to get to similar results, and I'm still learning.
cu
Sneaker -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 10/02/2003 at 02:01, xxxxxxxx wrote:
ok, here is the way to our first real plugin.
Marcus, thanks again to provide me with the code and additional information.
There is one thing I didn't change, but I think it's better to change it in future.
You stored the PluginID in c4d_symbols.h. This file must be distributed to the end user
and therefore every end-user can change it. This might help during development, but I don't
think that anybody should be able to change a unique PluginID given to the author.so, the first thing we need is a plan what we're going to do.
It's an easy plugin so we don't need a big plan:
Plugin to send a Hello World message box and write some info into console
here are the steps to do this:
- create a subfolder Hello2 under "MyPlugins"
- copy our empty project to Hello2 and rename it like describe above
- create necessary subfolders in project and file system
- res
- strings_de
- strings_us
- ..... (whatever strings_lang you want)
- src
good.
now we need some files.create a new file in "res" folder called "c4d_symbols.h" and fill in this code:
enum { IDS_PLUGIN_NAME = 0, IDS_PLUGIN_DESCR, IDS_MESSAGE, IDS_ERR_CONSTR, PLUGIN_ID = 1009173 };
create a new file in "strings_us" folder called "c4d_strings.str" and fill in this code
STRINGTABLE { IDS_PLUGIN_NAME "Hello World Advanced ;)"; IDS_PLUGIN_DESCR "Prints out a Hello World message"; IDS_MESSAGE "Hello World!"; IDS_ERR_CONSTR "Construction of HelloWorld object failed"; }
if you like to you can create additional files in the language folders. example for "strings_de":
create a file called "c4d_strings.str" and fill in:STRINGTABLE { IDS_PLUGIN_NAME "Hallo Welt Erweitert ;)"; IDS_PLUGIN_DESCR "Gibt eine 'Hallo Welt'-Nachricht aus"; IDS_MESSAGE "Hallo Welt!"; IDS_ERR_CONSTR "Es konnte kein HelloWorld-Objekt erzeugt werden"; }
and now the very important plugin code itself. Create a new file in "src" folder called "Hello2.cpp"
and fill in:#include "c4d.h" #include "c4d_symbols.h" /** * */ class HelloWorld : public CommandData { public: virtual Bool Execute(BaseDocument* doc); }; /// Bool HelloWorld::Execute (BaseDocument* doc) { String wind0 = "Windows"; GeOutString (GeLoadString (IDS_MESSAGE), GEMB_OKCANCEL); GePrint ("Hello World Advanced :))))))"); if (GeGetCurrentOS() == GE_WIN){ GePrint ("Hello World "+wind0); } else { GePrint ("Hello World Mac :))))))"); } return (TRUE); } /** * */ Bool PluginStart () { HelloWorld *helloWorld = NULL; // initialize global resource object if (!resource.Init()) return FALSE; // create new instance of HelloWorld class, if not done already if ((helloWorld = new HelloWorld) == NULL) { GePrint (GeLoadString (IDS_PLUGIN_NAME) + ": " + GeLoadString (IDS_ERR_CONSTR)); return (FALSE); } // register hook and return return (RegisterCommandPlugin (PLUGIN_ID, GeLoadString (IDS_PLUGIN_NAME), 0, GeLoadString (IDS_PLUGIN_DESCR), helloWorld)); } /** * */ void PluginEnd () { } /** * */ Bool PluginMessage(LONG id, void* data) { return (FALSE); }
----------------------------
compile it and if error free start cinema. Open Menu/Plugins/Hello World Advanced (or similar depending on your language settings).
A dialog box appears with our "Hello World" message. Open the console window and see the additional info.
The next time we'll try to describe some background information how plugins work. Marcus supplied me with some html pages I'd like to publish.
No this time no download! Do your homework ;o).
good luck,
Sneaker -
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 10/02/2003 at 02:17, xxxxxxxx wrote:
Well done! Just one comment though...
> Quote: There is one thing I didn't change, but I think it's better to change it in future.
>
> * * *
>
> You stored the PluginID in c4d_symbols.h. This file must be distributed to the end user
> and therefore every end-user can change it. This might help during development, but I don't
> think that anybody should be able to change a unique PluginID given to the author.
>
> * * *I would DEFINATELY change this. If the PluginID is unique already, which it should be, then there is no reason why the end user should need to change it.
The fact that they _can_ change it means that some people will put in arbitrary values, and sooner or later it will conflict with someone else's plugin number.
With more complex plugins that store information in the document, the result of two different plugins sharing an ID number could be severe corruption of scene files, as one plugin modifies data that it thinks is its own, but actually belongs to another plugin.
I don't see any reason to have it in the symbols file, even during development.
I don't mean to sound critical, but this is a very important issue. If end users start changing plugin ID numbers (e.g. 'just to see what it does'), then you can wave goodbye to the stability that we enjoy at the moment.
Always use unique ID numbers assigned by PluginCafe, and NEVER let the end user change them - they don't need to, and it's dangerous!
Cheers - Steve
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 10/02/2003 at 06:15, xxxxxxxx wrote:
Hi Steve and Sneaker,
yep you both are right. I did this to make the ID easy modifyable for me. But you're right the data issue is very serious - I didn't think about it. I will change it.
Thanks for the comments. As you see, some comments are missing ... the documentation will follow. I swear! The weekend I was installing LINUX and still am, so please be patient
Ciao,
Marcus -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 10/02/2003 at 08:08, xxxxxxxx wrote:
With more complex plugins that store information in the document, the result of two different plugins sharing an ID number could be severe corruption of scene files, as one plugin modifies data that it thinks is its own, but actually belongs to another plugin.
---------------------------------
That is actually not possible IMO. Any other plugin with a different ID has access to "public" values created by another plugin. And private data can´t be changed (if not specificaly arranged) by any plugin anyway. Changing data isn´t really linked to PluginIDs. The main reason is to prevent collisions between the registration and for dialog IDs. So if you create a key with your plugin, any other plugin can find this key in the timeline and change the data if possible to change it.
Best
Samir -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 10/02/2003 at 09:23, xxxxxxxx wrote:
Hi,
I'm referring to private plugin data stored within the document.PluginID values can be used to uniquely identify a subcontainer stored within an object's base container, in which the plugin can safely store arbitrary information for its own purposes.
My understanding is that this is the recommended method for storing such private information.
If another plugin uses the same ID value then both plugins would have access to the same subcontainer, but both would believe that it belonged to them only - as a result they could interact with each other in unpredictable ways.
In this way, different plugins _can_ mess up each others private data.
Cheers - Steve
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 10/02/2003 at 09:33, xxxxxxxx wrote:
I'm referring to private plugin data stored within the document.
PluginID values can be used to uniquely identify a subcontainer stored within an object's base container, in which the plugin can safely store arbitrary information for its own purposes.
--------------------------------------------
1. Could you explain that "subcontainer" method a bit more detailed? I didn´t know this is a prefered method for using "private" data... two or three lines of code explaining what you mean would be appreciated.
2. private data can´t be accessed by other plugins for it is declared as "private". Maybe you are talking something else?
--------------------------------------------My understanding is that this is the recommended method for storing such private information.
--------------------------------------------
I don´t think so. I have a thousand times the same IDs for basecontainer values in my plugins and none of them did ever collide. So I don´t get the point here really. Maybe someone from the dev support could help us find out what´s going on with stored data in basecontainers... But I can´t imagine it is possible.
---------------------------------------------If another plugin uses the same ID value then both plugins would have access to the same subcontainer, but both would believe that it belonged to them only - as a result they could interact with each other in unpredictable ways.
----------------------------------------------
Sorry, I don´t believe that. Then it would be easily possible to exchange data thru a subcontainer but afaik that´s not possible but only over the PluginMessage Port....?!
Best
Samir