Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    PoseMorph tag always increases GetDirty() counter

    SDK Help
    0
    13
    1.5k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H
      Helper
      last edited by

      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=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?

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        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).

        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          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.

          1 Reply Last reply Reply Quote 0
          • H
            Helper
            last edited by

            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 🙂

            1 Reply Last reply Reply Quote 0
            • H
              Helper
              last edited by

              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

              1 Reply Last reply Reply Quote 0
              • H
                Helper
                last edited by

                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

                1 Reply Last reply Reply Quote 0
                • H
                  Helper
                  last edited by

                  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).

                  1 Reply Last reply Reply Quote 0
                  • H
                    Helper
                    last edited by

                    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

                    1 Reply Last reply Reply Quote 0
                    • H
                      Helper
                      last edited by

                      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?

                      1 Reply Last reply Reply Quote 0
                      • H
                        Helper
                        last edited by

                        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, Riccardo

                        PS: 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.

                        1 Reply Last reply Reply Quote 0
                        • H
                          Helper
                          last edited by

                          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 🙂

                          1 Reply Last reply Reply Quote 0
                          • First post
                            Last post