SOLVED Take Manager not recording Material Tag changes when running Python script

Hi,

The Python code below creates a new take, then finds the object of interest in order to add a new material tag for the newly created take (only). The code adds the material tag, however it does not record the changes within the Take Manager under take named "TEST". Any idea what the issue might be ?

import c4d

# Main function
def main():
    doc.StartUndo()
    
    c4d.CallCommand(431000081) # Auto Take toggle on

    # Create needed take system variables
    take_data = doc.GetTakeData()
    main_take = take_data.GetMainTake()
    child_take = main_take.GetDown()
    if child_take is None:
        msg = "Create first child take to clone. Only one take should be present in the take manager at this time"
        raise RuntimeError(msg)

    # Create a new take & set it as active
    new_take = take_data.AddTake("", main_take, child_take)
    new_take.SetName("TEST")
    take_data.SetCurrentTake(new_take)
    c4d.EventAdd()

    # Find object of interest and create an empty material tag
    obj = doc.SearchObject('Body') # Find object
    tag = obj.MakeTag(c4d.Ttexture) # Create an empty Materials Tag within object

    # Find material and assign it to the tag
    mat = doc.SearchMaterial('Fine') # Find material within Material Manager
    tag.SetMaterial(mat) # Assign material to tag associated with object
    #tag[c4d.TEXTURETAG_MATERIAL]=mat #alternate code, not needed

    # Take Manager is not reflecting changes from above to the currently active take "TEST".
    #tag.AddTag(take_data,c4d.Ttexture,mat) # something I tried to solve this issue, however didn't work

    doc.AddUndo(c4d.UNDOTYPE_NEW,tag)
    doc.EndUndo()

    c4d.EventAdd()

# Execute main()
if __name__=='__main__':
    main()

hi,

depending on what you want to do, there are different solutions.

You may want to add the material tag on a specific take and the object could have no material tag by default. This is done using OverrideGroups.

The other way would be to create the tag and modify the value of the material field, but it is not the way it should be done

You can also find some usefull information about takes and material on this thread

import c4d

# Main function
def main():
    doc.StartUndo()

    c4d.CallCommand(431000081) # Auto Take toggle on

    # Create needed take system variables
    take_data = doc.GetTakeData()
    main_take = take_data.GetMainTake()
    child_take = main_take.GetDown()
    if child_take is None:
        msg = "Create first child take to clone. Only one take should be present in the take manager at this time"
        raise RuntimeError(msg)

    # Create a new take & set it as active
    new_take = take_data.AddTake("", main_take, child_take)
    if new_take is None:
        raise ValueError("Could not create a new take")

    new_take.SetName("TEST")


    # Find material and assign it to the tag
    mat = doc.SearchMaterial('Fine') # Find material within Material Manager
    if mat is None:
        raise ValueError("Could not find the material")

    # Find object of interest and create an empty material tag
    obj = doc.SearchObject('Body') # Find object
    if obj is None:
        raise ValueError("Could not find the Object")

    overrideGroup = new_take.AddOverrideGroup()
    if overrideGroup is None:
        raise ValueError("could not create the override Group")
    # Create the material tag for that group and assign the material to it
    overrideGroup.AddTag(take_data, c4d.Ttexture, mat)
    # Do not forget to add the object to the group
    overrideGroup.AddToGroup(take_data, obj)

    take_data.SetCurrentTake(new_take)

    doc.EndUndo()

    c4d.EventAdd()

# Execute main()
if __name__=='__main__':
    main()

hi,

depending on what you want to do, there are different solutions.

You may want to add the material tag on a specific take and the object could have no material tag by default. This is done using OverrideGroups.

The other way would be to create the tag and modify the value of the material field, but it is not the way it should be done

You can also find some usefull information about takes and material on this thread

import c4d

# Main function
def main():
    doc.StartUndo()

    c4d.CallCommand(431000081) # Auto Take toggle on

    # Create needed take system variables
    take_data = doc.GetTakeData()
    main_take = take_data.GetMainTake()
    child_take = main_take.GetDown()
    if child_take is None:
        msg = "Create first child take to clone. Only one take should be present in the take manager at this time"
        raise RuntimeError(msg)

    # Create a new take & set it as active
    new_take = take_data.AddTake("", main_take, child_take)
    if new_take is None:
        raise ValueError("Could not create a new take")

    new_take.SetName("TEST")


    # Find material and assign it to the tag
    mat = doc.SearchMaterial('Fine') # Find material within Material Manager
    if mat is None:
        raise ValueError("Could not find the material")

    # Find object of interest and create an empty material tag
    obj = doc.SearchObject('Body') # Find object
    if obj is None:
        raise ValueError("Could not find the Object")

    overrideGroup = new_take.AddOverrideGroup()
    if overrideGroup is None:
        raise ValueError("could not create the override Group")
    # Create the material tag for that group and assign the material to it
    overrideGroup.AddTag(take_data, c4d.Ttexture, mat)
    # Do not forget to add the object to the group
    overrideGroup.AddToGroup(take_data, obj)

    take_data.SetCurrentTake(new_take)

    doc.EndUndo()

    c4d.EventAdd()

# Execute main()
if __name__=='__main__':
    main()

Hello @cinamatic,

without any further questions or other postings, we will consider this topic as solved and flag it as such by Friday, 17/06/2022.

Thank you for your understanding,
Ferdinand