THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 04/04/2007 at 15:48, xxxxxxxx wrote:
Cinema 4D Version: R8.2-R10
Platform: Windows ; Mac ; Mac OSX ;
Language(s) : C++ ;
I think that this is the word that seems to be missing in most discussions of the SDK - most especially undos.
Here's my point in case. Currently, the only way that I can store working undos is by storing the root polygon object of a rigged figure - this includes the bones and tags - and consumes memory like a mother. This just isn't viable. The alternative is to just store the tags which are at the root of the changes - and here's why:
The plugin bone uses GetDDescription() to create a set of sliders which represent the values on the plugin tags attached to it. Since the tags don't have sliders and aren't even visible - but the value is stored in the basecontainer there, I'm finding it impossible to get MSG_DESCRIPTION_INITUNDO called on the tag - because the slider is on the bone and sets the value in the basecontainer. Even literally calling tag.SetDParameter() from bone.SetDParameter() doesn't trigger this message.
I know that calling AddUndo() calls Init(),CopyTo(), and possibly GetDDescription() (?). That's after behavior. What I want to know is how to control before behavior - how does one trigger a MSG_DESCRIPTION_INITUNDO for bc->SetReal(ID, value) or some action done from another 'controlling' object. This might allow me to store only the tag in undo and save GB of memory.
Currently, I call a method to set the values (and perform other actions on the slider changes). But this method is called for everything - setup, like SetDParameter() - on all slider changes, even animation keyframes. So calling the AddUndo() from there wouldn't be viable as you can imagine. It isn't until R9.0 that MSG_DESCRIPTION_USERINTERACTION_END is added, if that is useful at all.
Thank you very much,
On 05/04/2007 at 15:43, xxxxxxxx wrote:
This sucks eggs!
Now I understand the behavior a little better.
For MSG_DESCRIPTION_INITUNDO handling:
UNDO_CHANGE: includes all children and tags, sends a MSG_CHANGE when undo is performed.
UNDO_CHANGE_NOCHILDS: includes no children and all tags, sends a MSG_CHANGE when undo is performed.
UNDO_CHANGE_SMALL: includes no children and no tags (which is what I want!), sends zilch (thanks).
Otherwise (internal undo handling) is exactly the same as UNDO_CHANGE_SMALL (note my appraisal of this).
I need UNDO_CHANGE_SMALL and a way to know when an undo is performed (for various reasons). This is exactly NOT how the C4D SDK works. Since the thing changing is a DYNAMIC!!! slider whose value is from a tag on the object, the internal/SMALL undo does not reset the tag and thus does not reset the slider (the value is pulled from the tag in GetDDescription(), duh) - though it does update the editor view properly (?).
Now, you're asking yourself: Why don't you just use UNDO_CHANGE_NOCHILDS? Because there is a situation with my morphs. Morph deltas are applied directly to the Polygon object point array as difference values (morph strength = new value - old value). The undo behavior leaves me without any way to make the difference calculation (the undo object which replaces the current one knows nothing of the current value!). Where would I cache the current value since the tag and node are replaced outright under these circumstances?
To Maxon: Please, please, please add a MSG_UNDO so that when a user performs an undo involving our painstakingly worked plugins, they can react properly by knowing that it occurred! I don't need stack access or lots of details, just a message to the undo object that it's about to be undone would be more than sufficient.
On 13/04/2007 at 16:00, xxxxxxxx wrote:
I'm still not pleased with undos (the C4D undo system sucks - state changes, not entire objects, please) - there are still situations where just adding the root object and plugin bone cause C4D to crash. The solution is still to AddUndo(UNDO_CHANGE, root) which entails the root object, all of its tags, all of its bones, all the bones' tags, all conformed figures (with similar), all parented objects. This is ridiculous!
Is there something about hierarchy modifiers wherein you MUST AddUndo() the entire hierarchy - because that is directly the cause: only adding the offending bone is causing the crash. Just undoing the root (no childs) doesn't work, but it never crashes. Adding the entire root and hierarchy works - but is so memory consumptive as to be prohibitive (we're talking possibly 10s or 100s MB at a shot - for each goddamn slider change!)
I have no control over the actual undo/redo process - only what I add to be undone/redone. 10 days of devoted, dedicated testing, checking, coding, debugging, and there is no way for me to determine why this behavior exists.
On 13/04/2007 at 16:36, xxxxxxxx wrote:
I'm starting to think that this has more to do with MSG_DESCRIPTION_INITUNDO than anything else. The same undo approach used in other places (actions that are independent of SetDParameter() and don't therefore send a MSG_DESCRIPTION_INITUNDO) work flawlessly. My tool, which sets the values on the same tags as the sliders only requires that AddUndo(UNDO_CHANGE, tag) is included to work. Same general ideal for my Fix (which converts my plugin objects to C4D objects) and Copy/Paste undos.
It is only in responding to that darned message to store a single undo for a possibly continuous slider change (which is the only message that is useful for this) that I need to store everything in sight or can expect a crash on undo. If this could work like my tool, heaven for me and my userbase.
By the way, the error is "Access Violation". You might already be receiving several of these from R10 users of my plugin. Something is getting befuddled in the plugin bone - but only in this case (?) and no others. My CopyTo() routine is bedrock (or I would know about it). Something else about hierarchy modifiers that this particular type of undo doesn't like...
You figure it out - it's your undo system.
On 14/04/2007 at 14:24, xxxxxxxx wrote:
To continue my rant/beef with the Cinema 4D SDK undo system, here is the behavior when changing a slider in the AM:
My point of contention is that MSG_DESCRIPTION_INITUNDO is only sent on the first interaction with the slider. If you then interact with the same slider (without going to another AM element), no MSG_DESCRIPTION_INITUNDO is sent. The same behavior exists even if the Timeline frame is changed (so as to animate the slider). This makes for an awkward situation since the first interaction may have been setting the intial value at frame 0 (with an undo) and the subsequent one a new value at frame N (no undo). How does C4D respond on undo - not very well as there was no way to add an undo for the slider's object between interactions (!).
Getting my point and frustration, yet?
I also cannot determine why undos for a tag on an object where the object AM is in use differ from those of the same tag on the same object, but being accessed by another tag (on the root object of the hierarchy). My only thought here has to do with messaging during the undo process (again, something that is internal to C4D and hardly within my control - unless someone has some insight here).
On 19/04/2007 at 01:13, xxxxxxxx wrote:
I will forward your findings to the developer. Maybe they have an answer.