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

PoseMorph tag always increases GetDirty() counter

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


Joined: 2015 Dec 15
Online Status: Offline
Posts: 78
Post Options Post Options   Quote Aaron94 Quote  Post ReplyReply Direct Link To This Post Topic: PoseMorph tag always increases GetDirty() counter
    Posted: 2017 Aug 14 at 9:38am

User Information:

Cinema 4D Version:   R16-R18 
Platform:   Windows  ;   
Language(s):     C++  ;   

---------

Hi all!

Look at the minimal scene with problem: 
https://www.dropbox.com/s/pwczovkyg408r1g/GetDirty%20always%20increase%20counter.c4d?dl=0

It's a part of bulb sent by one user. If the Pose Morph tag is assigned to the "spline" object (that is visible in object manager) then the value spline->GetDirty(DIRTYFLAGS_DATA) is increased after each user mouse click in C4D area: either selecting the active object in OM or selecting some tool or even clicks in the custom GUI for image processing.

Also for bulb (Lathe Object) which rotates the spline around the cache is always rebuilt after each such click (as described above). The value bulb->GetHDirty(HDIRTYFLAGS_OBJECT) is increased, the respective obj->GetDeformCache() points to different address (different cache object).

All this happens with no change in object parameters. Only minor mouse clicks.
In this case I don't know what Pose Morph is doing here. But it can be a valuable tool and we don't like if it always forces interactive rendering during modeling to force instant updates.

How to woraround this? Or in other words how to listen for scene updates that don't force unnessary work.

Best regards,
Aaron
Back to Top
mp5gosu View Drop Down
Member
Member


Joined: 2009 Mar 12
Online Status: Offline
Posts: 82
Post Options Post Options   Quote mp5gosu Quote  Post ReplyReply Direct Link To This Post Posted: 2017 Aug 14 at 9:53am
Just a wild guess. Is the tag in edit mode?
Back to Top
Aaron94 View Drop Down
Member
Member


Joined: 2015 Dec 15
Online Status: Offline
Posts: 78
Post Options Post Options   Quote Aaron94 Quote  Post ReplyReply Direct Link To This Post Posted: 2017 Aug 14 at 10:07am
Minimal code:
void DoRecursion(BaseObject *op, BaseDocument * doc)
{
if (!op) return;

UInt32 dirty_x = op->GetHDirty(HDIRTYFLAGS_OBJECT);
UInt32 dirty_y = op->GetDirty(DIRTYFLAGS_DATA);
UInt32 dirty_z = op->GetDirty(DIRTYFLAGS_CACHE);

BaseObject * tp1 = op->GetDeformCache();
BaseObject * tp2 = op->GetCache();

LONG pcnt = 0;
if (op->IsInstanceOf(Opolygon)) {
PolygonObject * pobj = ToPoly(op);
pcnt = pobj->GetPolygonCount();
}

BaseContainer * icnt = op->GetDataInstance();
BaseObject * ires = icnt != 0 ? icnt->GetObjectLink(INSTANCEOBJECT_LINK, doc) : 0;

printf("\n [%3d]:%4d dirty [%3d:%3d:%3d] tp %3d %3d %3d %3d name [%s] n %d",
int(op) % 1000,
op->GetType() % 10000,
dirty_x,
dirty_y,
dirty_z,
int(tp1) % 1000,
int(tp2) % 1000,
int(op->GetDown()) % 1000,
int(ires) % 1000,
op->GetName().GetCStringCopy(), pcnt);

if (tp1)  
DoRecursion(tp1, doc); 
else  
if (tp2)    
DoRecursion(tp2, doc); 
else    
if (!op->GetBit(BIT_CONTROLOBJECT))     
// if (op->IsInstanceOf(Opolygon))        
// { ... } 
}  
for (BaseObject * tp = op->GetDown(); tp; tp = tp->GetNext())  
DoRecursion(tp, doc);
}

void test_on_timer()
{
BaseDocument * doc = GetActiveDocument();
if (!doc) return;

for (BaseObject * tp = doc->GetFirstObject(); tp; tp = tp->GetNext()) {
if (tp != 0)
DoRecursion(tp, doc);
}
}

Printf result:
https://www.dropbox.com/s/vzlzfh6viiqjjme/printf.jpg?dl=0

As you see the caches are changed (their dirty flags) and pointers to them. All this happens after mouse clicks without object changes. How to fix?
Back to Top
Aaron94 View Drop Down
Member
Member


Joined: 2015 Dec 15
Online Status: Offline
Posts: 78
Post Options Post Options   Quote Aaron94 Quote  Post ReplyReply Direct Link To This Post Posted: 2017 Aug 14 at 11:38am
Originally posted by mp5gosu

Just a wild guess. Is the tag in edit mode?

Yes. It's in Edit mode. In Edit mode any click in a scene (or any selection of any object) forces the dirty flags to update. Most bad is update of spline->GetDirty(DIRTYFLAGS_DATA).
If not in Edit mode the situation is a little bit better. Only when user clicks on the spline object (makes it selected) then the spline->GetDirty(DIRTYFLAGS_DATA) is also updated.

I rely on these dirty flags as I need o make robust interactive rendering process while modeling whithout reloading geometry when it's not really needed (when nothing really changed).
Back to Top
mp5gosu View Drop Down
Member
Member


Joined: 2009 Mar 12
Online Status: Offline
Posts: 82
Post Options Post Options   Quote mp5gosu Quote  Post ReplyReply Direct Link To This Post Posted: 2017 Aug 14 at 11:42am
Just a quick tip (aside from your problem)
I'd recommend you to use the active object dialog (it comes with the c4dsdk)
There you'll find pointers, handles, flags, etc. in a nicely sorted way.
Back to Top
Aaron94 View Drop Down
Member
Member


