BaseContainer gone after doc=doc->Poligonize()?



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

    On 09/07/2010 at 09:14, xxxxxxxx wrote:

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

    ---------
    Hi,

    I'm currently writing an exporter to VRML where in addition to the integrated one I also can output additional elements. As an example I used stl.cpp from the SDK.

    I start the exportation with doc = doc->Polygonize(); 
    Then I go recursively through the scene and write out all the elements.
    This worked fine so far as I just had the standard objects.

    But now I have created my own LOD-Object which has relevant information stored in the Object BaseContainer.

    Now, if I want to export this object it seems that the BaseContainer is lost after doc->Polygonize(). 
    As a workaround I created a visible TagPlugin and assigned it to the Object. Then I copied the Objects BaseContainer into the tags BaseContainer. Now I can access the information, from the tag, in my exporter. To make it look nicer I tried to have an invisible tag.  So I registerd the tag without TAG_VISIBLE .
    But now it seems that the tag is gone after I apply doc = doc->Polygonize();

    Does someone know a solution to this? How can I keep the objects BaseContainer or an invisible tag after doc->Poligonize() ?

    Thanks, 
    flo



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

    On 10/07/2010 at 02:28, xxxxxxxx wrote:

    Hi,

    of course the basecontainer is not valid anymore after polygonization. It´s not your object then anymore but a regular c4d object.

    That the tag disappears also sounds reasonable, you need to take care of the tag yourself inside of your object. Simply make a clone of the tag in GetVirtualObjects() and attach it to the polygonobject you return in your LOD object´s GetVirtualObjects() function.

    This should do it.



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

    On 16/07/2010 at 06:24, xxxxxxxx wrote:

    Thank you, I did that and it's working now :)



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

    On 19/07/2010 at 01:55, xxxxxxxx wrote:

    hm, just one more thing.
    It works fine if I add children to my LOD object. But if I don't add children to the  LOD object it still won't be recognized.
    Which makes sense because for this case (is not dirty) I return NULL in GetVirtualObject(). 
    In my understanding I only can use GetAndCheckHierarchyClone() if there are kids and then return this created BaseObject.

    Is there any way to recognize the object without adding children to it, after i apply doc->polygonize() in the scenesaver plugin hook ?



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

    On 19/07/2010 at 01:56, xxxxxxxx wrote:

    return not NULL?



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

    On 19/07/2010 at 01:59, xxxxxxxx wrote:

    I tried to return the object but then I get a Stack overflow.



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

    On 19/07/2010 at 02:19, xxxxxxxx wrote:

    simply return BaseObject::Alloc(Onull);



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

    On 19/07/2010 at 05:01, xxxxxxxx wrote:

    thanks for helping 🙂

    But I'm still stuck. For my LOD object I used the Circle example from the SDK because I thought it's a good way to display the distance between objects and the LOD Object.I adjusted the example to my needs (if I add a child object I get a new field in the attribut manager to enter a distance).

    I haven't had a GetVirtualObjects() method but overwrote it after you suggested it in your previouse post.

    Now, the problem that I face is that if I return BaseObject::Alloc(Onull);  in  GetVirtualObjects() the circle is replaced by a Null object.

    How can I return the circle object?

    I tried to allocate and return a spline object and put all the circles variables in it's BaseContainer, hoping it would automaticly be drawn when returned. But that didn't worked.



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

    On 19/07/2010 at 05:17, xxxxxxxx wrote:

    Ok, first of all you should make clear what the LOD object really does.

    If you have input objects, you should use the AtomArray.cpp example from the SDK.
    The circle object is only a generator on its own (no input objects, and it generates ONLY splines!). If you want to return arbitrary objects (primitives, polygonobjects, splines etc.) you need to overload GetVirtualObjects(). Inside of it, generate any object you want and return it. That´s all you need (screw the other function that returns the spline).

    If you have input objects you also need to specify the according flags in your RegisterObject routine. see the atomarray example as mentioned.



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

    On 20/07/2010 at 11:02, xxxxxxxx wrote:

    I'll try to make clear what I want first:

    I have my LOD-Obect. If a child objects get put under it a new field appears in the atttribute manager, where one can enter the distance from the object to the LOD-Object.

    The,n when I export the scene in my scene saver I want to have the Objects writen out like that:

    LOD {
    \> range[ 300 , 600 ]		//the different distances entered in the attribut manager
    \> level [
    \> > data from childobject 1 {},
    \> > data from childobject 2 {},
    \> > ]
    }
    

    My problem from the beginning was that the distance values which are entered in the atttribut manager and which are stored in subcontainers of the objects BaseContainer are lost after i apply doc->poligonize() in my scene saver.

    That's why I had them copied in a tag, but the tag also dissapered after doc->poylgonize() when it is invisible. It works when the tag is visible.

    I'm still looking for the best way to get the distance values, when I write out the objects in my scene saver after I applied doc->polygonize().

    As a "nice to have" it would be good if I could have optional spheres drawn around my LOD-Object with the radius of the distance values. I managed to do that with the AtomArray example, but I didn't figured out how to only show them in Cinema 4D and don't export them in my scene saver. I recon I have to mark them somehow and I tried so with bc->SetBool(MY_CONSTANT, TRUE) but after doc->Polygonize MY_CONSTANT was gone again.

    I hope that clears up what I want to do. I guess I can use any Object for the LOD - Object if I don't have the additional spheres drawn. If I want the spheres I need to have a generator which takes input objects like the AtomArray.

    I hope thats not all too confusing.I appreciate any help, 
    thanks.



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

    On 20/07/2010 at 11:23, xxxxxxxx wrote:

    the tag isn´t visible to the user anyway is it? so a visible tag should be ok (simply create it in GetVirtualObjects() and set the value in its container).
    For the sphere drawing, why don´t you simply draw 3 circles in different orientations from within the "Draw()" method of your LOD object?



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

    On 21/07/2010 at 02:14, xxxxxxxx wrote:

    thanks for beein patient 😉
    Now I draw my circles in the Draw() method and it works perfect. 🙂

    About the tag, if I don't use the GetVirtualObjects() and use a visible tag it works (I copied the object container to the tag container in Message()).
    How would I use GetVirtualObjects() correctly?

    Here is what I have:

    BaseObject* LODObject::GetVirtualObjects(PluginObject *op, HierarchyHelp *hh)
    {
    \> op->MakeTag(ID_LODOBJECT_TAG);
    \> BaseTag *tag = op->GetFirstTag();  
    \> while (tag)
    \> {
    \> > if( tag->GetType()==ID_LODOBJECT_TAG) 
    \> > {
    \> > > BaseContainer *bc = op->GetDataInstance();
    \>
    \>> > tag->SetData(*bc,1);	//Put the object container into the tag container
    \>
    \>> }
    \> tag = tag->GetNext();
    \> }
    \> return op;
    }
    

    This creates a stack overflow, so I guess I have to allocate memory, but where and how do it have to do this?



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

    On 21/07/2010 at 02:41, xxxxxxxx wrote:

    Don´t use op! In GetVirtualObjects you must create your own objects and NEVER modify the existing scene! NEVER. op and hh are only there for working with them.

    Do it something like this (not guaranteed to work right away, just example code) :

    BaseObject* LODObject::GetVirtualObjects(PluginObject *op, HierarchyHelp *hh)
        
        {  
              Bool dirty	= FALSE;   
        //First check if there are child objects, if not, there is definetly nothing to do so return an empty polyobject for example  
        BaseObject* down = op->GetDown(); if(!down) return PolygonObject::Alloc(0,0);   
        //Otherwise there are child objects, so get them with GetAndCheckHierarchyClone (the dirty variable will be filled automatically if any of the children has changed)  
        down = op->GetAndCheckHierarchyClone(hh, down, HCLONE_ASIS, &dirty, NULL, TRUE);   
        //If down is not filled there was a problem and you return for safety  
        if(!down) return PolygonObject::Alloc(0,0);  
        //If there was no change to the children and there was no change in your objects settings by the user then you have again nothing to do  
        if (!dirty && !op->IsDirty(DIRTY_DATA))   
        {  
        	return down; //simply return the children  
        }  
          
        //Ok, if we got to this point, you now need to do what you want to do  
        //1. Go thru all children, because children count = distance settings count   
        
        
        
        //Get the first child  
        BaseObject *first	= static_cast<PolygonObject*>(down->GetDown()); if(!first) return PolygonObject::Alloc(0,0);  
        
    //A temporary variable for an index like behavior. The distance setting ids in your object#s container should be enumerated accordingly (e.g. 2000,2001,2002...)  
    int index = 0;  
    while(first!=NULL)  
    { 
    //First make a visible tag of yours (the tag should have one setting which can take the distance!)  
    BaseTag* tag = first->MakeTag(YOUR_TAGID); if(!tag) continue;  
    //Now set the data in the tag (not in the objects container)  
    tag->GetDataInstance()->SetReal(YOURTAG_DISTANCEVALUE_RESOURCE_ID, op->GetDataInstance()->GetReal(ID_IN_OBJECT + index,0));  
    //Get next children  
    first = first->GetNext();  
    //Increase the index  
    ++index;  
    }  
      
    return down;  
    }
    

    Now, please check the sdk examples deeper and try to understand the concepts first before you make any further steps. Otherwise you end up wasting time and not get to the point correctly.

    Hope this helps you getting started



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

    On 21/07/2010 at 05:21, xxxxxxxx wrote:

    Thanks for taking your time and explaining :) 
    That helped  a lot, I got it all working now!


Log in to reply