Hi there, I'm working on a script to transfer (or copy) the overrides from a source object to a target one and it seems to be working if there is no overrides in sub-Takes.
Basically what the script does is a scan through all Takes starting from the first after the Main (takeData.GetMainTake().GetDown()
) and retrieves each override ID and value and it adds to the target object via FindOrAddOverrideParam()
.
But for any odd reason the result is not consistent if there are sub-Takes involved as it changes depending on which one is active before running the script, and in all cases, I would expect a perfect copy but that's not what's happening. I must be missing something here :/
My gut feeling says that the problem is related to the backup so I just tried forcing it via FindOverrideCounterPart()
but without success.
I'm sending a dummy file attached with a set of Takes just to show the problem I'm trying to describe here:
copy_overrides_to_another_object.c4d
This is the script that works with the file above:
import c4d
def GetNextTake(op):
if op == None: return None
if op.GetDown(): return op.GetDown()
while not op.GetNext() and op.GetUp(): op = op.GetUp()
return op.GetNext()
def getDescIdName(op, descID):
description = op.GetDescription(c4d.DESCFLAGS_DESC_0)
for bc, paramid, groupid in description:
if paramid == descID:
return bc[c4d.DESC_NAME]
def TransferTakeOverrides(srcObj, trgObj, takeData, currentTake):
while currentTake:
srcOverride = currentTake.FindOverride(takeData, srcObj)
if srcOverride is not None:
for descID in srcOverride.GetAllOverrideDescID():
# Get the backup node for the source override
backup, result = takeData.FindOverrideCounterPart(srcOverride, descID) # backup: The counterpart node // result: the Take
if backup is None:
raise RuntimeError("Failed to find the default override.")
# Get the backup value of the given Description ID
backupValue = backup.GetParameter(descID, c4d.DESCFLAGS_GET_0)
print(currentTake.GetName(), " DescID:", getDescIdName(srcObj,descID))
print(" --->",srcOverride.GetSceneNode().GetName())
print(" overr. value:", srcOverride.GetParameter(descID, c4d.DESCFLAGS_GET_0))
print(" backup value:", backupValue,"from", result.GetName())
# Get the override value
srcOverValue = srcOverride.GetParameter(descID, c4d.DESCFLAGS_GET_0)
# add override to the target object
trgOverride = currentTake.FindOrAddOverrideParam(takeData, trgObj, descID, srcOverValue)
# Get the backup node for the target override
trg_backup, trg_result = takeData.FindOverrideCounterPart(trgOverride, descID)
trg_backupValue = trg_backup.GetParameter(descID, c4d.DESCFLAGS_GET_0)
# force adding source backup value to the target backup take (just trying to fix the problem!)
trgBackup = trg_result.FindOrAddOverrideParam(takeData, trgObj, descID, backupValue)
trgBackup.UpdateSceneNode(takeData, descID)
trgOverride.UpdateSceneNode(takeData, descID)
print(" --->",trgOverride.GetSceneNode().GetName())
print(" overr. value:", trgOverride.GetParameter(descID, c4d.DESCFLAGS_GET_0))
print(" backup value:", trg_backupValue,"from", trg_result.GetName())
print(" ----------------")
currentTake = GetNextTake(currentTake)
print("======================================")
def main():
op = c4d.BaseObject(c4d.Ocube)
op[c4d.ID_BASELIST_NAME] = "trg_Cube"
doc.InsertObject(op)
objs = doc.GetObjects()
objs.reverse()
if len(objs) != 2: return
takeData = doc.GetTakeData()
currentTake = takeData.GetMainTake().GetDown()
TransferTakeOverrides(srcObj=objs[0], trgObj=objs[1], takeData=takeData, currentTake=currentTake)
c4d.EventAdd()
if __name__=='__main__':
main()