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:
            return True
        def Update_Data(self, op) :
            #---------------// Here 's where I fill the array
            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.



  • 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?



  • 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.

  • On 26/10/2015 at 03:24, xxxxxxxx wrote:


    can you show us what exactly you are doing in your CopyTo() and Read(), Write() functions? What exactly does crash?

    Best wishes,

  • 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
            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
            for i in self.data:
                for j in i:
                    # Write each point
            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()
            # 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()
        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.



  • On 27/10/2015 at 09:28, xxxxxxxx wrote:


    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,

Log in to reply