Basic Objects



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

    On 06/05/2008 at 03:16, xxxxxxxx wrote:

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

    ---------
    Hey folks,

    I recently started developing a plug-in in C++. After seeing through sample code and grubbing in the documentation I have still difficulties to understand, what steps are needed to create an object (i.g. a polygonal sphere). At least I am sure of beeing in need of this, the class definition and an initialization:

    class GenerateObject : public ObjectData
    {
    public:
         virtual Bool Init(GeListNode *node);
         virtual BaseObject* GetVirtualObjects(PluginObject *op, hierarchyHelp *hh);
         virtual Bool Message(GeListNode *node, LONG type, void *t_data);

    static NodeData *Alloc(void) { return gNew PolygonObject; }
    }

    Bool GenerateObject::Init(GeListNode *node)
    {
         BaseObject *op= (BaseObject* ) node;
         BaseContainer *data = op->GetDataInstance();
         return TRUE;
    }

    Is this correct? What is the next step to continue?



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

    On 06/05/2008 at 10:18, xxxxxxxx wrote:

    Hi!

    Never coded ObjectData, but you have to register this class.



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

    On 06/05/2008 at 11:04, xxxxxxxx wrote:

    There are a bunch of examples in the plugins:cinema4dsdk:source:object folder. There is really too much to be done to post it all here. You'll need a main.cpp which registers the plugin object and to fill out the ObjectData class methods that you need.

    Don't know what your object will be doing, but is using a PolygonObject with your own tag out of the question? Otherwise, you're going to need to track the vertices, polygons, and UV mapping yourself somehow since you can't extend any of the built-in object types.



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

    On 06/05/2008 at 11:37, xxxxxxxx wrote:

    Thanks for your answers. I was afraid to get advices like "watch the examples". As mentioned above I checked them but I can't get any clue what is needed and what's is not. I just have no idea in which order I have to use BaseObject, PolygonObject, Alloc etc ?!

    The Object should be a triangulated sphere of any size. it mustn't be necessarily changable, it can be fix for the moment.

    The Plug-In is, btw, registered via a simple main.cpp.



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

    On 06/05/2008 at 11:43, xxxxxxxx wrote:

    This is why I asked why you couldn't just add a PolygonObject and do the polygonal sphere setup using a plugin tag? If you go the plugin object route, you will not have any access to PolygonObject support and will need to do it *all* yourself. My philosophy is to use what is already available as much as possible. At least with a PolygonObject, you can procedurally set up the points and polygons of the triangulated sphere and have all of the C4D support already there.



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

    On 06/05/2008 at 12:02, xxxxxxxx wrote:

    You allude to AtomObject ?! There it seems the hardcore-routine is used. Well i really need a polygonal Object and not a tag cause view-dependent LOD refinement has to be done there at a l8er point.



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

    On 06/05/2008 at 12:32, xxxxxxxx wrote:

    Exactly. Return a PolygonObject from GetVirtualObjects(). The Atom example is pretty much the best template to do what you are trying to do. Remember that GetVirtualObjects() is called often - but this might suit your need for LOD.

    No problem using a tag to do work to its object. This would be a better approach to setup a one time built-in object or control it continuously.



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

    On 08/05/2008 at 02:46, xxxxxxxx wrote:

    After a little bit of coding and C&P; of Code from AtomObject.cpp i managed to a) create a polygon object with n vertex and m faces, but the faces aren't visible somehow.
    b) create a single sphere primitive, but its subdivision or lod values are not changing the objects appearance.

    At first: What is the difference between *BuildPolgonHull(...) creating primitives and *BuildIsoHull(...) creating a LineObject.

    Second: How can I transform an object from parametrical into polygonal? With toPoly() ?



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

    On 08/05/2008 at 10:14, xxxxxxxx wrote:

    Hopefully, you've set up the vertices values (for a sphere) and set up the polygon indices (a,b,c,d) to point to the proper vertices by index in the Vector array. You should call obj->Message(MSG_UPDATE) after doing this setup.

    The sphere primitive subdivision or lod only apply to the sphere primitive object. There can be no effect on the polygon object without direct intervention (you, that is).

    BuildPolyHull() and BuildIsoHull() are what the Atom object in the examples is using to build the objects to represent the atom. These are probably a bit more complex than your needs since you are only interested in building a single object. I wouldn't worry about the BuildIsoHull() at all.

    ToPoly() only changes the pointer type. To make an object polygonal (when possible) you need to use SendModelingCommand(MCOMMAND_CURENTSTATETOOBJECT). I don't think you should be doing this in a generator object's GetVirtualObject() method, though.

    My thoughts here:

    1. You could just use a tag plugin attached to a regular sphere primitive which sets the sphere primitive segments depending upon some calculation of the distance of the sphere from the current camera. Now you have a sphere with LOD. This is what makes tags so useful - we can't modify or augment existing object types in C4D, but we can do this (to some extent) with plugin tags. In some sense, the same is true of generator and modifier object plugins as well - but their purposes are more explicit.

    2. If you are determined to go the generator object route, it may require that there is a child object (or not - not certain if GetVirtualObjects() is somehow not triggered without a child present). You should either just create a primitive sphere and do the LOD for its segments or just create a polygon object and set it up with the calculated vertices dependent upon the LOD. You can't convert the primitive into a polygon object while in GetVirtualObjects() as best I can tell (see this
    discussion).



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

    On 09/05/2008 at 01:59, xxxxxxxx wrote:

    Thank you for some clearing thoughts.
    Uhm, well I haven't set vertice values or poly indices yet. I just found out that PolygonObject::Alloc(6,5); allocates 6 Points and 5 Faces. I have to look at this in the examples to set up vertice values and poly indices. Thx for this clue ;) I am sure, GetVirtualObjects is triggered without a given child. My result has been 6 Points in the object's center.

    About the tag: I just cannot imagine, that this type would fit my needs. The LOD I wan't to apply if the category CLOD and therefore mustn't be uniform throught the whole mesh, so two basics have to be fulfilled: a poly mesh is built up from scrap using triangle faces (for further refinement/coarsing). Refinement may be possible with mid-edge cutting, coarsing with merging vertexpoints. Perhaps I am running into a dead end with this idea, but in theory it is possible. (A directX C#/.NET prototype of this is already existing)



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

    On 09/05/2008 at 08:44, xxxxxxxx wrote:

    Yep. You'll need to make some initial estimate or use a stock amount of points and polygons on the initial Alloc() but you can update these using VariableChanged (see the SDK docs for more details about using it) while you do your CLOD calculations.

    I see. For something like this, a generator object may be best then. I would create the 'unformed' PolygonObject, set it up initially to the average or lowest subdivision of the sphere for the LOD, and then do the finer CLOD work. All of this can be done in GetVirtualObjects() - or using calls from there like the AtomObject uses with BuildPolyHull().



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

    On 09/05/2008 at 09:09, xxxxxxxx wrote:

    I planned to start from a sphere with a radius x and a segment count of 4 (representing an octa).
    But I have serious problems building up this quite simple object.
    GetVirtualObject() calls the Recurse() function, which calls the BuildPolyHull(). My probs are to extract the necessary items from the Recurse(), resulting in a crash of C4D, since the recurse requires an polygonized input object, etc. :/ Right now I am overwhelmed by the complexity of the atom.cpp.

    But thanks to you for your patience so far ;)



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

    On 13/05/2008 at 08:20, xxxxxxxx wrote:

    I think I figured out how the object is built. However no object is created and inserted into the scene.

    What went wrong ?

    > class GenerateObject : public CommandData \> { \> public: \>      virtual Bool Execute(BaseDocument \*doc, HierarchyHelp \*hierarchyHelper); \> }; \> \> PolygonObject \*CreatePolygonObject(BaseDocument \*doc, HierarchyHelp \*hierarchyHelper) \> { \>      BaseContainer baseContainer; \>      LONG vCnt,pCnt;      \>      const Vector \*vArr=NULL;      \>      const CPolygon \*pArr = NULL; \>      Vector \*vertexArr = NULL; \>      CPolygon \*polyArr = NULL; \> \>       \>      BaseThread \*baseThread=hierarchyHelper->GetThread(); \> \>       \>      baseContainer.SetReal(SPHEREOBJECT_RAD,100.0); \>      baseContainer.SetLong(SPHEREOBJECT_SEG,4); \> \>       \>      PolygonObject \*sphere = (PolygonObject\* )GeneratePrimitive(doc,Osphere,baseContainer,4,FALSE,baseThread); \>      if(!sphere){ \>           blDelete (sphere); \>           return NULL; \>      } \> \>      vCnt = sphere->GetPointCount(); \>      pCnt = sphere->GetPolygonCount(); \>      vArr = sphere->GetPointR(); \>      pArr = sphere->GetPolygonR(); \> \>      AutoAlloc<PolygonObject> polyObject(vCnt,pCnt); \>      if(!polyObject){ \>           return NULL; \>      } \> \>      for(LONG i=0;i<vCnt;i++) \>      { \>           vertexArr[i]= vArr[i]; \>           for(LONG j=0;j<pCnt;j++) \>           { \>                polyArr[j] = CPolygon(pArr[j].a,pArr[j].b,pArr[j].c); \>           } \>      } \> \>      return polyObject; \> } \> \> \> Bool GenerateObject::Execute(BaseDocument \*doc, HierarchyHelp \*hierarchyHelper){ \>      PolygonObject \*returnedPolyObject = CreatePolygonObject(doc, hierarchyHelper); \>      return TRUE; \> } \> #define ID_GENERATEOBJECT 1022395 \> \> Bool RegisterGenerateObject(void) \> { \>      // decide by name if the plugin shall be registered - just for user convenience \>      String name=GeLoadString(IDS_GENERATEOBJECT); if (!name.Content()) return TRUE; \>      return RegisterCommandPlugin(ID_GENERATEOBJECT,name,0,"icon.tif",String("Generate Object"), gNew GenerateObject); \> }



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

    On 13/05/2008 at 11:08, xxxxxxxx wrote:

    You can't just cast the primitive into a PolygonObject. It is a BaseObject and you'll need to make it editable before it can be used as a PolygonObject. In order to do make it editable, you will need to take the sphere primitive and use it with SendModelingCommand(MCOMMAND_MAKEEDITABLE). See this method in the docs for how to set up (similar to the first example there).

    I wouldn't call blDelete(sphere) if it is NULL and instead you should call BaseObject::Free(sphere) when you delete a BaseObject so that all of the instance's resources are released.



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

    On 14/05/2008 at 01:53, xxxxxxxx wrote:

    @Robert: Actually you can cast the result of GeneratePrimitive() to a PolygonObject.

    Here a very simple but complete example of a polygonal sphere generator plugin.

    > \> #include "c4d.h" \> #include "c4d_symbols.h" \> #include "oatom.h" \> \> class AtomObject : public ObjectData \> { \>      public: \>           virtual Bool Init(GeListNode \*node); \>           virtual BaseObject\* GetVirtualObjects(PluginObject \*op, HierarchyHelp \*hh); \> \>           static NodeData \*Alloc(void) { return gNew AtomObject; } \> }; \> \> // initialize settings \> Bool AtomObject::Init(GeListNode \*node) \> { \>      BaseObject \*op = (BaseObject\* )node; \>      BaseContainer \*data = op->GetDataInstance(); \> \>      return TRUE; \> } \> \> // main routine: build virtual atom objects \> BaseObject \*AtomObject::GetVirtualObjects(PluginObject \*op, HierarchyHelp \*hh) \> { \>      BaseContainer bc; \>      PolygonObject \*sphere = NULL; \>      sphere = (PolygonObject\* )GeneratePrimitive(NULL,Osphere,bc,1.0,FALSE,hh->GetThread()); \> \>      if(!sphere) goto Error; \> \>      return sphere; \> \> Error: \>      blDelete(sphere); \>      return NULL; \> } \> \> // be sure to use a unique ID obtained from www.plugincafe.com \> #define ID_ATOMOBJECT 1001153 \> \> Bool RegisterAtomObject(void) \> { \>      // decide by name if the plugin shall be registered - just for user convenience \>      String name=GeLoadString(IDS_ATOM); if (!name.Content()) return TRUE; \>      return RegisterObjectPlugin(ID_ATOMOBJECT,name,OBJECT_GENERATOR,AtomObject::Alloc,"Oatom","atom.tif",0); \> } \>

    cheers,
    Matthias



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

    On 14/05/2008 at 05:19, xxxxxxxx wrote:

    Thanks Matthias for this simple example. This works and creates an "objected" polygon sphere. Objected means, it is a convertable object. Now I have to make this one editable, to access its vertex points and egdes.

    I've tried to make this object editable with MCOMMAND_CURRENTSTATETOOBJECT and MCOMMAND_MAKEEDITABLE but getting either the result NULL or a crash.
    I read it is not recommended using SendModelingCommand within GetVirtualObject since Cache is beeing rebuild by SMC. But I recognized no difference in result using it there or calling another function within GetVirtualObjects (like Bool ConvertObject(PolygonObject *sphere) ).

    > <code>BaseObject *GenerateObject::GetVirtualObjects(PluginObject *op, HierarchyHelp *hh)
    > {
    >      BaseContainer bc;
    >       bc.SetReal(PRIM_SPHERE_RAD,100.0);
    >       bc.SetLong(PRIM_SPHERE_SUB,4);
    >       PolygonObject *sphere = (PolygonObject* )GeneratePrimitive(NULL,Osphere,bc,1.0,FALSE,hh->GetThread());
    > PolygonObject *poly=NULL;
    >
    >       ModelingCommandData mcd;
    >       BaseDocument *doc;
    >       mcd.bc = &bc;
    >       mcd.doc = doc;
    >       mcd.op = sphere;
    >       if(!SendModelingCommand(MCOMMAND_CURRENTSTATETOOBJECT,mcd)) return NULL;
    >
    >       poly=static_cast<PolygonObject*>(mcd.result->GetIndex(0));
    >
    >       if(!poly) goto Error;
    >       return poly;
    >
    > Error:
    >      blDelete(sphere);
    >       blDelete(poly);
    >       GePrint("no Objects");
    >      return NULL;
    > }
    > [/CODE]</code>

    I assume the error is cause of *doc. But doc=GetActiveDocument(); leads to a crash too. Don't know how to obtain the current open document at another way...



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

    On 14/05/2008 at 05:25, xxxxxxxx wrote:

    Well, if you want to have a polygon object you can't use a generator plugin since it always creates generators not polygon objects. In this case you have to use a tag. Maybe you can tell us what you actually want to achieve with your plugin. This would help to find a good solution.

    cheers,
    Matthias



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

    On 14/05/2008 at 07:17, xxxxxxxx wrote:

    In the first step, I want to create a polygonal okta (like a sphere-primitive with 4 segments). The second step is to make this object editable, so I can gain access to its polys and vertex points.

    As mentioned above a CLOD-Algorithm for coarsing/refining a mesh view-dependent has to be applied on this mesh.
    View-dependency is at the moment a secondary goal, primary I want to create a polygonal planet based on a given dataset. Therfor I need the vertex points and their connecting edges (building its triangles).

    For interested people: have look at Cloddy



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

    On 14/05/2008 at 07:36, xxxxxxxx wrote:

    If you are using a command plugin you have of course to insert the polygon object into your scene with InsertObject(). See also this thread how to create and insert objects.

    making a sphere

    cheers,
    Matthias



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

    On 14/05/2008 at 08:52, xxxxxxxx wrote:

    @Matthias: Well, yeah, you can cast it as a PolygonObject* but it doesn't make it a PolygonObject instance. An Osphere doesn't have GetPolygon(), GetPoint(), etc. because it is not a PolygonObject.

    @SnakeByte: If you go the tag route you might have an easier time here. You will be needing to affect a Polygon object to which the tag is attached by changing its vertices and polygons. Actually, the beauty of a tag plugin here is that you don't have to reinvent the wheel with a plugin object that works like a Polygon object - and you could generalize the CLOD to work with any Polygon object (not just spheres) either now or later.


Log in to reply