UNSOLVED Get ID of Undo-ed parameter...?

C++

Hello.
(very simplified explanation of what my plugin performs )
My ObjectData plugin has some slider parameter ("myParameter") which controls the radius parameter of some sphere.
When the user changes myParameter, MSG_DESCRIPTION_POSTSETPARAMETER catches the message of its ID and calls the function void modifySphereRadius().
(in reality there are lot of "myParameters", "objects" and "modifyObjFunc()"s in my plugin).

At this step everything works fine.

Now I want to make a proper Undo/Redo operation.
I don't want to add AddUndo() operation (doc->AddUndo(UNDOTYPE::CHANGE, mySphere);) inside to my modifySphereRadius() function. It causes the problems during running animation (when myParameter is animated) etc.

So, what I've think, that it would be good to call my modifySphereRadius() function only when myParameter value is restored from the Undo.

Is the way to achieve this?

When the user changes myParameter, the C4D creates the undo-version of my node. And when the user calls Undo action, the old myParameter value of my node is restored.

BUT what I've found that no corresponding messages in the MSG_DESCRIPTION_POSTSETPARAMETER for the myParameter ID was sent.

Is the way to catch the message for the exact parameter ID after it was restored when user called Undo/Redo?

hi,

this is not super clear why you have so much issue while you are running the animation or why you need to execute those function to update your values. I am afraid you are adding hack over hakcs.

The object itself is added to the undo stack, you cannot know the parameter that have been changed.
You could react to the undo being triggered with the message MSG_DOCUMENTINFO that should have the type of MSG_DOCUMENTINFO_TYPE_UNDO . This message will be broadcast to all the object in the scene. In your message function you can add something like this:

else if (type == MSG_DOCUMENTINFO)
	{
		DocumentInfoData* const msg = static_cast<DocumentInfoData*>(t_data);
		if (msg == nullptr)
			return false;
		// switch message sub-type
		if (msg->type == MSG_DOCUMENTINFO_TYPE_UNDO)
		{
			GeData data;
			node->GetParameter(TUBEOBJECT_RAD, data, DESCFLAGS_GET::NONE);
			Int32 radius = data.GetInt32();
			DebugStop();
		}

You will not know which parameter have changed but you will be able to retrieve the new values.
Cheers,
Manuel

Hi Manuel.
I have a pretty complex structure when not only the slider parameter but also the SplineData parameter of my plugin controls an array of objects (its radiuses, positions, etc).
So I need to use doc->StartUndo() every for-cycle loop for each object in the array. During animation it gets me the error in doc->StartUndo() line, in AddUndo() line, EndUndo() and sometimes causes a crash.
Also I don't need to create the Undo each frame during the animation (when parameter is changed by animation key). I need to create Undo only once - when the user interacts with the parameter(s).

According to your code snippet above. Is the way somehow to achieve this:

  1. at the start of Undo/Redo call by user, BEFORE the previous/next version of the node was copied to the scene, somehow to compare the current values of parameters with the values from a copied node-version.
  2. store the parameters for which we find the difference
  3. at the end of Undo/Redo call by user, AFTER the previous/next version of the node was copied to the scene, send the message to a node with the exact parameter-ID
    ?

the message like this:

DescriptionPostSetValue dc;
DescID distrID = DescID(DescLevel(1140, CUSTOMDATATYPE_SPLINE, op->GetType()));
dc.descid = &distrID;
op->Message(MSG_DESCRIPTION_POSTSETPARAMETER, (void*)&dc);

thank you

The problem is that the message is send once the object have been undone. So, you cannot compare anymore two objects.
You can either update all your objects based on the new data or check all your structure and check if it needs any updates.

Thank you for your explanation. I suspected that most likely it would not be possible to catch the moment of the beginning of Undo/Redo. Sad...

So if to consider your advice:...
@manuel said in Get ID of Undo-ed parameter...?:

You can either update all your objects based on the new data or check all your structure and check if it needs any updates.

...if I want to call update function in MSG_DOCUMENTINFO_TYPE_UNDO, so how to retrieve the correct object which have been updated here? (it should be my node). As I think I do not need make update in situations when Undo was made for another objects in the scene.

And also I did not understand the second part in the quote. What the structure should I check? Structure of parameters of my node? Or structure of objects? And how to check that they need any updates?