python parameter expressions

   19782   14   0
User Avatar
Member
224 posts
Joined: June 2009
Offline
A few questions about parameter expressions using Python

First, it seems from the documentation that Houdini is heading away from hscript, and converting everything to python. Yet all the examples with parameter expressions still use hscript - it is ture that it is a bit shorter, but the python approach seems to be a bit more general, especially when it comes to local variables. As a newbie to Houdini, I don't really want to mix two languages, I would prefer to stick to python throughout - is this recommended?

Second, I have some problems with python parameter expressions. For example, lets say I create a simple box. If I set the language to hscript, then I can set the tx parameter to $F, and the box will move over time. If I now change the language to python, how can I get the same result. I have tried hou.expandString('$F'), but this does not work, any ideas why?

Cheers
Patrick
Patrick
User Avatar
Member
1926 posts
Joined: Nov. 2006
Offline
You certainly can use Python throughout, however you can be limited when it comes to trying to access things are are not implemented yet. As much as I love Python I still find it easier to use hscript expressions for certain simple things since keeping it simple is the way to be.

There is an existing bug where expandString/hscriptExpression don't properly become time dependent when using things like $F. However, if you want to keep it all Python then you can just use hou.frame() or hou.intFrame().
Graham Thompson, Technical Artist @ Rockstar Games
User Avatar
Member
9653 posts
Joined: July 2007
Offline
in my experience python for realtime expressions is way slower than hscript (at least was in 9.5) so that's the main reason i am still using hscript
Tomas Slancik
CG Supervisor
Framestore, NY
User Avatar
Member
224 posts
Joined: June 2009
Offline
Thanks for your replies, that clarifies things. Using hou.frame() or hou.intFrame() seems clearer anyway.

Another question regarding these parameter expressions. If I create a curve node, I can fill in the coordinates of the CVs. But what if I want to define the points with an expression?

If I type in some numbers, it works fine.
If I type hscript expressions with backticks it works fine.
But I can't seem to get any Python expressions to work.

How do I do this?

Cheers
Patrick
Patrick
User Avatar
Member
8147 posts
Joined: July 2005
Offline
backticks only work for hscript expressions. You can only use Python expressions in channels so you first have to keyframe the string parameter at frame 1.
User Avatar
Member
224 posts
Joined: June 2009
Offline
excellent - works fine
Patrick
User Avatar
Member
224 posts
Joined: June 2009
Offline
Another question - going one step further.

I am wondering how to access attributes from with a parameter expression. For example, lets say that I have a curve node, with some input that results in a bunch of point attributes. I I want my curve to go through these points, so I key frame the coords parameter, and then type in the following:

this_node = hou.pwd()
this_geom = this_node.geometry()
points = this_geom.pointAttribs()


However, I get an error on the second line, when I call the geometry() method. The error says ‘Infinite recursion in evaluation.’
Patrick
User Avatar
Member
8147 posts
Joined: July 2005
Offline
The output of a SOP node is its geometry. This geometry is created based upon the values of its parameters. So if you put an expression on the parameter that uses its geometry, you have infinite recursion.
User Avatar
Member
224 posts
Joined: June 2009
Offline
Ah… I see…
So when I look at the geometry spreadsheet for a particular node, that is actually the output of the node.

From a parameter expression, is there a way to get access to the attributes coming into a node, before they are processed by the node?

Or do you have to go to the nodes that you are getting your inputs from, and then call the geometry() method on those nodes.
Patrick
User Avatar
Member
1926 posts
Joined: Nov. 2006
Offline
You have to do it basically like you would using a point expression.

point(“../point1”, $PT, “Cd”, 0)

is equivalent to something like this

pwd().node(“../point1”).geometry().iterPoints().attribValue(“Cd”)

Of course you can replace node with pwd().inputs() and pwd().curPoint.number() with lvar(“PT”)
Graham Thompson, Technical Artist @ Rockstar Games
User Avatar
Member
224 posts
Joined: June 2009
Offline
Thanks graham. Ok - so to summarise for the benefit of other newbies - I can write Python parameter expressions to access both parameter values and attribute values.

For example, lets say I have two sphere SOPs and a curve SOP, and I want the latter to draw a line between the spheres. Then I can set a key on the coords parameter of the curve, and enter the Python parameter expression.

Using parameters:

n1 = pwd().node(“../sphere1”)
n2 = pwd().node(“../sphere2”)
pos1 = n1.evalParmTuple(“t”)
pos2 = n2.evalParmTuple(“t”)
return str(pos1) + “ ” + str(pos2)

Using attributes:

n1 = pwd().node(“../sphere1”)
n2 = pwd().node(“../sphere2”)
p1 = n1.geometry().points()
p2 = n2.geometry().points()
pos1 = p1.position()
pos2 = p2.position()
return str(pos1) + “ ” + str(pos2)

Now that I have figured out how to do it the complicated way, maybe someone can explain a more sensible way of drawing a line between two spheres I am sure there must be one….

Attachments:
python_expressions.hipnc (30.2 KB)

Patrick
User Avatar
Member
1926 posts
Joined: Nov. 2006
Offline
If you are looking to just draw a line between your two spheres I'd personally just merge them together and then add an Add SOP. If you turn on Delete Geometry But Keep the Points then on the Polygons tab put in * for Polygon 0. This will connect the two points with a line.
Graham Thompson, Technical Artist @ Rockstar Games
User Avatar
Member
224 posts
Joined: June 2009
Offline
thanks graham - that works great
Patrick
User Avatar
Member
8147 posts
Joined: July 2005
Offline
graham
…then on the Polygons tab put in * for Polygon 0. This will connect the two points with a line.

Or, instead, you can just click on the Polygons > By Group tab (instead of By Pattern). No need to enter anything in the group since an “empty” Group field there means everything.
User Avatar
Member
8147 posts
Joined: July 2005
Offline
graham
pwd().node(“../point1”).geometry()

Better yet, you can avoid hardcoding the node name and use instead:
pwd().inputs().geometry()
  • Quick Links