THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 20/01/2012 at 13:53, xxxxxxxx wrote:
Cinema 4D Version: R13
Platform: Windows ; Mac OSX ;
Language(s) : C++ ;
A GeDynamicArray of vectors is a member variable in my EffectorData class.
Most or all of the stored vectors are reset to their saved values each time an Undo action is peformed.
NodeData::CopyTo() is being called for each Undo and the array is being copied correctly to the cloned render document. Read() and Write() are implemented.
Bool GapEffector::CopyTo(NodeData *dest, GeListNode *snode, GeListNode *dnode, COPYFLAGS flags, AliasTrans *trn)
GapEffector* base = (GapEffector* )dest; if(!base) return FALSE;
base->datArr = datArr;
The problem doesn't occur if the array is stored in a static or global variable. Another option is needed as I don't want separate plugin instances accessing the same array.
Any help would be much appreciated.
On 21/01/2012 at 06:01, xxxxxxxx wrote:
You're not actually creating a new instance of the GeDynamicArray. You are simply pointing the destination at the source one. You need to allocate a new GeDynamicArray and copy/clone the data from source to destination. The '=' operator has this information:
_ Note: You need to increase the size manually using SetCount(). You also need to copy all elements from the array._
Either use this constructor (which may copy the data (??)) :
base->datArr = GeDynamicArray(datArr);
or use something like MergeIn().
On 21/01/2012 at 23:52, xxxxxxxx wrote:
Thanks for the suggestions Robert.
Unfortunately using the constructor in that way generates compile errors and the problem still exists with MergeIn().
I also tried this based on your old HyperFile post but the cache array is still being cleared.
base->cacheArr = GeAllocType(Vector, cnt); if(!base->cacheArr) return FALSE;
CopyMem(cacheArr, base->cacheArr, sizeof(Vector) * cnt);
I've tried using a SceneHook to send a MSG_DOCUMENTINFO_TYPE_UNDO message to the effector so that I can manually cache and restore the array. This isn't possible as Undo clears the array before the message is sent.
On 22/01/2012 at 07:53, xxxxxxxx wrote:
You are declaring the member variable like this (IvyRoot is a class that I use) :
Then allocating (gNew or ::Alloc() or GeAlloc()) each element of the array and pushing it:
IvyRoot* newRoot = gNew IvyRoot;
if (!newRoot) return FALSE;
// - copy values from source element to destination element
// - Push into GeDynamicArray
Note that you MUST allocate the objects stored in the GeDynamicArray.
I think that you must then recreate the elements on the source and Push() them onto the destination array in CopyTo(). Note that CopyTo() works in both directions - when storing an undo and actually undoing. When you store an undo (doc->AddUndo(UNDOTYPE_DELETE) for instance), CopyTo() copies the object (source->destination) into the undo stack. When an undo is undone, the copy is copied back using CopyTo() from the undo stack (still source->destination).
Hope that clarifies the use of GeDynamicArray, CopyTo() and undo a bit.
On 24/01/2012 at 03:38, xxxxxxxx wrote:
I'm afraid I can't get this to work but the clarification on the workings of CopyTo() and Undo is definitely useful. I'll keep exploring and post any reults.
Thanks again for your help.