Object Data Plugin¶
Optimize Cache¶
On each call of a method, Python has to manage a lot of stuff so that the method can be called.
The method
ObjectData.GetVirtualObjects()
is called on each scene execution (one or multiple time per frame).
Once the ObjectData.GetVirtualObjects()
is called, the returned result is stored into the object cache.Usually to optimize things, instead of re-generating everything at each scene execution, the recommended method is to return the object previously returned: the one that is present in the cache.
Find an implementation example of such a GetVirtualObjects bellow:
def GetVirtualObjects(self, op, hh):
# dirty = True if a cache is dirty or if the data (any parameters) of the object changed.
dirty = op.CheckCache(hh) or op.IsDirty(c4d.DIRTYFLAGS_DATA)
# If nothing changed and a cache is present, return the cache
if not dirty:
return op.GetCache(hh)
# Creates a cube
return c4d.BaseObject(c4d.Ocube)
This is the common way how to return the cached object, so Cinema 4D and Python don’t need to build the whole object on each scene execution.
That saves a lot of time. But as it’s written previously, just calling the method needs some time, because Python has to register this call to the internal management system.
As a workaround of the previous issue, self.SetOptimizeCache(True) can be called to return the cache of your already-built object on a level which is much closer to the internal system than Python.
Internally it will perform the same code than the previous code but in C++.
Meaning that if a cache is available and no parameters changed, it will return the previously stored object in the cache, without the need to call and prepare any python stuff as everything will be handled in C++.
Just as a quick result, our internal benchmark using the first python code give around 89 fps, while using the SetOptimizeCache give around 278 fps.
Note
self.SetOptimizeCache has to be called from the __init__ method of your class since its checked just after it.
Find an implementation example of such a GetVirtualObjects bellow:
class CacheTest(plugins.ObjectData):
"""CacheTest Generator"""
def __init__(self):
self.SetOptimizeCache(True)
def GetVirtualObjects(self, op, hh):
"""
Since SetOptimizeCache is defined to True in the __init__ methods, the next lines are no longer needed.
Internally the checks will still happen but in C++ instead of Python, leading to a performance gain.
# dirty = True if a cache is dirty or if the data (any parameters) of the object changed.
dirty = op.CheckCache(hh) or op.IsDirty(c4d.DIRTYFLAGS_DATA)
# If nothing changed and a cache is present, return the cache
if not dirty:
return op.GetCache(hh)
"""
# Creates a cube
return c4d.BaseObject(c4d.Ocube)