Your browser does not seem to support JavaScript. As a result, your viewing experience will be diminished, and you have been placed in read-only mode.
Please download a browser that supports JavaScript, or enable it if it's disabled (i.e. NoScript).
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.
takeData.GetMainTake().GetDown()
FindOrAddOverrideParam()
FindOverrideCounterPart()
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()
Hi,
Finally found why by adding the backupvalue in the function FindOrAddOverrideParam. I yet, need to understand why because it should be optional even if this parameter is there for something. Maybe for one of those case but I am not sure.
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, ownerTake = 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) srcOverValue = srcOverride.GetParameter(descID, c4d.DESCFLAGS_GET_0) print(currentTake.GetName(), " DescID:", getDescIdName(srcObj,descID)) print(" --->",srcOverride.GetSceneNode().GetName()) print(" overr. value:", srcOverValue) print(" backup value:", backupValue,"from", ownerTake.GetName()) # Get the override value # add override to the target object trgOverride = currentTake.FindOrAddOverrideParam(takeData, trgObj, descID, srcOverValue, backupValue) trgOverride.UpdateSceneNode(takeData, descID) # Get the backup node for the target override trg_backup, trg_ownerTake = takeData.FindOverrideCounterPart(trgOverride, descID) trgOverValue = trgOverride.GetParameter(descID, c4d.DESCFLAGS_GET_0) trg_backupValue = trg_backup.GetParameter(descID, c4d.DESCFLAGS_GET_0) print(" --->",trgOverride.GetSceneNode().GetName()) print(" overr. value:", trgOverValue) print(" backup value:", trg_backupValue,"from", trg_ownerTake.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()
Cheers, Manuel
@m_magalhaes said in Copying Take Overrides from an object to another via Python not working properly:
adding the backupvalue
You are master! thanks my friend, it's working!