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 09:53, xxxxxxxx wrote:

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

      1 Reply Last reply Reply Quote 0
      • 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