Shalinar Posted January 16, 2017 Share Posted January 16, 2017 Hi everyone, I'm trying to have my Python Module in my HDA place another node right below my asset on creation. So my OnCreation script runs my python module from disk, which has the following code: pos = first_node.position() second_pos = (pos[0], pos[1] - 2) second_node.setPosition(second_pos) This does nothing. The second node is always created near (0, 0) in the network editor. But if i run those lines in the Python shell in Houdini, it works just fine. So that tells me that the OnCreated scripts don't wait for the HDA to actually be placed into the scene before running, despite what the docs say (a problem I've run into before). My solution to this was to use hdefereval to wait to run the code until the event loop was idle. This shows promises of working, but I'm running into issues now. The code I'm trying is: pos = first_node.position() second_pos = (pos[0], pos[1] - 2) hdefereval.executeDeferred("second_node.setPosition(second_pos)") but the problem here is that when it goes to execute the code, the variables no longer exist, and the code fails because "Name 'second_node' is not defined". But I use a custom 123.py script every day that has the exact line hdefereval.executeDeferred("hou.hscript(code)") where "code" is a pre-defined variable, and hdefereval has no problem using that variable when it goes to execute. So I'm not really sure what the problem is here. What is the best way to move a node using Python? (and if you know how to get my hdefereval call to work, that'd be even better!) Thanks, ~Chris Quote Link to comment Share on other sites More sharing options...
f1480187 Posted January 17, 2017 Share Posted January 17, 2017 (edited) I think this stuff is done with tools. Check how the Sky Light tool was implemented. You don't need external tool to be installed with HDA and added to the user's shelf tab. Instead, go to the "Tool" tab (next to the "Scripts" where you are editing OnCreated) and here on "Script" tab you will see built-in creation tool. For example: import objecttoolutils objecttoolutils.genericTool(kwargs, '$HDA_NAME') The last line returns an actual node with position already set: node = objecttoolutils.genericTool(kwargs, '$HDA_NAME') print(node.position()) Here is a test script, without using position explicitly: import objecttoolutils node = objecttoolutils.genericTool(kwargs, '$HDA_NAME') null = node.createOutputNode('null') You can add this to make the output node selected and active, if you want: null.setCurrent(True, clear_all_selected=True) Edited January 17, 2017 by f1480187 Quote Link to comment Share on other sites More sharing options...
Shalinar Posted January 17, 2017 Author Share Posted January 17, 2017 Thanks F1! Experimenting with that now. I always wondered how the Tools tab was used. The documentation is pretty basic and doesn't address a lot of the advanced options for power users. Do you have a reference for this tab? My google-fu is weak here, since searching for the "tools" tab doesn't help much considering a lot of people use "tool" interchangeably with "node/asset/hda/otl". Quote Link to comment Share on other sites More sharing options...
f1480187 Posted January 17, 2017 Share Posted January 17, 2017 (edited) I guess, the tool is a script invoked right after click on tool's icon on shelf or tab-menu. There is bunch of useful data in local kwargs dictionary, and *toolutils modules creating stuff using it. Tool script precedes OnCreated event, which is called during node creation inside tool's script. You can add new tools to the list, they will be available for adding to the shelves. Like usual .xml ones. All *toolutils modules available in sources in $HH/python2.7libs/. They documented, you can read docstrings to get the basic idea. Variables used inside tool panel are not documented. Text search in $HH does not locate any places where they were defined, so I collected all different occurrences and printed their contents from the tool body: Custom Python OBJ test. name test_op label Test OP network Object Variable Prints as: ------------------------------------ $HDA_TABLE Object $HDA_NAME test_op $HDA_TABLE_AND_NAME Object/test_op $HDA_LABEL Test OP $HDA_ICON MISC_python $HDA_DEFAULT_TOOL object_test_op They are quite easy to understand, but I'm not sure if there is more of them. Edited January 17, 2017 by f1480187 Quote Link to comment Share on other sites More sharing options...
Shalinar Posted January 17, 2017 Author Share Posted January 17, 2017 Thank you, this worked perfectly. Time to go explore the *toolutils modules etc...! Quote Link to comment Share on other sites More sharing options...
elecstorm Posted April 27, 2017 Share Posted April 27, 2017 Hi! I have the same question. How can I get HDA position or position where it will be created in OnCreated Event? kwargs['node'].position() returns [0, 0] as expected. Quote Link to comment Share on other sites More sharing options...
bhouse Posted August 1, 2018 Share Posted August 1, 2018 (edited) On 4/27/2017 at 10:00 AM, elecstorm said: Hi! I have the same question. How can I get HDA position or position where it will be created in OnCreated Event? kwargs['node'].position() returns [0, 0] as expected. I know this is more than a year later, but if anyone is still wondering how to do this, I don't believe that it is directly possible to get a node's position OnCreated. However, you can get your cursor's position at the time of creation, which is usually close enough. # python code inside an OnCreated script # get current network pane net_editor = hou.ui.paneTabOfType(hou.paneTabType.NetworkEditor) # create your node myNode = hou.node(".").createNode("null", "my_node", 0, 0) # get cursor position position = net_editor.cursorPosition() # set position of node to cursor position myNode.setPosition(position) I use this to create nodes and connect outputs as desired. (Note that the position vector can be modified to set the node location to a position relative to your cursor location instead of directly on it.) import numpy as np # reference the created node createdNode = kwargs["node"] # get current network pane net_editor = hou.ui.paneTabOfType(hou.paneTabType.NetworkEditor) # create a child node of the created node # can just use createOutputNode if you only have 1 output and 1 input #childNode = createdNode.createOutputNode("null", "child_node") childNode = hou.node(".").createNode("null", "child_node", 0, 0) # for nodes with multiple inputs/outputs use setInputs # assign the 2nd output of the created node to the first input of the childNode childNode.setInput(0, createdNode, 1) # set position equal to cursor position minus a small amount # offset position down and to the right of cursor position position = np.subtract(net_editor.cursorPosition(), [-0.5,1]) # set childNode position childNode.setPosition(position) Edited August 2, 2018 by bhouse 6 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.