Undo loses stored data
-
On 23/10/2015 at 08:03, xxxxxxxx wrote:
Hi everyone.
I have an ObjectData plugin which processes and stores about 10 million values when a button is pressed. Then, the values are referenced in GetVirtualObjects (roughly 200 000 per frame). If I press undo, the stored values are lost. I've tried to use various AddUndo() etc commands but no success. I assume this is due to the values being stored in a standard list and not something C4D specific like a BaseContainer.
I can actually avoid this problem with a BaseContainer with many sub BaseContainers but unfortunately this seems to slow everything down a lot when reading it back every frame.
Does anyone know if I can keep my standard stored list method using an undo command configuration? Or if I'm missing something obvious?
Here is a fragment of a really simplified version of my plugin:
class MyPlugin(plugins.ObjectData) : def Init(self, op) : # ---------------// This is the data that disappears with an undo self.data = [] return True def Message(self, op, type, data) : if type == c4d.MSG_DESCRIPTION_COMMAND: #---------------// If the update button is pressed, call the update data function if data["id"][0].id == UPDATE_DATA: self.Update_Data(op) return True def Update_Data(self, op) : #---------------// Here 's where I fill the array self.data.append(1) self.data.append(2) self.data.append(3) return True def GetVirtualObjects(self, op, hh) : #---------------// And here's where I do stuff with it for i in self.data: print i return None
-
On 24/10/2015 at 06:24, xxxxxxxx wrote:
Hi Adam, you need to implement NodeData.CopyTo(). This will allow you to copy the data to the internal
copy of the object that is being made when an undo step is created. -
On 25/10/2015 at 10:28, xxxxxxxx wrote:
Thanks Niklas, that's exactly what I was looking for. I'm completely amazed that I've never actually needed that before.
Cheers,
Adam
-
On 25/10/2015 at 12:34, xxxxxxxx wrote:
Well I thought I was out of the woods but I guess I'm not yet. As soon as I introduce NodeData.CopyTo() into my plugin, it crashes at any attempted copying of the plugin object. Any ideas what might be doing that?
What I have tried so far is to implement the Read() & Write() methods correctly which I think I have managed to do as I can read the data back successfully after saving. I tried this as the documentation says that it's likely that I would need all three but I'm not sure if they get called on a copy command.
Even if the CopyTo function sits there empty it still crashes. What am I missing?
Thanks,
Adam
-
On 25/10/2015 at 13:15, xxxxxxxx wrote:
One more thing too add. This error does not occur in R16, only R17. I'm not sure if that means there is a bug or something I can't figure out about this:
- trn (
AliasTrans
) –
Changed in version R17.032: An alias translator is passed.
An optional alias translator for the operation.
An alias translator for the operation.
- trn (
-
On 26/10/2015 at 03:24, xxxxxxxx wrote:
Hello,
can you show us what exactly you are doing in your CopyTo() and Read(), Write() functions? What exactly does crash?
Best wishes,
Sebastian -
On 26/10/2015 at 03:53, xxxxxxxx wrote:
What exactly does Crash?
Cinema reports an application error and crashes and I have to execute a force quit. This error only occurs when the node is copied. e.g. I call a copy command(or press copy), I drop the object into a cloner etc.
What am I doing in my CopyTo(), Read() and Write()?
I'm passing a list from the old node to the new one in CopyTo(). Even if however, the CopyTo() function is completely empty and I pass nothing at all, Cinema still crashes. Again this only happens in R17 and not R16. The code works perfectly in R16.
Code below:
Here is the code:
def Write(self, node, file) : self.num_frames = len(self.data) # Write the number of frames to the hf file.WriteInt32(self.num_frames) for i in xrange(self.num_frames) : # These are the lengths of each frame frame_length = int(len(self.data[i])) # Write frame lengths to file file.WriteInt32(frame_length) for i in self.data: for j in i: # Write each point file.WriteVector(j) return True def Read(self, node, file, level) : # Read back number of frames self.num_frames = file.ReadInt32() # Read back the number of values for each frame frame_lengths = [] for i in xrange(self.num_frames) : fl = file.ReadInt32() frame_lengths.append(fl) # Read back the values and apply them to the frame lists # And recreate the main list del self.data[:] for i in frame_length: frame = [] for j in xrange(i) : pos = file.ReadVector() frame.append(pos) self.data.append(frame) def CopyTo(self, dest, snode, dnode, flags, trn) : dest.data = self.data return True
Saving and loading of data sees to be right in Read() and Write(), I've done a few tests.
Thanks,
Adam
-
On 27/10/2015 at 09:28, xxxxxxxx wrote:
Hello,
it seems that there is indeed a bug with CopyTo(). We are currently working on fixing this bug and try to provide a fix as soon as possible.
Thanks and best wishes,
Sebastian