Recalculate Plugin Object Cache



  • Hello,

    I have a plugin object that contain an another plugin object, and I want to clone the cache of the child object into the parent object. the problem is when I make changes in the child object parameters the change is not updated immediately in the parent object until I select it.

    So , I thought to add a Python Tag to the parent object to trigger the Cache recalculation from the Python Tag.

    def GetVirtualObjects(self, op, hh):
    
        child = op.GetDown()
        if not op.GetDown() :
            return c4d.BaseObject(c4d.Onull)
    
        child_cache = child.GetCache()
        
        dirty = op.CheckCache(hh) or op.IsDirty(c4d.DIRTY_DATA)
        if not dirty :
            return op.GetCache(hh)
    
        ...
    

    Thanks.



  • Hi,

    I am not quite sure for what you are actually asking, but if you have two objects A and B, where the cache of A is dependent on B, you have to turn off (or more precisely not turn on) the cache optimization for A and incorporate the state of B in the evaluation of if the cache of A has to be rebuild or not (taking place in GetVirtualObjects). How you analyze B depends on what you want to do, you can use C4DAtom.GetDirty() on B in most cases and compare it against the last checksum value you have encountered and stored in A. In more exotic scenarios you might have to cache the known data of B in A and compare against this data on the next call of GVO.

    Cheers,
    zipit



  • Hi @mfersaoui, thanks for reaching out us.

    With regard to your request I would actually consider to use the GetAndCheckHierarchyClone() which should work out of the box.

    Something like this, should work

    	def GetVirtualObjects(self, op, hh):
    		child = op.GetDown()
    		if child is None:
    			print "Object is supposed at least a child"
    			return c4d.BaseObject(c4d.Onull)
    
    		dirty = op.CheckCache(hh) or op.IsDirty(c4d.DIRTY_DATA)
    		if not dirty :
    			return op.GetCache(hh)
    
    		resGCHC = op.GetAndCheckHierarchyClone(hh, child, c4d.HIERARCHYCLONEFLAGS_ASIS, True)
    
    		if resGCHC['dirty'] == True:
    			return resGCHC['clone']
    			
    


  • Hi @r_gigante, @zipit,

    I'm creating something like the following code. I tried to use the GetAndCheckHierarchyClone, this works but the cloner object became to slow to calculate. For this reason I used the following solution:

    def __init__(self):
            pass
            #self.SetOptimizeCache(True)
    
    def GetVirtualObjects(self, op, hh):
            instance = op.GetDown()
            if instance is None:
                return c4d.BaseObject(c4d.Onull)
    
            dirty = op.CheckCache(hh) or op.IsDirty(c4d.DIRTY_DATA)
            instance_dirty = instance.IsDirty(c4d.DIRTY_DATA)
            
            dirty |= instance_dirty
    
            if not dirty:
                return op.GetCache(hh)
    
            cloner = c4d.BaseObject(c4d.Onull)
    
            count = 3
            n = 0
    
            while n < count:
                instance.GetCache().GetClone().InsertUnder(cloner)
                n += 1
    
            cloner.Message(c4d.MSG_UPDATE)
    
            return cloner
    

    So, by just deactivating the SetOptimizeCache and cloning only the cache of the instance object the cloner object calculate is become to fast. The unique problem now is the cloner object is return the cache of previous modification on the instance object. This is perceptible only with bool parameters.
    Example:
    When I check a bool parameter of the instance object, the cloner return the result of the previous state of the bool parameter. but if I mouseover the cloner in the Viewport or I select it object manager this update the cloner object.

    Thanks



  • This post is deleted!


  • This post is deleted!

Log in to reply