Unable to set override in take
-
Hi, I am having difficulty generating take overrides with ‘FindOrAddOverrideParam()’. When I run my script it creates a set of takes with an override but no value.
My script does ‘work’ if I use ‘OverrideNode()’ instead, but this overrides all of the parameters for the given object, which is much more than I want or need.
My code runs from a Python tag and is activated by a user data button. The intention is to increment the user data by one for each child object.
Any assistance would be greatly appreciated.
import c4d def createTake(): # Get existing take structure take_data = doc.GetTakeData() main_take = take_data.GetMainTake() # Get Selector child objects obj = op.GetObject() # Create header take select_take = take_data.AddTake("Selector", main_take, None) select_take.SetName(obj.GetName()) child = obj.GetDown() #records original user value, used with OverrideNode() originalSelection = obj[c4d.ID_USERDATA,2] n = 1 while child: print (f"n{n} obj {child.GetName()}") childTake = take_data.AddTake("Selection", select_take, None) childTake.SetName(child.GetName()) obj[c4d.ID_USERDATA,2] = n #increment userdata, used with OverrideNode() descId = c4d.DescID(c4d.DescLevel(c4d.ID_USERDATA), c4d.DescLevel(2)) #childTake.OverrideNode(take_data, obj, False) overrideNode = childTake.FindOrAddOverrideParam(take_data, obj, descId, n) n = n + 1 child = child.GetNext() obj[c4d.ID_USERDATA,2] = originalSelection #restores original user value, used with OverrideNode() c4d.EventAdd() def message(msg_type, data): if msg_type == c4d.MSG_NOTIFY_EVENT: event_data = data['event_data'] if event_data['msg_id'] == c4d.MSG_DESCRIPTION_COMMAND: desc_id = event_data['msg_data']['id'] if desc_id[1].id == 5: # The ID of the User Data print ("Button Pressed") createTake() def main(): obj = op.GetObject() # Check if we already listen for message if not obj.FindEventNotification(doc, op, c4d.NOTIFY_EVENT_MESSAGE): obj.AddEventNotification(op, c4d.NOTIFY_EVENT_MESSAGE, 0, c4d.BaseContainer())
-
Hello @robpayne,
Welcome to the Maxon developers forum and its community, it is great to have you with us!
Getting Started
Before creating your next postings, we would recommend making yourself accustomed with our forum and support procedures. You did not do anything wrong, we point all new users to these rules.
- Forum Overview: Provides a broad overview of the fundamental structure and rules of this forum, such as the purpose of the different sub-forums or the fact that we will ban users who engage in hate speech or harassment.
- Support Procedures: Provides a more in detail overview of how we provide technical support for APIs here. This topic will tell you how to ask good questions and limits of our technical support.
- Forum Features: Provides an overview of the technical features of this forum, such as Markdown markup or file uploads.
It is strongly recommended to read the first two topics carefully, especially the section Support Procedures: Asking Questions.
About your First Question
Your question is lacking a bit in repeatability (see Support Procedures: Asking Questions) because you do not provide a scene.
The first thing I would do, is remove the fanciness here. I assume this is meant to be a Python Programming tag solution. You do sort of the right thing by using a button and
message()
instead of themain()
function which would run off-main thread. You are however still lacking a main thread check before you call yourcreateTake
. To learn more about threading restrictions in our Threading Manual. Also the fact that you hook with an event notification into the host of your tag so that can you can add and press the button there, does not make this more streamlined. It is fine to be fancy when everything runs, but I would avoid it when running into problems.I removed all the fluff from you code and ran it as a Script Manager script. The problem is then that I can only speculate about how your scene is meant to look like and what kind of parameter type
c4d.USERDATA, 2
is meant to be, I guess aBaseLink
? I can also only guess what your child loop is meant to do functionally, because there [USERDATA, 2] now seems to be an integer. The lineobj[c4d.ID_USERDATA,2] = n
is also not necessary but your comment somewhat implies that you are aware, but you should remove it. When I run your code within what I can guess, its output looks fine to me. IWith all that being said, the Take system can be hairy subject, so problems are not unusual, especially in the context of
FindOrAddOverrideParam
. You can find here multiple FindOrAddOverrideParam topics I answered in the past. A common trap is that users do not enable overrides in the UI as discussed here.Worth a look ar also our Python Take System examples.
When you require more help, please provide executable code/a scene and a clear explanation of what you consider to fail.
Cheers,
Ferdinand -
Hi @ferdinand , thank you for kindly informing me, and for your guidance.
I was able to achieve a working solution by simplifying. This Script Manager script:
- creates a cube
- creates a take
- creates an override with new width for the cube
import c4d def main() -> None: # Instantiate a cube – for test only obj = c4d.BaseObject(c4d.Ocube) doc.InsertObject(obj) # Get take structure takeData = doc.GetTakeData() mainTake = takeData.GetMainTake() #Insert new take newTake = takeData.AddTake("Test", mainTake, None) #Capture descID of paramater to override descID = c4d.DescID(c4d.DescLevel(c4d.PRIM_CUBE_LEN, c4d.DTYPE_VECTOR, 0), c4d.DescLevel(c4d.VECTOR_X,c4d.DTYPE_REAL,0)) #Set take override newTake.FindOrAddOverrideParam(takeData, obj, descID, 10) c4d.EventAdd() if __name__ == '__main__': main()
The problem I had before was my descID was improperly collected. I needed to specify datatypes, as is the case here.
Many thanks,
Rob -
Hey @robpayne that is great to hear, thank you for informing us!