Internal objects cloned for GVO don't show

On 24/01/2013 at 09:22, xxxxxxxx wrote:

User Information:
Cinema 4D Version:    
Platform:      
Language(s) :

---------
My plugin has a private attribute   AtomArray* objects   which is a collection of BaseObject instances.
The objects in this array are not linked in any relationship (free-standing, no document, no parent,
but possibly children). On GVO, I clone these objects and insert the clones under a null-object.

    BaseObject\* GetVirtualObjects(BaseObject\* op, HierarchyHelp\* hh) {
        LONG count = objects->GetCount();
        if (count <= 0) return NULL;

        /\* This Null-Object will serve as a "container" for all the
         \* other objects. \*/
        BaseObject\* root = BaseObject::Alloc(Onull);
        if (root == NULL) return NULL;

        for (LONG i=0; i < count; i++) {
            BaseObject\* reference = (BaseObject\*) objects->GetIndex(i);
            BaseObject\* clone = (BaseObject\*) reference->GetClone(
                    COPYFLAGS_0, NULL);
            if (clone == NULL) {
                GeDebugOut("ERROR %s:%d - %s: cloning cached reference "
                           "object failed.", \__FILE\_\_, \__LINE\_\_, \__FUNCTION\_\_);
            }
            else {
                clone->InsertUnder(root);
            }
        }

        /\* FIXME: The cloned objects inserted under `root` are not
         \* "recognized" by Cinema 4D. \*/
        return root;
    }



The objects do not show up in the editor. When casting a CSTO on the generator, the resulting
null-object does not have any children.


Before I began the C++ version, I was attempting a Python version, where this issue occured
and I was hoping it was an issue with Python, but it isn't. You can find the (incomplete, but
enough for demonstration) [Python version here](https://docs.google.com/file/d/0B8i9BbP98pJRUWRzLTVYYnFzOEk/edit).


The internal objects come from the active document, therefore before I add them to my array,
I call GeListNode::Remove() on them. When I store an object in the array that does not come
from the active document (eg. allocated and inserted directly, Remove() not called), the object
is shown. In the following video, the "packed" object is loaded from the HyperFile when the
scene is loaded from the disk, therefore it is shown (because it was allocated and inserted
directly). [Video on Youtube](http://www.youtube.com/watch?v=NTAqQDj7oJw)


How can I fix this issue?

On 24/01/2013 at 09:39, xxxxxxxx wrote:

could be related to the dead objects problem i ran into here :

https://plugincafe.maxon.net/topic/6767/7472_what-are-dead-objects-&KW=dead+spline

c4d doesn't like floating objects at all, but the fact that directly allocated objects work fine
is funny. have you tried to insert them into a dummy document  before you clone them ?

On 24/01/2013 at 09:56, xxxxxxxx wrote:

Hi Ferdinand,

Thanks for your input. Hm, I thought this was a Python-only issue..? Eg. that a dead object is an
object that has already been deallocated but the Python runtime still has a reference to it. It looks
kind of an overhead to me to create a document where I store my private objects instead of a
simple AtomArray.

Gon'na try and report.

Best,
Nik

On 24/01/2013 at 10:16, xxxxxxxx wrote:

Bad news: It doesn't fix the problem, still the same.

The doc variable is a private BaseDocument* attribute of my ObjectData subclass.

    void Packup(BaseObject* op) {
        BaseObject* current, *next;
        for (current=op->GetDown(); current; current=next) {
            next = current->GetNext();
            current->Remove();
            doc->InsertObject(current, NULL, NULL);
        }
    }
  
    void Unpack(BaseObject* op) {
        BaseObject* current, *next;
        for (current=doc->GetFirstObject(); current; current=next) {
            next = current->GetNext();
            current->Remove();
            current->InsertUnder(op);
            current = next;
        }
    }
  
    BaseObject* GetVirtualObjects(BaseObject* op, HierarchyHelp* hh) {
        LONG count = objects->GetCount();
        if (count <= 0) return NULL;
  
        /* This Null-Object will serve as a "container" for all the
         * other objects. */
        BaseObject* root = BaseObject::Alloc(Onull);
        if (root == NULL) return NULL;
  
  
        BaseObject* current = doc->GetFirstObject();
        for (; current; current=current->GetNext()) {
            BaseObject* clone = (BaseObject* ) current->GetClone(COPYFLAGS_0, NULL);
            clone->InsertUnder(root);
        }
  
        return root;
    }

Best,
Niklas