Your browser does not seem to support JavaScript. As a result, your viewing experience will be diminished, and you have been placed in read-only mode.
Please download a browser that supports JavaScript, or enable it if it's disabled (i.e. NoScript).
On 22/03/2013 at 10:05, xxxxxxxx wrote:
User Information: Cinema 4D Version: R13 Platform: Windows ; Language(s) : C++ ;
--------- Hi,
I've written a kind of cloner object using GetVirtualObjects. I alloc instances of the original object and group it under a null. I'm now wondering if this will produce a memory leak, since the objects will never be freed, f.ex. if the user switches off the generator.
Additional, I would kindly ask you, if you think, this is the best method due to performance. It may produce thousends of clones.
BaseObject *IMVertec::GetVirtualObjects(BaseObject *op, HierarchyHelp *hh) { BaseDocument *doc = hh->GetDocument(); BaseContainer *bc = op->GetDataInstance(); // Daten-Container BaseObject *tp = op->GetDown(); // Tracker-Masterobjekt if (!tp || !bc->GetBool(INIT)) { op->SetDeformMode(FALSE); // Objekt ausschalten bc->SetBool(INIT, FALSE); return NULL; } Bool dirty = FALSE; BaseObject *pp = op->GetAndCheckHierarchyClone(hh, tp, HIERARCHYCLONEFLAGS_ASIS, &dirty;, NULL, TRUE); if (!dirty) return pp; if (!pp) return NULL; // Tracker-Klone erzeugen und auf dem Grid positionieren AutoAlloc<BaseLink> link; BaseObject *gp = bc->GetObjectLink(IMV_GRID_LINK, doc); Matrix mg = gp->GetMg(); BaseObject *mp = BaseObject::Alloc(Onull); if (!mp || !link) goto Error; link->SetLink(tp); LONG i, pcnt = ToPoly(gp)->GetPointCount(); const Vector *pAdr = ToPoly(gp)->GetPointR(); for (i=0; i<pcnt; i++) { BaseObject *cp = BaseObject::Alloc(Oinstance); if (!cp) goto Error; cp->SetParameter(DescLevel(INSTANCEOBJECT_LINK), GeData(link), DESCFLAGS_SET_0); cp->SetRelPos(pAdr[i] * mg); cp->InsertUnderLast(mp); } return mp; Error: blDelete(pp); blDelete(mp); return NULL; }
Maybe, the source code of the C4D cloner object is available somewhere?
Thanks for your assistance.
On 22/03/2013 at 11:51, xxxxxxxx wrote:
The objects will be freed by Cinema. By returning them from GVO, the ownership goes to the Application. This is stated in the docs, when I remember correctly.
Best, Niklas
On 22/03/2013 at 13:27, xxxxxxxx wrote:
blDelete(mp), I think this is incorrect. You should use BaseObject::Free().
On 23/03/2013 at 08:36, xxxxxxxx wrote:
Thanks. I copied that from the atom example of the sdk. But I remeber also that it's better to use Free.
On 23/03/2013 at 08:38, xxxxxxxx wrote:
The SDK says:
static void blDelete(BaseList2D*& bl)
Destructs objects derived from BaseList2D. It's basically the same as BaseList2D::Free().
On 23/03/2013 at 08:56, xxxxxxxx wrote:
Hi Klaus,
Ok, I confused it with bDelete().
Best, -Niklas
On 24/03/2013 at 03:43, xxxxxxxx wrote:
Hi, Using blDelete() or BaseList2D::Free() is really dangerous in bigger projects. Using smart pointers like AutoFree<BaseList2D> is more safe way to to this.
BaseObject *IMVertec::GetVirtualObjects(BaseObject *op, HierarchyHelp *hh) { BaseDocument *doc = hh->GetDocument(); BaseContainer *bc = op->GetDataInstance(); // Daten-Container BaseObject *tp = op->GetDown(); // Tracker-Masterobjekt if (!tp || !bc->GetBool(INIT)) { op->SetDeformMode(FALSE); // Objekt ausschalten bc->SetBool(INIT, FALSE); return NULL; } Bool dirty = FALSE; //BaseObject *pp = op->GetAndCheckHierarchyClone(hh, tp, HIERARCHYCLONEFLAGS_ASIS, &dirty, NULL, TRUE); AutoFree<BaseObject> pp( op->GetAndCheckHierarchyClone(hh, tp, HIERARCHYCLONEFLAGS_ASIS, &dirty, NULL, TRUE) ); if (!dirty) return pp.Release(); //if you forget Release() here then C4D will crash if (!pp) return NULL; // Tracker-Klone erzeugen und auf dem Grid positionieren AutoAlloc<BaseLink> link; BaseObject *gp = bc->GetObjectLink(IMV_GRID_LINK, doc); Matrix mg = gp->GetMg(); AutoFree<BaseObject> mp( BaseObject::Alloc(Onull) ); //can also be replaced with AutoAlloc<BaseObject> if (!mp || !link) goto Error; link->SetLink(tp); LONG i, pcnt = ToPoly(gp)->GetPointCount(); const Vector *pAdr = ToPoly(gp)->GetPointR(); for (i=0; i<pcnt; i++) { //this is only one place where AutoFree is not really necessary for now, //but if this for loop will grow over times then it will be. AutoFree<BaseObject> cp( BaseObject::Alloc(Oinstance) ); if (!cp) goto Error; cp->SetParameter(DescLevel(INSTANCEOBJECT_LINK), GeData(link), DESCFLAGS_SET_0); cp->SetRelPos(pAdr[i] * mg); cp->InsertUnderLast(mp); cp.Release(); // this is important because cp now belong to mp. } //if you forget Release() here then C4D will crash and you will know why, but no memory leaks will happens. return mp.Release(); Error: //this is not really needed any more. //pp.Free(); //blDelete(pp); //mp.Free(); //blDelete(mp); return NULL; }
Remo
On 25/03/2013 at 03:25, xxxxxxxx wrote:
Thanks Remo, I will try it.
On 25/03/2013 at 03:52, xxxxxxxx wrote:
C4D crashes immidiately. Switching back to the old call of GVO works. This looks coherent for me, since there is no allocation of the virtual object pp at all.
On 25/03/2013 at 04:34, xxxxxxxx wrote:
of course it will crash
if (!dirty) return pp.Release(); //if you forget Release() here then C4D will crash
Crash is better as memory leak, it is much easier to find and to fix.
On 29/03/2013 at 05:17, xxxxxxxx wrote:
Rendering doesn't work. Dirty is always FALSE. Any ideas?