Joined: 2015 Dec 15
Online Status: Offline
Posts: 78
Post Options Post Options   Quote Aaron94 Quote  Post ReplyReply Direct Link To This Post Posted: 2017 Aug 14 at 12:13pm
Thanks for reminding me about this sample from SDK. I have already remoted from it and fogotten. But still it shows the same thing. Addresses and dirty flags of the scene. 
I have tested a couple of render engines with IPR modes and it's the same. They restart render on mouse click on any object :)
Back to Top
knickknack View Drop Down
Forum Moderator
Forum Moderator


Joined: 2016 Jul 01
Location: Italy
Online Status: Offline
Posts: 170
Post Options Post Options   Quote knickknack Quote  Post ReplyReply Direct Link To This Post Posted: 2017 Aug 23 at 9:41am
Hi Aaron, sorry for getting back so late here.

I confirm the behavior you mentioned and I also spotted similar behavior in other renderers. The PoseMorph Tag actually delivers this behavior by-design in order to achieve the desired functionality.

At the same time you can consider on computing the CRC32 checksum (look at ZipFile::CalcCRC32()) of the array storing the vertexes of the cache in order to avoid false-positive updates.
I've tested here and I'd say it plays good enough although you should expect some marginal overheads in terms of interactivity.

Best, Riccardo
MAXON Computer GmbH
SDK Support Team
Back to Top
Aaron94 View Drop Down
Member
Member


Joined: 2015 Dec 15
Online Status: Offline
Posts: 78
Post Options Post Options   Quote Aaron94 Quote  Post ReplyReply Direct Link To This Post Posted: 2017 Sep 20 at 1:40pm
Hi Riccardo, thanks for advice, I use a similar thing (with a different implementation) for different other things as the last method in the world. It's hard to avoid this method for matrix updates in a highly dynamic scene graph with many possible connections and dependecies. But certainly we wanted to avoid such a not very elegant method for mesh data which could contain millions (dozens of millions) of vertices/normals/UVs and etc. 
I suggest C4D developers to fix this issue and make Cinema a bit more clever on dirty/updates department.

Thanks, 
Aaron
Back to Top
Aaron94 View Drop Down
Member
Member


Joined: 2015 Dec 15
Online Status: Offline
Posts: 78
Post Options Post Options   Quote Aaron94 Quote  Post ReplyReply Direct Link To This Post Posted: 2017 Sep 20 at 2:09pm
Btw, how to get the array of UVWStructs as elements of UVWTag? 
From what I have seen the usage is UVWStruct uvw = uvwtag->GetSlow(i). This is not array but a class member call for each element (i.e. slow).
Back to Top
knickknack View Drop Down
Forum Moderator
Forum Moderator


Joined: 2016 Jul 01
Location: Italy
Online Status: Offline
Posts: 170
Post Options Post Options   Quote knickknack Quote  Post ReplyReply Direct Link To This Post Posted: 2017 Sep 21 at 3:11am
Hi Aaron, with reference to the UVWTag I suggest to have a look  at the UVWTag Manual where fast access to UVWTag is explained in detail.

Best, Riccardo
MAXON Computer GmbH
SDK Support Team
Back to Top
Aaron94 View Drop Down
Member
Member


Joined: 2015 Dec 15
Online Status: Offline
Posts: 78
Post Options Post Options   Quote Aaron94 Quote  Post ReplyReply Direct Link To This Post Posted: 2017 Sep 21 at 5:36am
It works like this:
uvwData = UVWTag::Get(handle, i);
UVWTag::Set(handle, i, uvwData);

But do you have some access to array of UVs?
uvwData = uvw_array[4 * i + poly_id]?

There are such arrays for vertices, polygon_to_vertex indices, normals and no UVW. Why?
Back to Top
knickknack View Drop Down
Forum Moderator
Forum Moderator


Joined: 2016 Jul 01
Location: Italy
Online Status: Offline
Posts: 170
Post Options Post Options   Quote knickknack Quote  Post ReplyReply Direct Link To This Post Posted: 2017 Sep 27 at 5:24am
Hi Aaron94, thanks for writing us.

I partially disagree because although vertices and polygon-to-vertex indices are stored as plain arrays, normals and UVW are actually residing in tags which among all the things let the user define multiple set of values rather than a single one (as for vertices and poly-vertex indexes). On top of that even using the VariableTag::GetLowLevelDataAddressR() or (VariableTag::GetLowLevelDataAddressW()) makes no real difference since to retrieve the desired values you should invoke UVWTag::Get().

Long story short the existing API (to access the UVWStruct) is the only (and best)-way to go.
Best, Riccardo

PS: For the future I also warmly invite you to post questions on subjects different from the topic on a new thread.
MAXON Computer GmbH
SDK Support Team
Back to Top
Aaron94 View Drop Down
Member
Member


Joined: 2015 Dec 15
Online Status: Offline
Posts: 78
Post Options Post Options   Quote Aaron94 Quote  Post ReplyReply Direct Link To This Post Posted: 2017 Sep 29 at 8:30am
Thanks Riccardo! I just analize all possible opportunities of C4D API to improve solutions to our tasks. 

As for not openning other thread, then excuse me please. Here you have offered a workaround that can be directly applicable to some data of mesh (vertices, polygons) and I have asked if the similar solution is hidden in API for UVs. No, ok. Then we can collect data into own array.

Why I think accessing UVs through the wrapper is not efficient? Simply because I care about tiny performance bits too after I had practice with asm coding :) 
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.125 seconds.