channel_list=hou.ChannelList()collection_name="test_collection"# g is any hou.Geometry with channel primitives.channel_list.addGeometryChannels(g,collection_name)hou.playbar.setChannelList(channel_list)# Mutable geometry in which to write modified channel primitives.output_geometry=hou.Geometry()defchannels_changed(channel_names,collection_name):print(f"Channels in {collection_name} were modified: ",channel_names)# Write the changed channels back in to channel primitives.hou.anim.mergeGeometryChannels(collection_name,output_geometry,channel_names)# Called whenever geometry channels added to the channel list are modified,# such as when they are edited in the Animation Editor.hou.anim.addGeometryChannelsChangedCallback(collection_name,channels_changed)
After reading the code example I still don't get it. The naming is so confusing... what is "collection" here? Does it have anything to do with channel group?
Not a lot. Geometry channels here just means that they're channels backed by geometry channel primitives. The "channel list" is the list of channels currently being worked on, it's what you see in the Animation Editor. When you add the channel primitives to the animation editor, you can give them a name, which the "collection_name" in this case. You can add multiple "collections" of the channel primitives to the "channel list" and they show up somewhat like different regular nodes.
I am starting to understand what channel primtives are.
animation-data stored on invisible primtives with hidden "attributes" that we can extract and make visible through both vex ("chprim_" functions) and python using the channellist and channelprim functions. this way we can store the animation to geometry without having to store the actual vertex-positions for each frame seems very convenient and saves a lot of diskspace when dealing with a lot of animations. It's something that I have been wanting for a while, so I would love to learn more about it.
now the example that Kodra posted shows an example on how to convert those primitives back to animation curves where we can modify them using the animation-editor again.
however, I believe the example is not altering the primitives themselves at the moment.
I personally get the error that the output_geometry was not defined. which makes sense, because it's created before the callback function. But there is an issue with writing back even if we were to add a proper geometry reference to the callback function.
a callback function is not executed from a python-sop I believe so all the geometry that we try to modify is read-only.
How can we after altering the animation curves, store the data back to channel-primitives? I believe that is what kodra's example tries to do. But using the callback doesn't work for me so far.
The most common usage right now is the APEX Animate state. It saves the geometry into a "data"/"stash" parameter on the SOP HDA, and inside, a Python SOP is used to merge the geometry from the data/stash parameter into its output.
It doesn't make a lot of sense to make a callback from a Python SOP because the node network needs to cook on the farm where there will not be any user interaction at all.