Hello @ECHekman,
Thanks for providing the information that the init function should not modify the scene graph. Ill take this into account in the future.
It is not only NodeData::Init but the majority of NodeData methods and the methods of derived classes that cannot modify the scene graph of a loaded document, as for example the scene graph they are attached to. The reason is that such methods, as for example NodeData::Init, TagData:Execute, ObjectData::GetVirtualObjects, and many more, run in their own threads to parallelize scene execution. Modifying the scene graph of a loaded document from a non-main-thread (i.e., parallel) context can lead to race conditions and access violations and are therefore strictly forbidden. Forbidden are primarily allocations and deallocations, parameter get/set access is allowed (as long as it does not allocate or deallocate a pointed object) but also discouraged outside of TagData::Execute. For details, see Cinema 4D Threads Manual.
I went through that example you linked, but I' m a bit unclear why it is necessary to manually create the handling of a custom and parallel nodegraph branch when plugin GeListNodes are already graphs themselves?
I am not quite sure how you mean 'parallel', but a GeListNode implements both hierarchal (i.e., tree) relations with InsertUnder, GetUp, GetDown, GetNext etc. and arbitrary (i.e., graph) relations with GetBranchInfo. The hierarchy of a node type, e.g., Obase - a BaseObject or Tmytag - your tag class, are always meant to be of the same type and follow the conventions of their base class. Tags are not meant to have children. You must implement your own branch to declare your own non-hierarchical relation between your plugin tag and your basic node.
⚠ The workaround Maxime suggested, just implementing NodeData::CopyTo is unfortunately not valid.
First of all, you must always implement all three serialization functions Read, Write, and CopyTo, you can never only implement only one of them.
But storing nodes irregularly in this manner can lead to access violations as Cinema 4D is then not aware that this quasi-branch exists and might try to execute multiple things at once (via NodeData::GetAccessedObjects), leading to read/write access violations. Moreover, I am fairly sure that this might lead to event or call starvation when Cinema finds there such a dangling BaseList2D (NodeData) instance under your BaseTag (TagData). Or even worse, it will ignore completely it in some contexts, because tags are not supposed to have children.
You must implement a branch in your case, I would recommend following the SDK example as it is slightly cleaner than the forum preview Maxime linked to.
Cheers,
Ferdinand