Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Recent
    • Tags
    • Users
    • Login

    Undo loses stored data

    Scheduled Pinned Locked Moved PYTHON Development
    8 Posts 0 Posters 732 Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H Offline
      Helper
      last edited by

      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
      
      1 Reply Last reply Reply Quote 0
      • H Offline
        Helper
        last edited by

        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.

        1 Reply Last reply Reply Quote 0
        • H Offline
          Helper
          last edited by

          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

          1 Reply Last reply Reply Quote 0
          • H Offline
            Helper
            last edited by

            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

            1 Reply Last reply Reply Quote 0
            • H Offline
              Helper
              last edited by

              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.
              1 Reply Last reply Reply Quote 0
              • H Offline
                Helper
                last edited by

                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

                1 Reply Last reply Reply Quote 0
                • H Offline
                  Helper
                  last edited by

                  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

                  1 Reply Last reply Reply Quote 0
                  • H Offline
                    Helper
                    last edited by

                    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

                    1 Reply Last reply Reply Quote 0
                    • First post
                      Last post