UNDOTYPE_CHANGE Creates Duplicate Objects on Redo



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



  • 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



  • 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



  • 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



  • 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



  • 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



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


Log in to reply