I have some custom LOP HDas that when a certain attribute changes it should trigger a value change on some other attributes. I would want this to work with context options, so that if the context options change (or render clones use different contexts) that these dependent attributes are updated along from the parameter change callback.
I'm using the Callback Script attribute of the parameter currently:
What can I do for this to support updates to other parms from this parm to trigger some 'python callback' to evaluate the result? Would that only be feasible by using some python expression instead of a parm changed callback?
Context Options do not trigger parm changed script callback
980 8 3- colorbleed
- Member
- 20 posts
- Joined: Jan. 2024
- Offline
- tamte
- Member
- 8832 posts
- Joined: July 2007
- Offline
- colorbleed
- Member
- 20 posts
- Joined: Jan. 2024
- Offline
- mtucker
- Staff
- 4525 posts
- Joined: July 2005
- Offline
In what way do you want your HDA to change in response to the context option value change? The most robust way to do this is by using expressions on your HDA that reference the context option values to alter the behavior of the HDA on a per-cook basis. This is the _only_ thing you can do if you want to drive your HDA using "Edit Context Option" LOPs instead of using "global" context options (Edit -> Context Options).
But maybe you need to respond to context option changes with more drastic changes to your HDA (adding or removing parms, etc). And you are expecting these changes to be driven only by changes to the global context option state. In this case you can use a "context option change callback", `hou.addContextOptionChangeCallback`.
But maybe you need to respond to context option changes with more drastic changes to your HDA (adding or removing parms, etc). And you are expecting these changes to be driven only by changes to the global context option state. In this case you can use a "context option change callback", `hou.addContextOptionChangeCallback`.
- colorbleed
- Member
- 20 posts
- Joined: Jan. 2024
- Offline
Hi Mark,
In my particular case I have some parms on my node that define e.g. the "shot" and some "version" parameters for published content - and based on changes there another parm should update the actual filepath. (This filepath is computed using the other parameters via a Python function on our pipeline). If I understand correctly this should thus be doable by making the other parm just a Python expression?
If so, I'll have to look into that. Can the singular "Python expression" reference multiple other parameters on the same node just fine?
In my particular case I have some parms on my node that define e.g. the "shot" and some "version" parameters for published content - and based on changes there another parm should update the actual filepath. (This filepath is computed using the other parameters via a Python function on our pipeline). If I understand correctly this should thus be doable by making the other parm just a Python expression?
If so, I'll have to look into that. Can the singular "Python expression" reference multiple other parameters on the same node just fine?
- colorbleed
- Member
- 20 posts
- Joined: Jan. 2024
- Offline
- colorbleed
- Member
- 20 posts
- Joined: Jan. 2024
- Offline
This does seem to work, draft implementation for my end is here: https://github.com/ynput/ayon-houdini/pull/112 [github.com]
1. Lots of calls. I must admit that the expression callbacks gets called way more often than I had expected (like three times on average where I'd have expected it to trigger once) so I had to resort to some caching.
2. Detecting changes and triggering other changes Also, in some cases I would want to trigger something else (like e.g. updating some 'thumbnail' for the node itself) if the value changed from the previous value. But it seems that within the expression I can't easily check the 'current' or 'old' value from the last evaluation? (Evaluating the parm itself seems to introduce a cycle?) Any pointers there?
1. Lots of calls. I must admit that the expression callbacks gets called way more often than I had expected (like three times on average where I'd have expected it to trigger once) so I had to resort to some caching.
2. Detecting changes and triggering other changes Also, in some cases I would want to trigger something else (like e.g. updating some 'thumbnail' for the node itself) if the value changed from the previous value. But it seems that within the expression I can't easily check the 'current' or 'old' value from the last evaluation? (Evaluating the parm itself seems to introduce a cycle?) Any pointers there?
- mtucker
- Staff
- 4525 posts
- Joined: July 2005
- Offline
1. You say "expression callbacks"... Just to make sure I understand, you mean that the expressions get evaluated a lot, right? That is likely to happen as a result of showing the parameter dialog for the node.
2. You should really not be "doing things" as a result of evaluating expressions. The time to take actions is either during a cook (though this approach can also be difficult to get right), or most controllably, in response to a user action (like clicking a button). This is why Houdini nodes like File Cache have explicit buttons that the user has to press when they want to update the "state" of the node.
Taking the example of updating a thumbnail, you certainly don't want to create a thumbnail just because an expression is evaluated. And looking at the three node hip file in your video, even creating the thumbnail as part of the "cook" is probably not going to do what the user wants. This is because the first time you display the left hand node, the top node will cook and generate a thumbnail. Then when you display the second node, the top node will cook again, and generate a different thumbnail. And from that point on, switching between those two bottom node will no longer require the top node to cook, so the thumbnail will not be generated again.
So you could require the user to press a button on the top node to generate the thumbnail, or you could move the thumbnail generation to a separate node, and in your network put one "thumbnail" node on each of your two branches. Then you could do the thumbnail generation on cook, and you would have the advantage of being able to see both thumbnails at once...
Anyway, I'm really just guessing at what your planned overall workflow is, but hopefully this gives you some food for thought.
2. You should really not be "doing things" as a result of evaluating expressions. The time to take actions is either during a cook (though this approach can also be difficult to get right), or most controllably, in response to a user action (like clicking a button). This is why Houdini nodes like File Cache have explicit buttons that the user has to press when they want to update the "state" of the node.
Taking the example of updating a thumbnail, you certainly don't want to create a thumbnail just because an expression is evaluated. And looking at the three node hip file in your video, even creating the thumbnail as part of the "cook" is probably not going to do what the user wants. This is because the first time you display the left hand node, the top node will cook and generate a thumbnail. Then when you display the second node, the top node will cook again, and generate a different thumbnail. And from that point on, switching between those two bottom node will no longer require the top node to cook, so the thumbnail will not be generated again.
So you could require the user to press a button on the top node to generate the thumbnail, or you could move the thumbnail generation to a separate node, and in your network put one "thumbnail" node on each of your two branches. Then you could do the thumbnail generation on cook, and you would have the advantage of being able to see both thumbnails at once...
Anyway, I'm really just guessing at what your planned overall workflow is, but hopefully this gives you some food for thought.
- colorbleed
- Member
- 20 posts
- Joined: Jan. 2024
- Offline
> 1. You say "expression callbacks"... Just to make sure I understand, you mean that the expressions get evaluated a lot, right? That is likely to happen as a result of showing the parameter dialog for the node.
Correct. It may call the expression about 3-5 times.
> You should really not be "doing things" as a result of evaluating expressions.
Thanks - noted. I merely was replacing what was initially a 'callback' for which it seemed reasonable at the time.
Preferably I wanted so that if someone picked another asset or version to load that it'd update the thumbnail along. So I'd like it to respond to that without always having to click a button to refresh it.
Like you said, "on cook" also doesn't sound like the right approach. I may go back to making it an 'Update thumbnail' button for now until I have more sensible ideas on how to make this appear more 'live' to changes the artist might make to what they are loading.
Correct. It may call the expression about 3-5 times.
> You should really not be "doing things" as a result of evaluating expressions.
Thanks - noted. I merely was replacing what was initially a 'callback' for which it seemed reasonable at the time.
Preferably I wanted so that if someone picked another asset or version to load that it'd update the thumbnail along. So I'd like it to respond to that without always having to click a button to refresh it.
Like you said, "on cook" also doesn't sound like the right approach. I may go back to making it an 'Update thumbnail' button for now until I have more sensible ideas on how to make this appear more 'live' to changes the artist might make to what they are loading.
-
- Quick Links