Problem on AddUndo and SendModellingCommand (Weld Tool)



  • Hi PluginCafe team!

    I'm trying to create a script that weld selected points on the middle. For the scene, I just have the default cube made to an editable object.

    It works as expected, but not with the AddUndo.

    It gives me a dialog box error of
    A problem with this project has been detected: Object "Cube" - Point selection out of bonds

    Is there a way around this?

    Here is the code so far

    import c4d
    from c4d import utils
    
    settings = c4d.BaseContainer() 
    
    res = utils.SendModelingCommand(command = c4d.ID_MODELING_WELD_TOOL,  
                                    list = [op], 
                                    mode = c4d.MODELINGCOMMANDMODE_POINTSELECTION, 
                                    bc = settings,
                                    doc = doc)
                                    
    doc.AddUndo(c4d.UNDOTYPE_CHANGE, op)
    c4d.EventAdd()
    

    Thank you for looking at the problem

    P.S.
    From what I understand, if you set the c4d.BaseContainer at empty, it will weld it on the middle by default which is what I want. But just wondering, is there a way to set-it explicitly?

    I checked the parameters on the resource section which is follows:

    {
    
    	MDATA_WELD_POINT			    				     = 1100, //VECTOR
    	MDATA_WELD_TOPOINT                     = 1101, //BOOL
    	MDATA_WELD_POINTINDEX                  = 1102, //LONG
    	MDATA_WELD_OBJECTINDEX                 = 1103, //LONG
    	MDATA_WELD_VISIBLE			               = 1104, //BOOL
    	MDATA_WELD_COLLAPSE                    = 1105, //BOOL
    	MDATA_WELD_COLLAPSE_P1                 = 1106, //LONG
    	MDATA_WELD_COLLAPSE_P2                 = 1107, //LONG
    	MDATA_WELD_COLLAPSE_OBJ1               = 1108, //LINK
    	MDATA_WELD_COLLAPSE_OBJ2               = 1109, //LINK
    	MDATA_WELDPOINT_
    };
    

    But the documentation does not provide a description on such parameters. Or maybe I'm missing something out?



  • Hi @bentraje,

    In order to support undo, you should encapsulate all your calls of BaseDocument.AddUndo with BaseDocument.StartUndo and BaseDocument.EndUndo
    Moreover, take care depending on the operation you are doing, BaseDocument.AddUndo has to be called before or after your operation. Take a look at the documentation to know more.

    Typically StartUndo, defines the state of the scene to be reverted when pressing undo. And EndUndo the state of the scene to be reverted when pressing re-do after an undo.
    AddUndo then record all the changes that you want to store in this undoing.

    Which will give us something like:

    import c4d
    
    # Main function
    def main():
        # Create the BaseContainer to define the tool settings
        settings = c4d.BaseContainer()  
        
        # Explicitly say we will not use point, so the center will be used
        settings[c4d.MDATA_WELD_TOPOINT] = False
        
        doc.StartUndo()
    	
        doc.AddUndo(c4d.UNDOTYPE_CHANGE, op)
        # Execute the SendModelingCommand
        res = c4d.utils.SendModelingCommand(command = c4d.ID_MODELING_WELD_TOOL,
                                        list = [op], 
                                        mode = c4d.MODELINGCOMMANDMODE_POLYGONSELECTION, 
                                        bc = settings, 
                                        doc = doc)
                                        
        doc.EndUndo()
    	
        # Update the scene
        c4d.EventAdd()
    
    # Execute main()
    if __name__=='__main__':
        main()
    

    To find more information about how ID_MODELING_WELD_TOOL works, you can have a look at this topic.

    If you have any question, please let me know.
    Cheers,
    Maxime.



  • Thanks @m_adam

    Works as expected. Have a great day ahead!


Log in to reply