Iterate through Takes

On 14/12/2017 at 07:31, xxxxxxxx wrote:

i need some help with interacting with takedata.
Basically i want to iterate over the takes and fetch the userdata data under each take.
It would suffice i there is a way to select each of the (main) takes as the active take and then just fetch my desired userdata, since it changes with the take.

I am bit lost where to start, it would be nice if someone has an idea on this.

Update: I have an idea how i want to go on but i am a bit confused by the BaseTake.AutoTake function. 
What is the difference between node and undo ?

Thanks in advance!

On 15/12/2017 at 04:53, xxxxxxxx wrote:

Here is how to retrieve a userData by iterate over all takes and overrides.
The scene is pretty easy, A cube with an Real UserData, in first take value is 0.1 and in another one is 1.0

import c4d
def GetNextObject(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 main() :
    # Get all takes data from a documents
    td = doc.GetTakeData()
    # Get the Main (root) take
    take = td.GetMainTake()
    #iterate over each take
    while take:        
        # Get all overrides take
        overrides = take.GetOverrides()
        for override in overrides:
            dIdToMatch = c4d.DescID(c4d.DescLevel(c4d.ID_USERDATA, c4d.DTYPE_SUBCONTAINER, 0),c4d.DescLevel(1, c4d.DTYPE_REAL, 0))
            # Is override ?
            if override.IsOverriddenParam(dIdToMatch) :
                print "TakeName: {0} - Value: {1}".format(
                            override.GetParameter(dIdToMatch, c4d.DESCFLAGS_GET_0)
        # Go to the next take
        take = GetNextObject(take)
        print "-----------"
if __name__=='__main__':

If you didn't succes to get the correct full DescID wich wil be needed for Get/SetParameter you can do something like that

dIdToMatch = c4d.DescID(c4d.DescLevel(c4d.ID_USERDATA),c4d.DescLevel(1))
# Is override ?
if override.IsOverriddenParam(dIdToMatch) :
    # Get the correct DescID
    listDescid = override.GetAllOverrideDescID()
    for descID in listDescid:
        if dIdToMatch.IsPartOf(descID) :
            # Print the value
            print "TakeName: {0} - Value: {1}".format(
                        override.GetParameter(descID, c4d.DESCFLAGS_GET_0)

If you want more informations I suggest you to read C++ Manual of TakeSystem overview, and all his child manual (TakeData, BaseTake, BaseOverride).
You may also find some interesting example into the official github

About your second question. A node is an instance of a NodeData (which is the parent of object, tag, shader...) anything that store some DescID that can be overriden with the TakeSystem. So you pass two similar objects that have differents parameters(aka DescID) and it automaticly generate a take. You can find information into file from official github.

Hope it's help ! 🙂

On 15/12/2017 at 06:20, xxxxxxxx wrote:

Thanks that pushed me in the right direction !

I am still unsere about the undo and node parameter of the AutoTake function.
I thought it would add the differences between node and undo as overrides in the take, but i am not able to get a result with it.

On 15/12/2017 at 08:41, xxxxxxxx wrote:

Hi Eti,

the BaseTake::AutoTake() method basically requires the BaseList2D on which the override takes place and the BaseList2D representing the unchanged state with respect to the override. How are you using the Autotake in your code? Sharing a clarifying code snippet could be helpful to be more helpful.

Best, Riccardo

On 21/12/2017 at 08:44, xxxxxxxx wrote:

I wanted to use it to generate overrides for certain user data of an object. I found a more clean solution (at least in my opinion) by now, so i do not need any more assistance on this.

Thanks for clarifying AutoTake()!