Array cache bit is not updated

On 17/04/2018 at 00:36, xxxxxxxx wrote:

User Information:
Cinema 4D Version:   R18 
Platform:   Windows  ;   
Language(s) :     C++  ;

---------
Hello.

First of all, I need to receive all hierarchy object changes whenever they happen, 
so I check the data/chache/matrix bits in a Dialog's CoreMessage EVMSG_DOCUMENTRECALCULATED.

I have a scene with an array and an instance as a child. The instance points to a polygon.
Whenever I change the object link of that instance, its data-bit is updated.

The problem is that I don't receive any bit update on the array that contains the instance. 
After I move the camera, the array cache bit is updated. 
Why do I have to move the camera to have the array's bit updated ?

Thank you for your time.

On 18/04/2018 at 09:59, xxxxxxxx wrote:

Hi Peterakos, thanks for writing us.

I've tried to replicate the issue you mentioned but I wasn't able in the end to. Actually the array's cache dirty counter is properly increased every time the instance points to a different object in the scene as well as the array instance's data dirty counter. At the same time changing the camera position doesn't produce any effect on the array's cache dirty counter.

Assuming a scene like:
\
 |-Plane
 |-Disc
 |-Array
|-ArrayInstance

and changing the pointed object in the array instance from disc to plane (or viceversa), produces on EVMSG_DOCUMENTRECALCULATED the following output:

  
Previous state:  
Plane  
 hdOb: 1 / hdMa: 1 / hdObH: 0 / hdAl: 3  
 dDa: 11 / dMa: 1 / dCa: 1 / dCh: 0  
Disc  
 hdOb: 1 / hdMa: 1 / hdObH: 0 / hdAl: 3  
 dDa: 15 / dMa: 1 / dCa: 1 / dCh: 0  
Array  
 hdOb: 2 / hdMa: 1 / hdObH: 1 / hdAl: 4  
 dDa: 7 / dMa: 1 / dCa: 2 / dCh: 0  
Array Instance  
 hdOb: 2 / hdMa: 1 / hdObH: 0 / hdAl: 3  
 dDa: 8 / dMa: 1 / dCa: 0 / dCh: 0  
Current state:  
Plane  
 hdOb: 1 / hdMa: 1 / hdObH: 0 / hdAl: 3  
 dDa: 11 / dMa: 1 / dCa: 1 / dCh: 0  
Disc  
 hdOb: 1 / hdMa: 1 / hdObH: 0 / hdAl: 3  
 dDa: 15 / dMa: 1 / dCa: 1 / dCh: 0  
Array  
 hdOb: 2 / hdMa: 1 / hdObH: 1 / hdAl: 4  
 dDa: 7 / dMa: 1 / dCa: 2 / dCh: 0  
Array Instance  
 hdOb: 2 / hdMa: 1 / hdObH: 0 / hdAl: 3  
 dDa: 8 / dMa: 1 / dCa: 0 / dCh: 0   

where:
hdOb  -> GetHDirty(HDIRTYFLAGS_OBJECT)
hdMa  -> GetHDirty(HDIRTYFLAGS_OBJECT_MATRIX)
hdObH -> GetHDirty(HDIRTYFLAGS_OBJECT_HIERARCHY)
hdAl  -> GetHDirty(HDIRTYFLAGS_ALL)

dDa   -> GetDirty(DIRTYFLAGS_DATA)
dMa   -> GetDirty(DIRTYFLAGS_MATRIX)
dCa   -> GetDirty(DIRTYFLAGS_CACHE)
dCh   -> GetDirty(DIRTYFLAGS_CHILDREN)

