The issue is that such things as disabled/hidden are UI states and not guaranteed to be accurate at any given time. If the parameter interface hasn't had to display that node yet then its state is going to be unclear. You'll want to call hou.OpNode.updateParmStates() before checking the value which should give you your expected result.
https://www.sidefx.com/docs/houdini/hom/hou/OpNode.html#cooking [www.sidefx.com]
Found 1091 posts.
Search results Show results as topic list.
Technical Discussion » Parameter's (isDisabled) of nodes created using Python
- graham
- 1906 posts
- Online
Technical Discussion » Reference Copy with Python .
- graham
- 1906 posts
- Online
I just mean you need to set the function parameters that would cause it to create a reference copy:
geo = hou.node("/obj/geo1") xform_to_reference = geo.node("transform1") geo.copyItems([xform_to_reference], channel_reference_originals=True)
Technical Discussion » Reference Copy with Python .
- graham
- 1906 posts
- Online
You need to use hou.Node.copyItems() with the requisite parameters set:
https://www.sidefx.com/docs/houdini/hom/hou/Node.html#adding-and-removing [www.sidefx.com]
https://www.sidefx.com/docs/houdini/hom/hou/Node.html#adding-and-removing [www.sidefx.com]
Technical Discussion » Can not get HDA Section 'Contents.gz'
- graham
- 1906 posts
- Online
The issue here is that for whatever reason the hou.HDASection.contents() functions can't take its arg as a keyword argument, despite the docs saying so. Passing the enum directly will work
This does show up randomly on occasion and I would suggest submitting a bug to have it properly fixed.
print(n.type().definition().sections()['Contents.gz'].contents(hou.compressionType.Gzip)) ......
This does show up randomly on occasion and I would suggest submitting a bug to have it properly fixed.
Technical Discussion » How to modify HDA context visibility with python?
- graham
- 1906 posts
- Online
This post might be helpful as things don't seem to have changed and any creation of HDAs via Python does not generate the default tool by default: https://www.sidefx.com/forum/topic/85634/ [www.sidefx.com]
To basically change things after the fact you're pretty much forced to take the contents of the Tools.shelf section, parse the XML into a structure you can manipulate, add/modify whatever settings you want, then set the resulting data back to the definition.
To basically change things after the fact you're pretty much forced to take the contents of the Tools.shelf section, parse the XML into a structure you can manipulate, add/modify whatever settings you want, then set the resulting data back to the definition.
Technical Discussion » Get all parameters of a node - python
- graham
- 1906 posts
- Online
Technical Discussion » How to identify Factory Nodes shipped with Houdini?
- graham
- 1906 posts
- Online
There's no super simple and straightforward way, but it's doable. Everything revolves around hou.OpNodeType and whether it's a digital asset definition, as well as the hou.nodeTypeSource value.
- Check if the node type has a non-None definition (hou.OpNodeType.definition()). If it is not none then the node type is an HDA. From there you can basically determine if the hou.HDADefinition.libraryFilePath() starts with the value of $HFS and is thus inside the install directory and is shipped with Houdini. If you want to be more specific and say tell if something is shipped as a "package" like SideFXLabs, kinefx, etc, you could be more specific and check that it starts with $HH or $HFS/packages to determine how it's included in the Houdini install.
- If something isn't a digital asset then that basically means it's a compiled node. You can get the return value of hou.OpNodeType.source() and compare that to the enum values.
- hou.nodeTypeSource.Internal generally means that the operator is defined internally in one of Houdini's libraries and a call to hou.OpNodeType.sourcePath() will return "Internal".
- A custom compiled operator will generally give you hou.nodeTypeSource.CompiledCode and sourcePath() will point to the actual file on disk.
There are some other possible things I think, usually to do with compiled shader stuff (other enum values for hou.nodeTypeSource) but the above is general for most cases and I've used such logic before for determining the dependencies and sources.
- Check if the node type has a non-None definition (hou.OpNodeType.definition()). If it is not none then the node type is an HDA. From there you can basically determine if the hou.HDADefinition.libraryFilePath() starts with the value of $HFS and is thus inside the install directory and is shipped with Houdini. If you want to be more specific and say tell if something is shipped as a "package" like SideFXLabs, kinefx, etc, you could be more specific and check that it starts with $HH or $HFS/packages to determine how it's included in the Houdini install.
- If something isn't a digital asset then that basically means it's a compiled node. You can get the return value of hou.OpNodeType.source() and compare that to the enum values.
- hou.nodeTypeSource.Internal generally means that the operator is defined internally in one of Houdini's libraries and a call to hou.OpNodeType.sourcePath() will return "Internal".
- A custom compiled operator will generally give you hou.nodeTypeSource.CompiledCode and sourcePath() will point to the actual file on disk.
There are some other possible things I think, usually to do with compiled shader stuff (other enum values for hou.nodeTypeSource) but the above is general for most cases and I've used such logic before for determining the dependencies and sources.
Edited by graham - Nov. 13, 2023 11:18:10
Technical Discussion » soho_program and hdaModule
- graham
- 1906 posts
- Online
I usually just put the program code (eg. soho_program.py) under "Extra Files" and use that using the previously mentioned opdef:
opdef:Driver/test::1?soho_program.py
Technical Discussion » Creating Digital asset with rop geometry node.
- graham
- 1906 posts
- Online
Unfortunately this is entirely an issue with the ROP Deadline submission tooling in that it is pretty bad at what it lets you do. It totally doesn't understand the concept of digital assets so as you've found out you can't really create wrappers around Houdini nodes and get it to work. TOPs might be a better option, but I don't have much experience with using Deadline from there. Unless you're willing to write your own Deadline submission code you're probably stuck with using straight ROP nodes
Technical Discussion » How to pass a .py script to hython?
- graham
- 1906 posts
- Online
I think you'll need to provide an example of the file you're trying to run as Houdini on Windows seems to have no issues executing a passed in script for me.
Technical Discussion » Where does launcher look for env variables?
- graham
- 1906 posts
- Online
The launcher can only support configurations specified in standard Houdini known locations, which basically means things under $HOUDINI_USER_PREF_DIR. Since other locations like $HSITE rely on vars being set already they won't generally work.
houdini.env will certainly be picked up, though its usefulness is restricted to things that actually work being set within it. If you have packages (or symlinks to things) under $HOUDINI_USER_PREF_DIR/packages then those will be found as well.
houdini.env will certainly be picked up, though its usefulness is restricted to things that actually work being set within it. If you have packages (or symlinks to things) under $HOUDINI_USER_PREF_DIR/packages then those will be found as well.
Technical Discussion » How to I read a key-value dictionary from an expression?
- graham
- 1906 posts
- Online
JohnFannyYou can set the hou.Parm directly with a dictionary, however all the keys and values will need to be strings.
Hi, do you know how to do the reverse? I mean write the dictionary with python?
hou.parm('/obj/subnet1/newparameter').set({"key1": "value1", "key2": "value2"})
Technical Discussion » Unittesting callbacks on a hda issues and questions
- graham
- 1906 posts
- Online
So the problem with your hip file, and tests assuming that they matching what this is doing, is that when you set a parameter via Python (or hscript) it doesn't actually cause the parameter callback to execute: you need to call hou.Parm.PressButton() to execute it. Annoyingly there is no kwarg on set() that allows you to trigger it in one go like the hscript opparm -C flag.
In terms of the issue with hou.Parm.pressButton() being lame and not helpful for discerning if anything happened I would probably forgo any attempts at using it. If it were me I would have things set up so that my callback was calling into the PythonModule (or I guess it could just be importing and calling all at once) such that to "test" it I would just call the function in the HDA module directly.
To ensure nobody messes with the callback code I'd probably access the parameter template and validate the code it's running is what I expect and that the language is set to Python. Not necessarily ideal but that's how I'd just do this call. Alternatively depending on what the callback is calling into, you could maybe just mock that, actually run the callback, and validate it was called with the expected args.
In terms of the issue with hou.Parm.pressButton() being lame and not helpful for discerning if anything happened I would probably forgo any attempts at using it. If it were me I would have things set up so that my callback was calling into the PythonModule (or I guess it could just be importing and calling all at once) such that to "test" it I would just call the function in the HDA module directly.
To ensure nobody messes with the callback code I'd probably access the parameter template and validate the code it's running is what I expect and that the language is set to Python. Not necessarily ideal but that's how I'd just do this call. Alternatively depending on what the callback is calling into, you could maybe just mock that, actually run the callback, and validate it was called with the expected args.
Technical Discussion » Unittesting callbacks on a hda issues and questions
- graham
- 1906 posts
- Online
I think you'll probably need to provide an example file of what you're trying to do since there should be no issue running callbacks via non-graphical Houdini and a quick test results in the expected behavior.
In terms of catching errors related to pressButton(), you'll never be able to. While calling it is done in Python, there's no guarantee that the callback is executing Python so there's no real expectation that any errors experienced during the callback would bubble up as something useful. It's mildly inconvenient that it doesn't throw some general exception like hou.OperationFailed when something seems to go wrong though.
In terms of catching errors related to pressButton(), you'll never be able to. While calling it is done in Python, there's no guarantee that the callback is executing Python so there's no real expectation that any errors experienced during the callback would bubble up as something useful. It's mildly inconvenient that it doesn't throw some general exception like hou.OperationFailed when something seems to go wrong though.
Technical Discussion » How to read custom variable in node?
- graham
- 1906 posts
- Online
Since you're creating the attribute in VEX you need to manually create a mapping between the parameter and a variable:
That being said, PolyExtrude won't accept a local variable in that parameter so even if your variable was correctly set up it would throw a warning. In your case you could do something like set the Distance to 1 and use your attribute as the Distance Scale in the Local Attributes tab.
addvariablename(0, "h", "MYVAR");
That being said, PolyExtrude won't accept a local variable in that parameter so even if your variable was correctly set up it would throw a warning. In your case you could do something like set the Distance to 1 and use your attribute as the Distance Scale in the Local Attributes tab.
Houdini Indie and Apprentice » Hiding nodes in tab menu?
- graham
- 1906 posts
- Online
Yeah, those ones look to be defined in specific .shelf files in $HH/toolbar so there's not much that can be done about them other than making copies of the tool definitions and trying to remove all their context settings to not show up.
Houdini Indie and Apprentice » Hiding nodes in tab menu?
- graham
- 1906 posts
- Online
Annoyingly the "Stereo Camera" labeled tool is for Object/sterocamrig and the "Stereo Camera Template" tool is Object/stereocam.
The easiest way to find the offical name of a node (node type name) is by instantiating it and checking the MMB info:
.
You could also drag the node into a Python Shell and run the following:
You can also generally infer the name based on the node naming when you create one as it's usually the "{node type name}{some digit}".
All that being said, sometimes it's not easy/possible to hide things in the Tab Menu as they may be set up as macros to create one or mode nodes with certain settings and the tools aren't bound directly to an operator name so ophiding things won't work
The easiest way to find the offical name of a node (node type name) is by instantiating it and checking the MMB info:
.
You could also drag the node into a Python Shell and run the following:
>>> hou.node('/obj/stereocamrig1').type().name() 'stereocamrig'
You can also generally infer the name based on the node naming when you create one as it's usually the "{node type name}{some digit}".
All that being said, sometimes it's not easy/possible to hide things in the Tab Menu as they may be set up as macros to create one or mode nodes with certain settings and the tools aren't bound directly to an operator name so ophiding things won't work
Technical Discussion » Forcing Python node to recook when its dependencies change
- graham
- 1906 posts
- Online
AnsonSavageBYUNot sure how you've got it set up, but it seems to work for me okay. See attached file where I've put it all in the compute wrangle and am using the detail() expression pointing to it without issues.
I'm experiencing two issues: if I have the camera reference the new focal length in a detail attribute, this creates infinite recursion (I guess when the detail attribute changes, the camera changes, which causes the Python node to cook again which recooks the node the computes the new focal length...)
Also you should be able to fold all the 2nd input stuff into the same wrangle as it's not doing anything terribly complex.
Houdini Lounge » Houdini 16.0 download
- graham
- 1906 posts
- Online
You should be able to find older version builds on the SideFX ftp server: ftp.sidefx.com
Technical Discussion » Forcing Python node to recook when its dependencies change
- graham
- 1906 posts
- Online
AnsonSavageBYUThanks for the hip file! From looking at it, you're running into essentially an infinitely recursive situation, though Houdini is silently not doing anything or warning you about it...graham
So this should work (and does in a quick test scene I made) so you might have to provide an example file to help see why it's not recooking on changes.
Without seeing the scene, my only real thought is that whatever node chain your HDA is displaying isn't involved with the Python SOP so it has no reason to recook.
Hi! Here's my HIP file! The main reason I'm using Python is because I want to get the global orientation of the Camera, after parenting and constraints and everything like that. If there's a way to do this with Vex, even better.Image Not Found
Because you're evaluating the focal parm in your Python SOP and then down the chain trying to set that parm again, it's causing a bunch of issues. At least in the hip file posted you're not actually doing anything with that "current" value anywhere, just printing for I'm guessing debug purposes? If you get rid of that (in the get data node and compute nodes) the problem mostly solves itself. That said, using that other Python SOP to set a parameter value during cook is also a very bad idea. A more proper solution would be to have the focal parameter on the camera just use a detail() expression to grab the computed value from the compute node.
You should also be able to easily grab the transform matrix in VEX without doing any Python at all using optransform() to get the matrix and then getting the position and rotation matrix from that instead of relying on the Python node to provide it.
Edited by graham - May 22, 2023 20:06:22
-
- Quick Links