Jump to content
chrisdunham95

Python in Houdini Question

Recommended Posts

Hello all, 

n = hou.node('/obj/geo1/box1')
f = hou.node('obj/geo1/file1')
f.setFirstInput(n)

- so this is a little python ive got so far which does as expected; connects my two nodes. The second action I want is to be able to 'disconnect' the nodes. Ive tried setting first input to a invalid input but ofcourse it just errors, and cannot find the 'removefirstinput' or 'disconnect' nodes function for python, 

Any help or link to where to find this stuff would be awesome,

Best

C

 

 

 

 

Share this post


Link to post
Share on other sites
Posted (edited)

Try using setInput() instead. (supplying None)

http://www.sidefx.com/docs/houdini/hom/hou/Node.html#setInput

Quote

If item_to_become_input is not None, connect the output connector of another node to an input connector of this node. Otherwise, disconnect anything connected to the input connector.

 

Edited by Atom
  • Like 1

Share this post


Link to post
Share on other sites

Hello all again, 

so I have a lil python script for diving into otl's/subnets and selecting a specific node (For using paint sops etc inside a otl). 

parm = hou.node("obj/geo1/subnet2/subnet1/paint1")    

parm.setCurrent(True, clear_all_selected=True)

 

- Works in the python shell fine. Now I'm trying to turn it into a button instead, 

parm = hou.node("obj/geo1/subnet2/subnet1/paint1")      
kwargs['node'].parm.setCurrent(True, clear_all_selected=True)    
 
- I was hoping this may work, but doesn't which I guess is perhaps I need to set my 'parm' elsewhere in the otl and then just use my second line in the button to call it in - but wondered if anyone could clear this up for me? (Or is the syntax etc different on buttons or inside a hda/otl to using the python shell) 
 
Thanks 
C :)

 

 

Share this post


Link to post
Share on other sites
Posted (edited)

so on your button parameter make sure Callback Script language is set to python (obviously ;) )

and a single line like this works just fine

kwargs['node'].node('paint1').setCurrent(True, True)

Why does that work? hou.Node.node() does accept relative paths and since kwargs['node'] returns the current node we can find the paint node relative to it

 

Edit: oh and if your paint is inside a subnet (that lives inside the subnet your pressing the button on) change to node('subnet1/paint1')

Edited by 3dome
  • Like 1

Share this post


Link to post
Share on other sites
28 minutes ago, 3dome said:

so on your button parameter make sure Callback Script language is set to python (obviously ;) )

and a single line like this works just fine


kwargs['node'].node('paint1').setCurrent(True, True)

Why does that work? hou.Node.node() does accept relative paths and since kwargs['node'] returns the current node we can find the paint node relative to it

 

Edit: oh and if your paint is inside a subnet (that lives inside the subnet your pressing the button on) change to node('subnet1/paint1')

Ahhh awesome all makes way more sense, thanks a lot for the explanation Dominik! 

Share this post


Link to post
Share on other sites

Another Question - I keep managing to successfully write scripts in python that work in the shell - but then converting them into working buttons I'm not always understanding the logic. 

Does anyone know of any particular tutorials that follow this method or show you how one converts such script into buttons (OR I believe you can store scripts in your otl and call them into a button? ) 

Or any documentation, I'm just finding chunks within the Houdini docs but it doesn't always correlate together in a way I'm properly understanding. [ I guess I'm trying to work out the correct and best workflow for python > buttons etc.] 

Thanks Guys

C :)

 

 

 

 

 

 

Share this post


Link to post
Share on other sites
Posted (edited)

I don't know about any tutorials specific on this but I guess the main thing is with the shell you are working on a more loose level compared to python on an HDA where the "working area" is sort of defined. (hope that sentence makes sense :D )

The way I usually use Python with HDAs is indeed that in the Scripts Tab of the TypeProperties I create a PythonModule.

In there you can define entire functions the way you are used to.
For lack of a better example I just use parts of the one that is in front of me right now:

def editLockedHDA(self):
	input = self.inputs[0]
	input.allowEditingOfContents()
	
	newNode = input.createNode("null")
	newNode.setColor(hou.Color(0.5, 0.2, 0.8))

