How do I put objects into the timeline?
-
Yes, that topic again... the last one devolved into a discussion on GetBranchInfo(), which was broken at that time but meanwhile works fine.
So: If I have an object somewhere (BaseList2D, I guess), which has a track, how can I make it appear in a timeline?
I tried the NBIT_TLxxx flags, which control the selection/folding state and allow me to hide an object, but there is no flag that determines that the object is in the timeline at all.
Essentially, I want to replicate the functionality of the context menu entry "Show Tracks"/"Show FCurve". What's the true code behind those?
The determining factor seems to be somewhere hidden. If I use "Show Tracks" on all objects/tags in the scene, then I can NBIT_TLxxx_HIDE the unwanted objects afterwards, but it doesn't seem to be possible to get to this initial visibility state in the first place (and also, any further use of "Show Tracks" restricts this visibility again to the selected objects).
Out of desperation, I may use the BranchInfo flags next, but I have no hope that I am even close to the solution.
Clarification: I am not looking for the iteration of objects, for the selection, or for the folding. Just for the method that will show the object/the track in timeline xxx.
-
Okay, perhaps my expectations are wrong anyway. I played around a little in the Timeline, and its re-ordering and hierarchical re-assigning seems impossible to achieve without a complete secondary object tree.
AFAICS there is no hint in the API that this secondary tree can be accessed in any way. This tree can be built including animatable objects that are not part of the Object Manager, e.g. Project->Dynamics, and shows tracks as entries. Plus, it is different for all timeline windows. And a manually changed object order in the timeline even survives the closing and re-opening of the window.
As the GetBranchInfo() traversing of the scene refers to the OM tree, I see that the timeline trees are completely hidden structures that can neither be read nor changed from a Python or C++ plugin/script. This explains at least why there is no controlling bit - the stuff going on behind the scenes seems far more complicated.
Unfortunately, this leaves me no choice than to use the menu functions, which I only can control with CallCommand() (e.g. switching on Automatic Mode, or Show Tracks), which again presents the problem that they only affect the last selected timeline, with no way of controlling the target window.
-
So, the only way I see so far is to switch on the Automatic Mode (which seems to build the timeline tree internally) and then Hide any element that I do not want to see. Manual Mode is impossible due to the lacking API functions.
This does prevent any of the reordering stuff you can do (allegedly) in Manual Mode, but fortunately I never used that anyway, so it's an acceptable loss.
Of course I still need to call some menu functions to switch on the Automatic Mode and switch off the "only animated" toggle. The rest of the timeline functionality may still work...
...now I just need to test whether the concept collides with Takes. -
(Marking this as solved now, as I finished the script I wanted, but I wouldn't mind if someone could confirm that there is no access at all to the Timeline elements, or present an alternative...)
-
Hello @Cairyn,
thank you for reaching out to us.
Clarification: I am not looking for the iteration of objects, for the selection, or for the folding. Just for the method that will show the object/the track in timeline xxx.
I wouldn't mind if someone could confirm that there is no access at all to the Timeline elements, or present an alternative...)
You can add
BaseList2D
to a Timeline Manger by simply adding aCTrack
to them. But you are probably after the special case where an object is being placed by drag and drop into a Timeline. This is a special case since the object has then no track. When you delete the last track of an object in a Timeline, then the object will be removed. This makes the drag and drop case a special case. Internally, the objects of a Timeline Manager are tracked in a list-like structure which is populated by traversing a document and events like object creation or drag and drop. It will automatically ingest allBaseList2D
that have a track (and remove such that do not have tracks anymore). Nodes without a track that have been dragged and dropped into a Timeline are added "manually" to that list without being deleted. This works as far as I understand with aGeMarker
being added to them. So technically, one might be able to replicate this in C++ by also adding that marker, but its content is not public and might carry other side effects.What I found out while playing around with tracks, is that one can add "fake" tracks by either completely making up a track id, which are then called just "track", or incomplete ids, e.g., for the position of an object. This could serve as a clean slate if desired but could also have side effects.
descId = c4d.DescID(c4d.DescLevel(c4d.ID_BASEOBJECT_REL_POSITION, c4d.DTYPE_VECTOR, 0)) track = c4d.CTrack(op, descId) op.InsertTrackSorted(track) c4d.EventAdd()
Preventing the object being removed from the Timeline when deleting its last track is not possible in Python. At least I do not see a way to do it at the moment.
Cheers,
Ferdinand