Plugin Cafe Homepage
Forum Home Forum Home > Plugin Cafe > SDK Help
  New Posts New Posts
  FAQ FAQ  Forum Search   Register Register  Login Login

DIRTYFLAGS_DATA

 Post Reply Post Reply
Author
Message
C4DS View Drop Down
Member
Member


Joined: 2015 Dec 01
Online Status: Offline
Posts: 157
Post Options Post Options   Quote C4DS Quote  Post ReplyReply Direct Link To This Post Topic: DIRTYFLAGS_DATA
    Posted: 2017 Dec 04 at 1:48am

User Information:

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

---------

Testing with a MessageData plugin.
On every EVMSG_CHANGE I parse the scene hierarchy and check every polygon object's state:


                    if (object->IsDirty(DIRTYFLAGS_DATA))
                        GePrint("Object " + object->GetName() + " data state has changed");
                    else
                        GePrint("Object " + object->GetName() + " data state unchanged");


Funny thing is, when I select a face or an edge with the live selection tool: no change of state.
When I use ring selection tool, or loop selection, result is a change of state (which I would expect).

What's the consistency here, or rather the inconsistency?
What has changed in the object's container with ring/loop that hasn't changed with a live selection?

Back to Top
Andreas Block View Drop Down
Forum Moderator
Forum Moderator
Avatar

Joined: 2014 Oct 01
Location: Hannover
Online Status: Offline
Posts: 1599
Post Options Post Options   Quote Andreas Block Quote  Post ReplyReply Direct Link To This Post Posted: 2017 Dec 04 at 8:27am
Actually nothing changes in the BaseContainer of an object, when selections are changed. The fact some selection tools are changing the dirty count of the object itself, may have other (or even historic) reasons.

Rather check the dirty count of the selection itself (BaseSelect::GetDirty()).

Cheers,
Andreas
SDK Support Engineer
Back to Top
C4DS View Drop Down
Member
Member


Joined: 2015 Dec 01
Online Status: Offline
Posts: 157
Post Options Post Options   Quote C4DS Quote  Post ReplyReply Direct Link To This Post Posted: 2017 Dec 04 at 11:43pm
Andreas, thanks for bringing up the BaseSelect::GetDirty(), as this has been something I had overlooked.
However, I do get inconsistent results from this.
Sorry to keep bringing up these weird situations.

In the same test MessageData plugin, I thus check on the dirty value of the baseselect.
It changes each time one or more polygons are selected/deselected.
The increment of the dirty value seems to depend on the amount of polygons that get selected/deselected. Not really that important for now, but if there is some logic behind it, it might be useful for me to understand.

Now, when I perform an undo or redo, the dirty value increments with a value of one. Again, the increment value is not that important. But the dirty value changes, which is important to know.
When you use loop or ring selection, the dirty value increments as expected, except if you perform undo or redo. Then suddenly the dirty value DOES NOT CHANGE.
Still the selection is different before and after an undo.

As such, there is again an inconsistency between live selection and loop/ring selection. Which means checking the dirty value is again not a common solution.

Back to Top
Andreas Block View Drop Down
Forum Moderator
Forum Moderator
Avatar

Joined: 2014 Oct 01
Location: Hannover
Online Status: Offline
Posts: 1599
Post Options Post Options   Quote Andreas Block Quote  Post ReplyReply Direct Link To This Post Posted: 2017 Dec 05 at 6:20am
I already mentioned (and explained the reasons) in the other thread (http://www.plugincafe.com/forum/forum_posts.asp?TID=13933), IsDirty() shouldn't be used in this context. Instead use GetDirty(). Also one should not try to interpret any meaning into the changes of the dirty counts. Only compare them to the last value on (in-)equality.

I'm terribly sorry, you are encountering one issue after another. You seem to have a run there...

I can reproduce the behavior of the BaseSelect dirty count. In my tests a combination of the host object's dirty count and the BaseSelect's dirty count seem to work. But I'm sure you will find another issue (but please don't stop, every issue we are aware of helps in the end) and I will also add this topic to my discussion with development.

