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
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    UNDOTYPE_CHANGE Creates Duplicate Objects on Redo

    Scheduled Pinned Locked Moved PYTHON Development
    7 Posts 0 Posters 734 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 20/10/2015 at 16:40, xxxxxxxx wrote:

      Hi,

      I'm running into an issue w/ UNDOTYPE_CHANGE. The documentation says it should be used for:

      Any change to an object, including hierarchy modifications; modification in positioning (object has been moved from A to B), substructures etc. (Needs to be called BEFORE action.)

      However, it doesn't seem to respect Hierarchy changes where the object is removed from the hierarchy and reinserted somewhere else.

        
      """Place Under Null   
      Places the first selected object under a Null located at the world origin.   
      """   
        
      import c4d   
      from c4d import gui   
        
      def main() :   
          #Remove the Selected Object   
          doc.StartUndo()   
          doc.AddUndo(c4d.UNDOTYPE_CHANGE, op)   
          op.Remove()   
             
          #Create a Null, and place selected under it   
          null_obj = c4d.BaseObject(c4d.Onull)   
          op.InsertUnder(null_obj)   
             
          #Add null to scene   
          doc.InsertObject(null_obj)   
          doc.AddUndo(c4d.UNDOTYPE_NEW,null_obj)   
             
          #Tell C4D something has changed       
          doc.EndUndo()   
          c4d.EventAdd()   
        
      if __name__=='__main__':   
          main()   
      

      To Recreate:

      1. Add a cube to your scene
      2. Run the above script, your Cube will be placed under a Null
      3. Hit Undo (Null is removed, you just have your Cube again)
      4. Hit Redo - You get your cube under the null, and a copy of your cube!

      Using "c4d.UNDOTYPE_DELETE" seems to resolve the issue, but I'm curious to know why UNDOTYPE_CHANGE doesn't work as described.

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

        On 21/10/2015 at 01:08, xxxxxxxx wrote:

        Hello,

        there is a special undo type for hierarchy modifications: UNDOTYPE_HIERARCHY_PSR. With this type only one undo step is needed:

          
        doc.StartUndo()  
          
        doc.AddUndo(c4d.UNDOTYPE_HIERARCHY_PSR, op)  
          
        op.Remove()  
        doc.InsertObject(op, None, None)  
          
        doc.EndUndo()  
        

        best wishes,
        Sebastian

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

          On 21/10/2015 at 12:54, xxxxxxxx wrote:

          Hi Sebastian,

          When I use that undo type the objects are removed from the scene when I hit Undo. Seems like this might be a bug in the Python API.

            
          """Place Under Null   
          Places the first selected object under a Null located at the world origin.   
          """   
            
          import c4d   
          from c4d import gui   
            
          def main() :   
              #Remove the Selected Object   
              doc.StartUndo()   
              doc.AddUndo(c4d.UNDOTYPE_HIERARCHY_PSR, op)   
              op.Remove()   
            
              #Create a Null, and place selected under it   
              null_obj = c4d.BaseObject(c4d.Onull)   
              op.InsertUnder(null_obj)   
            
              #Add null to scene   
              doc.InsertObject(null_obj)   
              doc.AddUndo(c4d.UNDOTYPE_NEW,null_obj)   
            
              #Tell C4D something has changed       
              doc.EndUndo()   
              c4d.EventAdd()   
            
          if __name__=='__main__':   
              main()   
          

          - Donovan

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

            On 21/10/2015 at 16:14, xxxxxxxx wrote:

            I think the support guys are gone until Monday Donovan.

            You seem to be doing hierarchy changing on the object while it's in memory rather than in the OM. And that might be why the undo is not working as expected. I honestly don't know.
            This code works for me. But I'm doing it a bit differently so I don't know if it really answers your question or not.

            #This script shows how to undo hierarchy changes  
              
            1. Add a null to your scene  
            2. Add a cube to your scene and make sure it's selected  
            3. Run this script and your Cube will be placed under a new Null  
            4. Undo and the cube goes back to being all by itself again and the new null gets deleted  
              
            import c4d  
            def main() :  
              
              #Creates a Null object and then inserts it after the selected object(Cube)  
              null_obj = c4d.BaseObject(c4d.Onull)  
              null_obj.SetName("NN")     
              doc.InsertObject(null_obj, None, op)   
              doc.AddUndo(c4d.UNDOTYPE_NEW, null_obj)  
              
              #Now we will move the op in the OM and make it a child of the new null object  
              #There is a special undo function for changing hierarchies  
              doc.AddUndo(c4d.UNDOTYPE_HIERARCHY_PSR, op)  
              op.Remove()   
              op.InsertUnder(null_obj)         
              
              c4d.EventAdd()  
              
            if __name__=='__main__':  
              main()
            

            -ScottA

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

              On 26/10/2015 at 01:40, xxxxxxxx wrote:

              Hello,

              if you move an object that already is in the scene you don't need an UNDOTYPE_NEW. Take a look at the example I posted.

              Best wishes,
              Sebastian

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

                On 26/10/2015 at 07:26, xxxxxxxx wrote:

                We are both using: c4d.BaseObject(c4d.Onull) to dynamically create a new parent null object.
                That's what the instance of UNDOTYPE_NEW is for.

                My code works as expected for me.
                But Donovan never replied back if his works as expected now or not.

                -ScottA

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

                  On 26/10/2015 at 09:33, xxxxxxxx wrote:

                  Hey Scott,

                  Thanks for the reply. Yep, it seems like you're correct - the issue I was experiencing is because I was adding my objects as a child of the Null before inserting it into the scene which is why I was getting the duplicate objects upon Redo. Good to know the correct way of going about things.
                  Thanks!

                  Donovan

                  PS: I'd say this issue is now resolved for me.

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