Then on a button I call this method with

kwargs['node'].hdaModule().editLockedHDA(kwargs['node'])

 

Cheers

 

EDIT: I'm not happy with the first sentence. You can still do things about everywhere in Houdini from the python Module of a HDA. I should say it's more likely that one wants to do something within the context of the HDA and the kwargs is a handy starting point. still a whacky sentence :wacko:

Edited by 3dome
  • Thanks 1

Share this post


Link to post
Share on other sites
20 minutes ago, 3dome said:

I don't know about any tutorials specific on this but I guess the main thing is with the shell you are working on a more loose level compared to python on an HDA where the "working area" is sort of defined. (hope that sentence makes sense :D )

The way I usually use Python with HDAs is indeed that in the Scripts Tab of the TypeProperties I create a PythonModule.

In there you can define entire functions the way you are used to.
For lack of a better example I just use parts of the one that is in front of me right now:


def editLockedHDA(self):
	input = self.inputs[0]
	input.allowEditingOfContents()
	
	newNode = input.createNode("null")
	newNode.setColor(hou.Color(0.5, 0.2, 0.8))

Then on a button I call this method with


kwargs['node'].hdaModule().editLockedHDA(kwargs['node'])

 

Cheers

Yeah that makes sense for sure! 

Ahhhh yeah that's exactly what I thought you could do! 

just wasn't sure how to go about it, but ive got it working based off your example huge thanks man! 

Share this post


Link to post
Share on other sites
Posted (edited)

So another quick question - 

I have a much larger script but keep getting errors on this one line which says; 

z = hou.evalParm('obj/Subnet1/number_parm')           - Getting the parameter value 

The script including this line works fine in the shell once again. But inside Type Properties > Scripts - then pressing the button its connected too gives me this error; 

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "opdef:/Object/CD_GameDev_Export?PythonModule", line 31, in removegeo
  File "C:/PROGRA~1/SIDEEF~1/HOUDIN~1.439/houdini/python2.7libs\hou.py", line 57496, in evalParm
    return _hou.evalParm(*args)
OperationFailed: The attempted operation failed.

 

- If I change my script from hou.evalParm to houd.parm it works perfectly, but I wanted the evaluated value of my parm rather than the parm string, can anyone lead me to where I'm going wrong? 

 

- Please ignore the above,  I found the issue my hou.evalParm line was missing a ' - which every other line had, silly me least I found the issue! :)

 

 

 

Edited by chrisdunham95
I WAS WRONG

Share this post


Link to post
Share on other sites

I have another python question, 

So I have a button which takes the user into the compositing network, to pair with that I'm trying to change the 'scene view' to 'compositor view' but cant seem to find much on this type of stuff done via python in buttons? anyone who could point me in any direction would be super useful :)! 

 

Share this post


Link to post
Share on other sites

this should do it:

hou.ui.paneTabOfType(hou.paneTabType.CompositorViewer).setIsCurrentTab()
(put this in the callback script - no need for module but feel free to put it wherever you want to. but then you might want to split it into 2 lines maybe for readability)

also here's the list of the types in case Scene and Comp is just the beginning ;)

http://www.sidefx.com/docs/houdini/hom/hou/paneTabType.html

 

  • Like 1

Share this post


Link to post
Share on other sites
Posted (edited)
On ‎25‎/‎05‎/‎2018 at 9:18 PM, 3dome said:

this should do it:

hou.ui.paneTabOfType(hou.paneTabType.CompositorViewer).setIsCurrentTab()
(put this in the callback script - no need for module but feel free to put it wherever you want to. but then you might want to split it into 2 lines maybe for readability)

also here's the list of the types in case Scene and Comp is just the beginning ;)

http://www.sidefx.com/docs/houdini/hom/hou/paneTabType.html

 

Ahhh fantastic thankyou once again man! Really really appreciated :) I have another small question, 

So I have a button which adds extra nodes inside my OTL. It also unlocks the OTL to allow it to create new nodes as my line below shows. 

