Questions of comprehension about the SDK



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 14/03/2005 at 08:07, xxxxxxxx wrote:

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

    ---------
    Hello together,
     
    this is my first post here, but I think it won't be the last;-)
     
    During the last few days I have been reading through the SDK documentation and I also have done my first steps with the SDK. So far, all my test worked all fine with the help of the examples. But since Im going to do some rather large project I would like to have some better understanding of the overall architecture of the SKD. So here my questions:
     
    1. When you create a plugin you have to derive your class from ???Data (where ??? is the chosen plugin type). But for every of the plugin types there also exists a Plugin??? class. How are these two actually connected? Is it correct to say, that the ???Data classes handle everything what has to do with user interaction (editor interactivity, attribute manager) and that the Plugin??? classes are responsible for storing the data?
     
    2. Another question that arises there: normally for your plugin you have to derive a class from ???Data. But what if you would like to extend let's say for example the PluginSceneHook (I have chosen this one, because I stumbled across the TP_Mastersystem which is derived from PluginSceneHook) and you want your SceneHookData-Plugin to have this new class as the node parameter instead of the more general PluginSceneHook. How would you actually do that?
     
    3. One last but therefore a more concrete question: in the documentation it says about the Init(..)-Function of the NodeData class: "Called when a new instance of the node plugin has been allocated. You can use this function to ..."
    But when are actually new instance of the node plugin created? The reason why I ask this: I have done a little test with the ObjectData-Plugin and I wanted to perfom some action every time the user creates the object from the menu and only then. But it turned out (I placed a GeDebugOut in the init-function) that this is also called when you change any of the base-properties in the AM. Okay, I found out that you can do this by using the Message-function and checking for MSG_MENUPREPARE. But Im still wondering, why is there a new instance created with every base-attribute change?
     
     
     
    Thanks in advance,
    Dani



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 14/03/2005 at 10:55, xxxxxxxx wrote:

    1. The PluginXX class is the 'control' structure created by Cinema4D (or your plugin if you create the plugin using something like PluginObject::Alloc()). It contains the glue to make it a part of the Cinema4D interface. The XXData is your 'data' structure with some SDK controls. They are not connected very much at least from a programmer's perspective. The standard methods in the XXData all Get() the GeListNode which is a generic pointer to the PluginXX instance. The PluginXX has no direct access to the XXData, but there are ways to get it if needed.

    2. As far as I know, it is not possible to extend any of the existing Cinema 4D objects (Object, Material, Shader, etc.). Don't know about SceneHook in this instance. All plugins must be derived from a XXData class and multiple-inheritance in not supported (again, as far as I know).

    3. An instance is created either by you programmatically (see above), by the user, or indirectly by the user loading a document containing the plugin object. The SDK is a little incorrect or vague on this. I've seen Init() called many times on a single instance, so be careful about allocations done within it.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 15/03/2005 at 03:34, xxxxxxxx wrote:

    Robert, thanks for your answer. I think it makes things clearer now. So, just only a few comments
     
    1. Ok
     
    2. I would say from the programming point of view it should be possible to extend the existing objects, since they exist in the SDK as normal C++ - classes. The problem just would be how to get your new class into the standard methods of the XXData.
     
    3. I have been "investigating" this a bit further and it seems that Init() is always called after the object has been created. So, actually with every call of Init() you get a new instance. How I found this out: I simple placed GeDebugOut()-calls into the default constructor, Init(), and so.
    Well, this behavior still seems a bit weird to me. Why isn't it enough that the Object is created once the plugin is called from the menu (in the case of a tag or object-plugin)?



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 15/03/2005 at 09:10, xxxxxxxx wrote:

    2. Don't be fooled by the SDK! ;) The classes on display for 'built-in' objects are just there for programmatic access to certain features and controls of these objects. There are data members which are private and hidden as well as Cinema4D facilities which act upon them beyond a plugin classes reach. For instance, objects like Mmaterial and Opolygon are not plugin extensions of BaseMaterial and BaseObject, but fully supported objects within the interface. This support is not made available to a plugin object. But, if you find a clever way around this, we'd all be listening! :)

    3. Well, yes, Init() is always called when the object is created, but whether multiple Init()s are instantiating multiple same (as in indistinguishable copies replaceing one another) objects is the question. Init() in itself doesn't instantiate. That is done by the constructor. But, as I said, if you are instantiating anything within the Init() method (and not checking for previous instantiation), you will get multiples (and possibly memory leaks to boot).



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 16/03/2005 at 10:54, xxxxxxxx wrote:

    2. Okay, I didn't take that into account;-) So, to rephrase it: it's possible to extend the SDK-classes of C4D-objects, but this extension will only be visible within the plugin itself.
    And yes, if I find something I will surely write it here;-)
     
    3. Hmm, but that faces me with a slight problem concerning my project. There I have several own Tags and an Object. And after creation from the menu they should register with a manager which is implemented as a SceneHook. But when I now store there in the manager the pointer to the TagData / ObjectData plugin-instances would it mean that after an Init()-call, the stored pointers reference to wrong instance, since the objects have been instantiated again.
     
     
     
    Dani



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 16/03/2005 at 12:33, xxxxxxxx wrote:

    2. Yes, to some extent. And what that means is that the functionality that makes the C4D object work is inaccessible by both your derived object and C4D. It is even possible that implementing certain virtual methods in your plugin will override those used by and necessary for the C4D object. You can get the 'pretty' GUI by including the .res for the base type in your .res file, but it will be dangerously nonfunctional.

    3. Nope. Init() only initializes the data members of the XXData class.

    From the start here, you first declared and defined a global RegisterXXPlugin() method which was called from your PluginStart(). This registers the new plugin type for use. This just tells Cinema4D how to make instances of your plugin (note that you explicitly tell it the Alloc() method).

    Then a user selects your plugin object type to be added to a Document. The first thing that happens is that your plugin's Alloc() method is called which invokes the constructor (whether explicit to your XXData or implicit from what it is derived - BaseData). Cinema4D allocates and constructs the 'wrapper' PluginXX automatically which represents the plugin object.

    Now, Init() is called for the XXData to initialize data members. As we have noted, this is done several times at first and may be called again later. You still have the same XXData instance in memory. You pass this to your SceneHook for registration. If the XXData is registering itself with the SceneHook, you are literally passing 'this' as the instance. If you are passing 'this' from XXData.Init(), it will still be the same 'this'.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 23/03/2005 at 06:08, xxxxxxxx wrote:

    While still waiting for someone (Mikael?) to answer my own questions from monday, like others, here is something i found out about your Init() question:
    The undo-chain is realized by creating new instances of your object. This means a copy of your object is created via alloc() and then the init() function for the new instance is called. The new instance will hold the undo-information, meaning your original instance is now changed. this happens with every change of data of your object.
    greetings
    Peter



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 23/03/2005 at 09:53, xxxxxxxx wrote:

    This makes sense and would explain the Init()-CopyTo() calls made beyond the initial instantiation. But it does not explain four successive Init()-CopyTo() calls on an instantiation.

    For instance, you call:

      
    myPtr = (MyPlugin* )gNew PluginXX::Alloc(type);  
    

    or create an instance of your plugin object in a usual way and you get the following sequence of calls:

      
    Init()  
    Init()  
    CopyTo()  
    Init()  
    CopyTo()  
    Init()  
    CopyTo()  
    Init()  
    CopyTo()  
    

    This is pulled right off of the Console Window for the addition of one of my shaders to a Material.

    There are three instantiations that are unexplained. Mostly anyway. My guess is document caching is causing these extra calls.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 23/03/2005 at 11:00, xxxxxxxx wrote:

    Quote: Originally posted by kuroyume0161 on 23  March 2005
    >
    > * * *
    >
    > This makes sense and would explain the Init()-CopyTo() calls made beyond the initial instantiation. But it does not explain four successive Init()-CopyTo() calls on an instantiation.
    >
    > For instance, you call:
    >
    >

      
    \> myPtr = (MyPlugin* )gNew PluginXX::Alloc(type);  
    \> 
    

    >
    > OOps. this looks to me like doing the job of allocation twice because Alloc() creates a new instance and gNew does the same, so its not a surprise to me you get more than one inits().
    >
    > Try leaving the gNew and look whats happening. At least my own source works well this way.
    >
    > greetings
    >
    >



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 23/03/2005 at 11:45, xxxxxxxx wrote:

    Nope, that gNew doesn't belong there. :) I started typing on a class but went for a plugin alloc(). That doesn't change the results in the Console Window.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 23/03/2005 at 12:28, xxxxxxxx wrote:

    Hello Peter,
     
    thanks for your answer.
    Unfortenately, I don't have one for your question, Im just too new to the SDK;-)
     
    This undo-thing makes it definitely clear now, why the inits get called all the time when you change an attribute of your object. Well, it doesn't make programming easier, when you have to handle all these undo-inits().
     
    Dani



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 23/03/2005 at 12:40, xxxxxxxx wrote:

    You don't have to handle them. Just make sure that the Init() method initializes and Free() frees any allocated objects not added to a document. The undos and caches are automatic when done with user interaction. Otherwise, the facilities for creating undos and caches exist in the SDK (BaseDocument.StartUndo/AddUndo/EndUndo/Undo/Redo, etc.).

    You'll note that, as I had forgotten, whenever you render, a copy of the document is made for the rendering process. So, Cinema4D does alot of copying which always involves calls to Init().


Log in to reply