SOLVED Exporting data from Takes to a file

Hi,
I'm looking for a way to export info about objects, disabled for rendering, from take system, and use it later. I got a scene with hundreds of different viewpoints, each in separate take. If there are objects obstructing camera view, for that viewpoint, they I hide them for each take. That works great, and I'm big fan of Take System. The issue starts as soon as I want to bring updated mesh into my scene. As soon as the old mesh is deleted, and new mesh imported to the scene - all my references to previously hidden objects are gone (even the new mesh got identical hierarchy and names). As I understand Take Systems uses pointer to the scene node, rather than name of the object, which of course make sense.
To avoid hours of extra work every time when I bring updated mesh to c4d, to go thru all viewpoint and re-hide previously hidden objects, I'm looking for a solution to save info about hidden objects for each take, and then with the new mesh, just re-generate it in Python.
I checked all take examples on GitHub, as well as this forum, but was unable to find anything helpful for the task.

Can you please help me with this problem?
Best regards,
Tomasz

hi,

@futurium said in Exporting data from Takes to a file:

nodePositionAbs = c4d.DescID ( c4d.ID_BASEOBJECT_REL_POSITION)

This is not the correct definition for the parameter. The x position is a two level DescID made of two descLevel.

    nodePositionAbs  = c4d.DescID ( c4d.DescLevel(c4d.ID_BASEOBJECT_REL_POSITION), c4d.DescLevel(c4d.VECTOR_X))

But to print out the Values, you need to access only the first level of the parameter. You will retrieve a Vector that should contain all the values X, Y and Z.

    nodePositionAbs2 = c4d.DescID(nodePositionAbs[0])
 #......
  print ("take name", currentTake.GetName(), "node found", override.GetName(), "original object", override.GetSceneNode().GetName(), "position",  override[nodePositionAbs2])

Cheers,
Manuel

Hi,

Basically, you are trying to replace object that are acting like proxy and you want to replace them with a highpoly object?

Do you want to to it object by object or plane to have a list of objects? Having a list of object, you would need to identify each object and identifying them with their name is not the right/good solution. You would need to identify them with a unique ID. That's more work of course.

I need to check if it's possible to replace an object by another one on the take system. Otherwise, you will need to copy those parameters from one object to another.

Of course, the parameter needs to exist on both objects. Do you plan to copy other things than display settings?

Cheers,
Manuel

Hi Manuel,
What I really need is a code snippet to travel thru all takes, list all nodes per take with visibility changed, as per the screenshot below.
https://i.imgur.com/qedKv2K.png
I'd like to also know if there is a way to find what else has been changed per object (like coordinates)
I already got a code to rebuild takes, from a text file, when the updated mesh is imported and replacing the current mesh on the scene, so that's the only part which I need to make the solution work 🙂
Best regards,
Tomasz

Hi,

Takes, just like BaseOverrides are Baselist2D. That mean you can use GetNext, GetPred, GetDown, GetUp. Moving inside its hierarchy is the same as moving inside the object's manager hierarchy.

Once you know that, you can navigate among the takes and check if the descid value is overridden and what the value is.
Let me know if something isn't clear or if you have more questions.

import c4d
from c4d import gui


# as Takes are BaseList2D, we can use GetNext, GetPred, GetUp, GetDown
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 main():
    takeData = doc.GetTakeData()
    
    visibilityDescID = c4d.DescID ( c4d.ID_BASEOBJECT_VISIBILITY_EDITOR)
    currentTake = takeData.GetMainTake()
    
    while currentTake:
        overrides = currentTake.GetOverrides()
        for override in overrides:
            descIDs = override.GetAllOverrideDescID()
            if visibilityDescID in descIDs:
                print ("take name", currentTake.GetName(), "node found", override.GetName(), "original object", override.GetSceneNode().GetName(), "value",  override[visibilityDescID])
                        
        currentTake = GetNextTake(currentTake)
        
        

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

Cheers,
Manuel

Hi Manuel,
Thank you. I'll test it and come back to you if I have any questions.
Best regards,
Tomasz

Hi Manuel,
I've tested your solution and it works like a charm 🙂 Thank you.
As a next step, I wanted to grab node transforms from takes. I tried with c4d.DescID(c4d.ID_BASEOBJECT_REL_POSITION), but I'm not able to get any data. Below is your code with added two extra lines to get the node position. I also attached a screenshot with details from one of the takes.

Can you please help with the problem?

import c4d
from c4d import gui


# as Takes are BaseList2D, we can use GetNext, GetPred, GetUp, GetDown
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 main():
    takeData = doc.GetTakeData()
    
    visibilityDescID = c4d.DescID ( c4d.ID_BASEOBJECT_VISIBILITY_EDITOR)
    nodePositionAbs  = c4d.DescID ( c4d.ID_BASEOBJECT_REL_POSITION)
    currentTake = takeData.GetMainTake()
    
    while currentTake:
        overrides = currentTake.GetOverrides()
        for override in overrides:
            descIDs = override.GetAllOverrideDescID()
            if visibilityDescID in descIDs:
                print ("take name", currentTake.GetName(), "node found", override.GetName(), "original object", override.GetSceneNode().GetName(), "value",  override[visibilityDescID])
            if nodePositionAbs in descIDs:
                print ("take name", currentTake.GetName(), "node found", override.GetName(), "original object", override.GetSceneNode().GetName(), "position",  override[nodePositionAbs])

                        
        currentTake = GetNextTake(currentTake)
        
        

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

Screenshot from one of the takes

hi,

@futurium said in Exporting data from Takes to a file:

nodePositionAbs = c4d.DescID ( c4d.ID_BASEOBJECT_REL_POSITION)

This is not the correct definition for the parameter. The x position is a two level DescID made of two descLevel.

    nodePositionAbs  = c4d.DescID ( c4d.DescLevel(c4d.ID_BASEOBJECT_REL_POSITION), c4d.DescLevel(c4d.VECTOR_X))

But to print out the Values, you need to access only the first level of the parameter. You will retrieve a Vector that should contain all the values X, Y and Z.

    nodePositionAbs2 = c4d.DescID(nodePositionAbs[0])
 #......
  print ("take name", currentTake.GetName(), "node found", override.GetName(), "original object", override.GetSceneNode().GetName(), "position",  override[nodePositionAbs2])

Cheers,
Manuel

Hi Manual,
This is exactly what I needed. Thank you very much.
Best regards,
Tomasz