- hou.node('../CD_Tool).allowEditingOfContents() 

I then want to add another line which re-locks the OTL - I tried using the end brackets of allowEditingofContents with true and false, but to no luck, the documentation doesn't seem to specify but I could be me making a simple mistake? 

Theirs the match current definition way but that resets the network inside the OTL also which I don't want to doo. 

 

So the Answer was hou.node("obj/CD_Tool").matchCurrentDefinition()   - Which Locks my otl for me, but doesn't seem to revert any nodes or values particularly which was my concern from the way it was explained via the documentation 

 

 

Edited by chrisdunham95
FIXED!

Share this post


Link to post
Share on other sites
1 hour ago, chrisdunham95 said:

 

So the Answer was hou.node("obj/CD_Tool").matchCurrentDefinition()   - Which Locks my otl for me, but doesn't seem to revert any nodes or values particularly which was my concern from the way it was explained via the documentation

careful here! it does revert all internal node changes but not the parameter values. 

I would not recommend it but if you want to re-lock that thing again and have all the extra(or deleted) nodes saved use updateFromNode(node).
 

Share this post


Link to post
Share on other sites
53 minutes ago, 3dome said:

careful here! it does revert all internal node changes but not the parameter values. 

I would not recommend it but if you want to re-lock that thing again and have all the extra(or deleted) nodes saved use updateFromNode(node).
 

Hmmmmmm, right that kind of makes sense. What kind of node changes? As ive tested it a few times and my new geo nodes being created remain fine, and the nodes I disconnect also remain fine (that's the only functionality my buttons require the unlock for) 

Ahhh okay ill take a look at that node see if that can replace it! Thanks man :D

 

Share this post


Link to post
Share on other sites

interesting. just ran tests myself and new nodes, bypasses and disconnected wires all get destroyed, unbypassed and reconnected. just as i expected since the function restores the otls contents as saved in the latest definition of it

Share this post


Link to post
Share on other sites
16 hours ago, 3dome said:

interesting. just ran tests myself and new nodes, bypasses and disconnected wires all get destroyed, unbypassed and reconnected. just as i expected since the function restores the otls contents as saved in the latest definition of it

Hmmmm, I just tested my tool again to check and still no new created nodes or connections made/disconnected go back to the defaults using my buttons.

- Is it perhaps because my tool is working at a obj level?

(soo I have my tool > multiple geo networks > inside geo networks is the geometry)

(the buttons create new geo networks/nulls and connect/disconnect them to other geo networks at that level - no sop changes) 

- which means that definition of the function will turn the sop's inside the geo networks back to default but not the geometry networks themselves? 

Share this post


Link to post
Share on other sites

its a bit confusing right now :D

so here if you click a button to add nodes inside the locked OTL, unlock it with the code below and then (for whatever reason) lock it again aka matchCurrentDefiniton, all change you made inside that OTL are reverted (unless the function is buggy in the build you use which I highly doubt, because then it would give the same behaviour when right click -> matchCurrentDefinition)

22 hours ago, chrisdunham95 said:

So I have a button which adds extra nodes inside my OTL. It also unlocks the OTL to allow it to create new nodes as my line below shows. 

- hou.node('../CD_Tool).allowEditingOfContents() 

I then want to add another line which re-locks the OTL

 

and here you talk about your OTL creates nodes in some other context and not inside of itself. Of course those nodes won't be deleted, etc but then I'm wondering why you want to allowEditingOfContents() in the first place

2 hours ago, chrisdunham95 said:

Hmmmm, I just tested my tool again to check and still no new created nodes or connections made/disconnected go back to the defaults using my buttons.

- Is it perhaps because my tool is working at a obj level?

(soo I have my tool > multiple geo networks > inside geo networks is the geometry)

(the buttons create new geo networks/nulls and connect/disconnect them to other geo networks at that level - no sop changes) 

- which means that definition of the function will turn the sop's inside the geo networks back to default but not the geometry networks themselves? 

 

Share this post


Link to post
Share on other sites

Hi guys,
is there a way for select a node inside an OTL via Python, without dive in ?

I have an OTL with this code piece of code:

...
geo = node.node('./OUT_both')
geo.setCurrent(1,1)
...

Doing in this way, Houdini dive in the OTL, is there a way for avoid this behaviour ?

Thanks

Share this post


Link to post
Share on other sites

have you tried geo.setSelected(1,1)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×