Hey guys, using R23, Windows 10, C++.
I've got another question about my ObjectData plugin and GetVirtualObjects()
. The workflow is that a material needs to be created and inserted into the document. Each object in the scene needs to have a its own material and its own file loaded into memory.
In general the problem is that I can't exactly track the lifetime of an object in C4D scene. Functions like ObjectData::Init()
and ObjectData::Free()
get called all over the place s o I don't rely on them.
My solution is to insert the material in GetVirtualObjects()
. It consists of a different ObjectData "dummy" object and SceneHook object. The 2 ObjectData objects have a Link in their description pointing to each other. The second "dummy" ObjectData is inserted in the SceneHook:
GetVirtualObjects(BaseObject* object) {
BaseObject* dummy = getAtomBaseLink<BaseObject>(*object, DUMMY_OBJECT, NONE, false).GetValue();
BaseObject* dummyParent = nullptr;
if (dummy ) {
DebugAssert(link->GetType() == ID_DUMMY_OBJECT);
dummyParent = getAtomBaseLink<BaseObject>(*dummy, PARENT_OBJECT, document, NONE, false).GetValue();
}
if (!dummy || dummyParent != object) {
BaseSceneHook* hook = document->FindSceneHook(HOOK_ID);
if (hook) {
BranchInfo branchInfo[1];
const Int32 count = hook->GetBranchInfo(branchInfo, COUNT_OF(branchInfo), NONE);
if (branchInfo[0].head) {
GeListHead *dummiesHead = branchInfo[0].head;
dummy = BaseObject::Alloc(ID_DUMMY_OBJECT);
if (dummy != nullptr) {
dummy->InsertUnderLast(dummiesHead);
// set the links of the 2 objects to point to each other
// do other stuff for the material
}
}
}
}
}
At some points I iterate the dummies in the hook and if their Links are nullptr I know the original ObjectData object has been removed from the scene and I can free the material. That's the "garbage collection" process.
Overall this routine is working ok. The material is created just once for each object in the scene. But when I put my object in a Cloner, GetVirtualObjects(BaseObject* object)
would get called 9 different times with 9 different objects. I'd get 9 different dummies and 9 different materials which is what we want. But every time a setting is changed GetVirtualObjects(BaseObject* object)
would get called with yet another set of objects and add more materials, and this would continue indefinitely.
In the end my "garbage collection" process would clean them all up but still I really want to limit the creation to just the amount I need, but I'm not seeing how.
Furthermore I'm also keeping a hashmap in a different dll with some data, which corresponds to each object in the C4D scene. So i need some unique identifier, and I was using GetGUID
but again it is not suitable for the situation with the cloners.
Thanks for the attention and any help will be appreciated!
Warm regards,
Georgi.