Cheers,
Andreas
SDK Support Engineer
Back to Top
C4DS View Drop Down
Member
Member


Joined: 2015 Dec 01
Online Status: Offline
Posts: 157
Post Options Post Options   Quote C4DS Quote  Post ReplyReply Direct Link To This Post Posted: 2017 Dec 05 at 7:11am
Yes, read the IsDirty() explanation from the other thread.

Combination of object's dirty and BaseSelect's dirty ... humm, where did I see that before.

In a former life this is what I did:

    UInt32 objectDirty = object->GetHDirty(HDIRTYFLAGS_OBJECT);
    UInt32 selectionDirty = object->GetDirty(DIRTYFLAGS_SELECT);
    Bool selectionHasChanged = (mLastSelectionChecksum != selectionDirty);
    // When points, edges or polygons are selected via loop or ring selection,
    // performing an undo will not change the dirty checksum for DIRTYFLAGS_SELECT,
    // this dirty checksum is changed when undoing selections done via live, path, ... selection
    // In order to still detect selection changes we then look at the dirty flag on object
    // (which is changed by the undo/redo, but also most of all other user action, we thus need to filter)
    if (!selectionHasChanged && (mLastObjectChecksum != objectDirty))
    {
        mLastObjectChecksum = objectDirty;
        // check if the current selected items are still the same as previously,
        // user pressing undo will not trigger a change in DIRTYFLAGS_SELECT
        // when items were selected by ring selection or loop selection
        // This is time consuming for all the cases where object is dirty and selection not,
        // but is the only solution to detect undo/redo for loop and ring selection
...



Not exactly the same as checking object and baseselect, but close.
Now, I wanted to get rid of this "dirty" implementation (pun intended), but it seems I'll have to embrace it once again I am afraid.

Looking forward to developers' feedback on both this and the other topic.

By the way, is there a reason why BaseObject::GetDirty(...) returns an UInt32 while BaseSelect::GetDirty() returns an Int32 ?




Edited by C4DS - 2017 Dec 06 at 2:50am
Back to Top
Andreas Block View Drop Down
Forum Moderator
Forum Moderator
Avatar

Joined: 2014 Oct 01
Location: Hannover
Online Status: Offline
Posts: 1599
Post Options Post Options   Quote Andreas Block Quote  Post ReplyReply Direct Link To This Post Posted: 2017 Dec 05 at 7:21am
Regarding signed'ness of the different dirty counts... really? If I had to guess, these were implemented by two different developers and somebody failed to synchronize them. On the other hand, I'm sure, there are profound reasons, I just don't know them.

For your checks simply adding the dirty counts should do the trick:
const Int32 dirtyCount = obj->GetDirty(DIRTYFLAGS_ALL) + selection->GetDirty();
if (dirtyCount == mLastDirtyCount)
return; // nothing to do
mLastDirtyCount = dirtyCount;
// ...

Cheers,
Andreas
SDK Support Engineer
Back to Top
C4DS View Drop Down
Member
Member


Joined: 2015 Dec 01
Online Status: Offline
Posts: 157
Post Options Post Options   Quote C4DS Quote  Post ReplyReply Direct Link To This Post Posted: 2017 Dec 05 at 7:50am
Nah, the signed/unsigned question was just a joke.
I guessed the same thing as you did, but then again, never know if the difference was deliberate.
Back to Top
C4DS View Drop Down
Member
Member


Joined: 2015 Dec 01
Online Status: Offline
Posts: 157
Post Options Post Options   Quote C4DS Quote  Post ReplyReply Direct Link To This Post Posted: 2017 Dec 06 at 3:00am
There, I edited the post and moved the part about the signed/unsigned so as not to assume too much about it.

Additionally, I have now filtered out the BaseSelect changes as a result of undo/redo, and can thus (in theory) skip the check of object dirtiness.
Which doesn't mean I am not interested in feedback from developers about the inconsistent dirty count change. But for now, and this particular scenario, I seem to have a workaround.

Moving focus to the other issue of finding a proper way of detecting geometry change.


Back to Top
Andreas Block View Drop Down
Forum Moderator
Forum Moderator
Avatar

Joined: 2014 Oct 01
Location: Hannover
Online Status: Offline
Posts: 1599
Post Options Post Options   Quote Andreas Block Quote  Post ReplyReply Direct Link To This Post Posted: 2017 Dec 06 at 5:50am
The behavior of the BaseSelect's dirty count after undo (when loop or ring selection are undone, dirty count staying constant) is a bug.
As a workaround please stay with the suggestion above. I'll try to notify here, when it is fixed.

Cheers,
Andreas
SDK Support Engineer
Back to Top
C4DS View Drop Down
Member
Member


Joined: 2015 Dec 01
Online Status: Offline
Posts: 157
Post Options Post Options   Quote C4DS Quote  Post ReplyReply Direct Link To This Post Posted: 2017 Dec 06 at 6:03am
Sad to hear it's a bug.

Would this bug also be involved in the other inconsistent behaviour of the ring/loop selection reported in http://www.plugincafe.com/forum/forum_posts.asp?TID=13898
Where performing an undo would result in a crash, while it doesn't crash when undoing a live-selection action

Excerpt of the problem below:


            // selection change detected, undo the selection change
            doc->DoUndo();

            // we will now create our own undo stack,
            // make the selection change and our own change
            Bool ret = doc->StartUndo();
            ret = doc->AddUndo(UNDOTYPE_CHANGE, object);    // <- crashes when loop selection

            // step 1. redo the selection change for the new undo stack
            BaseSelect* polyS = ToPoly(object)->GetPolygonS();
            for (const auto& item : added)
                polyS->Select(item);
            for (const auto& item : removed)
                polyS->Deselect(item);

            // step 2. perform the actual action




Edited by C4DS - 2017 Dec 06 at 6:04am
Back to Top
Andreas Block View Drop Down
Forum Moderator
Forum Moderator
Avatar

Joined: 2014 Oct 01
Location: Hannover
Online Status: Offline
Posts: 1599
Post Options Post Options   Quote Andreas Block Quote  Post ReplyReply Direct Link To This Post Posted: 2017 Dec 06 at 6:07am
And I thought you'd be happy to hear it's a bug. This way in future a more consistent behavior is to be expected.

For the other question: I can't tell, yet. Please be patient, I will get back to you in the other thread as soon as I have something new.

Cheers,
Andreas
SDK Support Engineer
Back to Top
C4DS View Drop Down
Member
Member


Joined: 2015 Dec 01
Online Status: Offline
Posts: 157
Post Options Post Options   Quote C4DS Quote  Post ReplyReply Direct Link To This Post Posted: 2017 Dec 06 at 6:28am
Oh no, I'm not at all happy that it's a bug.

First, it means that we'll need to wait for it to get fixed.
If it wasn't a bug but a user-error, I might be told to implement it this or that way. And a solution might be available sooner.
Secondly, when the bug gets fixed that means in order to support different Cinema releases I will have to provide two versions of the implementation: a pre and a post bug-fix

So, I would prefer no bugs get fixed Wink
(and now I am going to duck and cover, as I hear things being thrown at me ...)
Of course I am looking forward to a bug-fix and more consistent behaviour.

I think this thread can be closed as solved. I'll follow the progress of the remaining two issues in their appropriate threads.
Thanks Andreas.



Back to Top
 Post Reply Post Reply

Forum Jump Forum Permissions View Drop Down

Bulletin Board Software by Web Wiz Forums® version 9.61 [Free Express Edition]
Copyright ©2001-2009 Web Wiz

This page was generated in 0.109 seconds.