Detect polygon selection change (revisited)

On 14/11/2017 at 05:44, xxxxxxxx wrote:

User Information:
Cinema 4D Version:   R19 
Platform:   Windows  ;   
Language(s) :     C++  ;

I mention the original topic for informational purpose only:

In the past I used a MessageData plugin to listen to EVMSG_CHANGE to detect changes in polygon selection performed by the user.

class TestMessageData : public MessageData  
  virtual Bool CoreMessage(Int32 id, const BaseContainer &bc);  
  UInt32    mLastDirtyChecksum;  
Bool TestMessageData::CoreMessage(Int32 id, const BaseContainer &bc)  
  // to detect if user has changed polygon selection we listen to EVMSG_CHANGE,  
  // and skip processing any other message  
  if (id != EVMSG_CHANGE)  
      return true;  
  BaseDocument* doc = GetActiveDocument();  
  if (!doc)  
      return true;  
  BaseObject* object = doc->GetActiveObject();  
  if (!object || !object->IsInstanceOf(Opolygon))  
      mLastDirtyChecksum = 0;  
      return true;  
  // !!! simplified detection of change of polygon selection !!!  
  UInt32 objectDirty = object->GetDirty(DIRTYFLAGS_SELECT);  
  if (mLastDirtyChecksum != objectDirty)  
      mLastDirtyChecksum = objectDirty;  
      // if 'undo' then bail out, else perform the action ...  

When user has made selection changes and then presses the undo button, this triggers the detection twice with increasing dirty values. As such, there is no way to know if a change was the result of a direct user action, or as a result of an undo.

Since undos cannot be detected from a MessageData, I am thus looking for an alternative solution to detect selection changes, only resulting from user interactions.

Using a SceneHookData I could detect the undo, but I see no way to combine the two (detect selection changes + detect undo) to omit detecting the selection changes as a result of undos.


On 15/11/2017 at 09:13, xxxxxxxx wrote:

Hi Daniel,

no really good news here. We are not aware of a good way to achieve this. Sorry.

But maybe we can try it the other way round. Why do you want to avoid acting on selections changed due to undo? In the end the selection changed, right? Maybe we can come up with another idea, if we understand the use-case.

On 15/11/2017 at 09:35, xxxxxxxx wrote:

Assume the following:
- when a user selects a polygon, calculation is performed on its vertices, affecting their positions.
- when a user deselects a polygon, another calculation is performed, taking the neighbor polygons into account, again affecting the positions of vertices of the polygon being deselected.
- both calculation do not cancel each other out.

As such, if a user selects and deselects a polygon the end result is not returning the vertices in their original position.
Since currently an undo is detected as if user deselects the selected polygon, there is no way for the user to revert a change.

On 15/11/2017 at 09:43, xxxxxxxx wrote:

Maybe you could get/store a clone of obj before the position change.
Then if you detect undo, set clonedObj->CopyTo(obj)

On 16/11/2017 at 06:51, xxxxxxxx wrote:

I don't think this cloning is a workable solution.

First of all, it's not a single undo step we're talking about. And between polygon selection actions the user can also do other things. Which means I should take a new clone at every polygon selection action, in case the user has changed other things. So, I would basically implement my own undo system in parallel to that of MAXON's. In one way or another I fear synchronization between the two undo systems will go south sooner than later.

Secondly, it's especially the "detect undo" which is the difficult part. If I can detect that the undo is related to change of polygon selection, and I would copy the cloned object back, then it's also as "simple" as not responding to the polygon selection change in the first place.

Detecting undo is feasible. Detecting that a polygon selection change occurred is feasible. Detecting both combined isn't that straightforward.
There isn't an <undo begins here> and <undo ends here>. That would allow me to detect if a selection change happens between (and thus ignore it).
Not that it matters but I am not sure what the MSG_DOCUMENTINFO_TYPE_UNDO and MSG_DOCUMENTINFO_TYPE_REDO actually indicate: is it <undo begins>, or <undo ends>? Or even <undo is ongoing>?

On 16/11/2017 at 08:59, xxxxxxxx wrote:

Hi Daniel,

we are not sure about the entire approach. You are basically hi-jacking the selection tools, and thus end up the above issues.
Wouldn't it be a better approach to implement your own tool? This could then of course also change the selection.