PoseMorph tag always increases GetDirty() counter
-
On 14/08/2017 at 10:07, xxxxxxxx wrote:
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=0As 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?
-
On 14/08/2017 at 11:38, xxxxxxxx wrote:
Originally posted by xxxxxxxx
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).
-
On 14/08/2017 at 11:42, xxxxxxxx wrote:
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. -
On 14/08/2017 at 12:13, xxxxxxxx wrote:
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 -
On 23/08/2017 at 09:41, xxxxxxxx wrote:
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
-
On 20/09/2017 at 13:40, xxxxxxxx wrote:
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 -
On 20/09/2017 at 14:09, xxxxxxxx wrote:
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). -
On 21/09/2017 at 03:11, xxxxxxxx wrote:
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
-
On 21/09/2017 at 05:36, xxxxxxxx wrote:
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?
-
On 27/09/2017 at 05:24, xxxxxxxx wrote:
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()
[URL-REMOVED]) 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, RiccardoPS: For the future I also warmly invite you to post questions on subjects different from the topic on a new thread.
[URL-REMOVED] @maxon: This section contained a non-resolving link which has been removed.
-
On 29/09/2017 at 08:30, xxxxxxxx wrote:
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