Hi @orestiskon I'm afraid there is nothing much more to say except what @zipit said.
Just a few notes:
- IsDirty is build to be used within a generator to check the current object only.
- GetDirty retrieves an integer value ta represents the dirty state of an object. It can be used to retrieve DirtyCount from outside.
Now take into consideration that the matrix object is kind of special since in reality, it creates nothing. But only feed some MoData and display them (but create no geometry). So how does an object that creates nothing can have its cache dirty? That's why it's up to the object that modifies the MoData (stored in its hidden tag ID_MOTAGDATA) to tell the matrix its content is dirty so other people that rely on this matrix know about it.
Additionally to what @zipit said (which will work in any case and it's preferred)
You can also consider checking for the dirtiness of the linked effector (but this will not consider Field).
Here an example in a Python Generator
import c4d
def CheckDirtyObj(obj, uuid, flag):
"""
Checks if an object by comparing the current Dirt Value with the one stored in the current op.BaseContainer
:param obj: The BaseList2D to retrieve the dirty state from.
:param uuid: The uuid used to store in the BaseContainer.
:param flag: The dirtiness flag to check for.
:return: True if the object is dirty, False otherwise.
"""
def GetBc():
"""
Retrieves a BC stored in the object BC, or create it if it does not exist yet
:return: A BaseContainer where value can be stored.
"""
bcId = 100001 # Make sure to obtain an UNIQUE ID in plugincafe.com
bc = op.GetDataInstance().GetContainerInstance(bcId)
if bc is None:
op.GetDataInstance().SetContainer(bcId, c4d.BaseContainer())
bc = op.GetDataInstance().GetContainerInstance(bcId)
if bc is None:
raise RuntimeError("Unable to create BaseContainer")
return bc
# Retrieves the stored value and the true DirtyCount
storedDirtyCount = GetBc().GetInt32(uuid, -1)
dirtyCount = obj.GetDirty(flag)
# Compares them, update stored value and return
if storedDirtyCount != dirtyCount:
GetBc().SetInt32(uuid, dirtyCount)
return True
return False
def main():
# Retrieve attached object and check if it's a matrix object
matrixObj = op[c4d.ID_USERDATA, 1]
if matrixObj is None or not matrixObj.CheckType(1018545):
return c4d.BaseObject(c4d.Onull)
# Retrieve the current cache
opCache = op.GetCache()
# We need a new object if one of the next reason are False
# The Cache is not valid
# The Parameter or Matrix of the current generator changed
# The Parameter or Matrix of the linked Matrix changed
needNewObj = opCache is None
needNewObj |= not opCache.IsAlive()
needNewObj |= op.IsDirty(c4d.DIRTYFLAGS_DATA | c4d.DIRTYFLAGS_MATRIX)
needNewObj |= CheckDirtyObj(matrixObj, 0, c4d.DIRTYFLAGS_DATA | c4d.DIRTYFLAGS_MATRIX)
# The Parameter or Matrix of effectors of the linked Matrix changed
objList = matrixObj[c4d.ID_MG_MOTIONGENERATOR_EFFECTORLIST]
for objIndex in xrange(objList.GetObjectCount()):
# If the effector is disabled in the effector list, skip it
if not objList.GetFlags(objIndex):
continue
# If the effector is not valid or not enabled, skip it
obj = objList.ObjectFromIndex(op.GetDocument(), objIndex)
if obj is None or not obj.IsAlive() or not obj.GetDeformMode():
continue
# Check for the dirty value stored (+1 because we already used ID 0 for the matrix object)
needNewObj |= CheckDirtyObj(obj, objIndex + 1, c4d.DIRTYFLAGS_DATA | c4d.DIRTYFLAGS_MATRIX)
if not needNewObj:
print "Old Obj"
return opCache
print "Generated New Object"
return c4d.BaseObject(c4d.Ocube)
Cheers,
Maxime.