For the sake of completeness here you are with the meaningful part of the code used to test the behavior

  
 void SDKSupport_14186_Dialog::TraverseObjectAndCheckDirty(BaseObject *obj, String& res)  
 {  
     const String objName = obj->GetName();  
     const Int32 hDirtyObject =  obj->GetHDirty(HDIRTYFLAGS_OBJECT);  
     const Int32 hDirtyMatrix =  obj->GetHDirty(HDIRTYFLAGS_OBJECT_MATRIX);  
     const Int32 hDirtyObjectH =  obj->GetHDirty(HDIRTYFLAGS_OBJECT_HIERARCHY);  
     const Int32 hDirtyAll =  obj->GetHDirty(HDIRTYFLAGS_ALL);  
       
      const Int32 dirtyData =  obj->GetDirty(DIRTYFLAGS_DATA);  
      const Int32 dirtyMatrix =  obj->GetDirty(DIRTYFLAGS_MATRIX);  
      const Int32 dirtyCache =  obj->GetDirty(DIRTYFLAGS_CACHE);  
      const Int32 dirtyChildren =  obj->GetDirty(DIRTYFLAGS_CHILDREN);  
        
      res += "\n" + objName + " \n hdOb: " + String::IntToString(hDirtyObject) + " / hdMa: " + String::IntToString(hDirtyMatrix) + " / hdObH: " + String::IntToString(hDirtyObjectH)+ " / hdAl: " + String::IntToString(hDirtyAll) + "\n dDa: " + String::IntToString(dirtyData) + " / dMa: " + String::IntToString(dirtyMatrix) + " / dCa: " + String::IntToString(dirtyCache)+ " / dCh: " + String::IntToString(dirtyChildren);  
        
      if (obj->GetDown())  
      {  
          BaseObject* child = obj->GetDown();  
          TraverseObjectAndCheckDirty(child, res);  
      }  
        
      if (obj->GetNext())  
      {  
          BaseObject* brother = obj->GetNext();  
          TraverseObjectAndCheckDirty(brother, res);  
      }  
  }  
    
  Bool SDKSupport_14186_Dialog::CreateLayout()  
  {  
      _prevState = "";  
      SetTitle("SDKSupport_14186_Dialog");  
      AddMultiLineEditText(TextID_DLG_14186, BFH_SCALEFIT | BFV_TOP, SizePix(400), SizeChr(160));  
      return true;  
  }  
    
  Bool SDKSupport_14186_Dialog::CoreMessage(Int32 id, const BaseContainer &msg)  
  {  
      if (id == EVMSG_DOCUMENTRECALCULATED)  
      {  
          // attempt to retrieve the active document  
          GePrint("DocumentRecalculated");  
          BaseDocument* activeDoc = GetActiveDocument();  
          if(!activeDoc)  
              return false;  
            
          // attempt to retrieve the first object in the scene  
          BaseObject* first = activeDoc->GetFirstObject();  
          if (!first)  
              return false;  
            
          // traverse the scene and check dirty counters  
          String currentState;  
          TraverseObjectAndCheckDirty(first, currentState);  
            
          // present the previous and current dirty counter states  
          if (_prevState.Content())  
              SetString(TextID_DLG_14186, "Previous state:" + _prevState + "\nCurrent state:" + currentState);  
          else  
              SetString(TextID_DLG_14186, "Current state:" + currentState);  
            
          _prevState = currentState;  
            
      }  
      return true;  
  }  
  
  Bool SDKSupport_14186::Execute(BaseDocument* doc)  
  {  
      if (_dlg.IsOpen() == false)  
          _dlg.Open(DLG_TYPE_ASYNC, g_SDKSupport_13370_TestDialog, -1, -1, 400, SizeChr(160));  
      return true;  
  }  
    
  Bool SDKSupport_14186::RestoreLayout(void* secret)  
  {  
      return _dlg.RestoreLayout(g_SDKSupport_14186_Dialog, 0, secret);  
  }  

Hoping it could be of any help, give best.
Riccardo

On 19/04/2018 at 02:15, xxxxxxxx wrote:

Hello.

First of all, allow me to thank you for helping me !

The hierarchy is 
 |-Plane
 |-Disc
 |-Array
   |-Instance

Once I change the object link from instance pointing to a different polygon, I get a data counter increment only in Instance. The array doesn't have its bit increased.

Also in your example, the previous state and the current state are exactly the same, unless I miss something.

In my code I was checking only data, matrix and cache bits. I tried out the hierarchy dirty flags and HDIRTYFLAGS_OBJECT is getting increased in both the array and the instance. Why does it differ from data and cache bits ?

Thank you for your time !

On 19/04/2018 at 13:15, xxxxxxxx wrote:

My bad Peterakos, I wrongly copied and pasted a portion of the log not showing the behavior I was describing.
The right portion of the log is instead:

  
Previous state:  
Array   
 hdOb: 2 / hdMa: 1 / hdObH: 1 / hdAl: 5  
 dDa: 8 / dMa: 1 / **dCa: 2** / dCh: 0  
Array Instance   
 hdOb: 2 / hdMa: 1 / hdObH: 0 / hdAl: 3  
  **dDa: 11** / dMa: 1 / dCa: 2 / dCh: 0  
Disc   
 hdOb: 2 / hdMa: 1 / hdObH: 0 / hdAl: 4  
 dDa: 17 / dMa: 2 / dCa: 2 / dCh: 0  
Plane   
 hdOb: 2 / hdMa: 1 / hdObH: 0 / hdAl: 4  
 dDa: 15 / dMa: 2 / dCa: 3 / dCh: 0  
Current state:  
Array   
 hdOb: 3 / hdMa: 1 / hdObH: 1 / hdAl: 6  
 dDa: 8 / dMa: 1 / **dCa: 3** / dCh: 0  
Array Instance   
 hdOb: 3 / hdMa: 1 / hdObH: 0 / hdAl: 4  
  **dDa: 14** / dMa: 1 / dCa: 2 / dCh: 0  
Disc   
 hdOb: 2 / hdMa: 1 / hdObH: 0 / hdAl: 4  
 dDa: 17 / dMa: 2 / dCa: 2 / dCh: 0  
Plane   
 hdOb: 2 / hdMa: 1 / hdObH: 0 / hdAl: 4  
 dDa: 15 / dMa: 2 / dCa: 3 / dCh: 0  

Now it's clear that whilst the Array Instance's data dirty counter increases from 11 to 14 (due to the change of the linked object in the "Reference Object") the Array's cache dirty counter increases as well from 2 to 3( due to the change of the geometry pointed in the instance object which reflects in the change of the geometry cloned by the array)

With regard to the HDIRTYFLAGS_OBJECT since it's actually referring to the data dirty status of a hierarchy, an increase in a child is reflected in an increase of the parent. In our case since the array instance (child) sees an increase in its data dirty counter, due to the parent-child relationship, querying  the array for HDIRTYFLAGS_OBJECT returns at least the same increase.

Hoping it helps give best.
Riccardo

On 20/04/2018 at 02:04, xxxxxxxx wrote:

Thank you very much Riccardo !