Help with maya api - undo/redo

Hi there,

I’m struggling to understand how to implement undo functionality in a maya plugin. The code is very simple, all i want to do is create a curve and then when i click undo i want to undo the curve creation. I have included my curve creating code, but i don’t think this is useful because it doesn’t use the MDagModifier setup, so ideally when i press undo all i should need to write is ‘self.dagModifier.undoIt()’ to undo all of the things created with dag modifier.

if anyone could shed some light on this i would really appreciate it. I need to eventually have this function undo multiple curve creations in one go. but one curve is enough for now.

thanks,
Sam

def redoIt(self):
	#create the curve
	curveFn = om.MFnNurbsCurve()
	
	arr = om.MPointArray() 
	positions=[(1,2,3),(0,2,3),(2,3,4),(5,2,4)] 
	for pos in positions: 
		arr.append(*pos)

	curveTransform = curveFn.createWithEditPoints( 
                            					  arr, 
                            					  3, 
                            					  om.MFnNurbsCurve.kOpen, 
                            					  False, 
                            					  False, 
                            					  True 
                            					  ) 
	
			
def undoIt(self):
	pass
	#undo curve creation here

You need an MDGModifier or MDagModifier to register with the undo system. I can never find good example code to show the idea, however. Basically the Modifier class is the undo item that Maya will store; the MPXCommand instance will call the DoIt(), UndoIt() and RedoIt() methods of the modifier to make sure Maya keeps track of the the changes. It is abysmally documented, though

You could check out https://github.com/theodox/plugger for some helper code I use to make it simple, but it’s still kind of annoying

1 Like

thank Theodox for the help,

yep i have been trying to tackle this problem for a week now and the information i have found is really sparse. Or the examples are not close enough to my problem to be useful. If i was a better programming i would probably figure it out logically. But I’ve sort of given up and was hoping someone could just write out the exact code setup i need for this.

i know i can put this is undo:

om.MGlobal().deleteNode(self.curveTransform)

but apparently it is bad practice and can cause maya to crash- so yea hopefully someone on here knows the MDagModifier setup,

cheers,
Sam

FWIW the MDagModifier/MDGModifier stuff only works properly inside a registered plugin to: it doesn’t work properly if you’re just doing it in the listener

can you do what you need just using regular maya.cmds? does it have to be plugin?

the whole reason I’m forced to use api is because i can’t produce an ep curve which has uniform parameterisation between its points and is of degree 3. I have been using this before:

cmds.curve(d=3,n='curve11', ep=[posList[0],posList[1],posList[2],posList[3],posList[4],posList[5]])   

this will create what i want, but then the parameterisation of the curve ranges from 0 to chord length. In order to then make the curve have equal parameterisation between points eg. 0 to 1, 1 to 2, 2 to 3 etc. i need to rebuild the curve, but this makes the points of the curve shift their position slightly. Its so annoying but someone eventually suggested the API way of doing it which gives uniform parameterisation straight away.

So now I’m in the position of having something that works but then being dragged into the world of dagModifier and undo/redo. But as i am probably going to transfer a lot of my code into c++ eventually for speed, i have to learn sometime.

Sam

Do you mean you want the curve to be 0-1 but otherwise keep the shape? That should be


rebuildCurve -ch 1 -rpo 0 -rt 0 -end 1 -kr 2 -kcp 1 -kep 0 -kt 0 -s 0 -d 3 -tol 1e-08 "your_curve_here";

doesn’t do what you need?