Passing an Expression to a Group Node within Digital Asset

   4594   7   1
User Avatar
Member
2035 posts
Joined: Sept. 2015
Offline
Hello,

In the file attached I have a digital asset that has a group node parameter “promoted” up to the digital asset level.

One of them is the Filter Expression parameter.

In that parameter I can enter an expression like
lvar('PT') < 15
directly into the group node parameter. ( When it's not part of an asset in which it's being referenced/controlled )

However, when I try to enter the same expression at the digital asset level it errors out.

If I don't use an expression and just use the parameter slider at the asset level, that value will get reflected as expected within the group node parameter itself that is being referenced.

It's only when I try to use an expression that I run into problems.

Not sure if I have to make the digital asset differently or maybe digital assets were not intended to be used in the way I am trying?

Feedback is appreciated - Thanks.
Edited by BabaJ - July 25, 2016 16:14:56

Attachments:
Use expression for group relative reference.hiplc (101.9 KB)

User Avatar
Member
402 posts
Joined: June 2014
Offline
Hi there,

Thanks for posting that one up, it isn't something I had ever tried out before. Turns out that the answer was (again), more Python [docs.python.org] than houdini. Just reference your string parameter (the expression) on the digital asset inside an eval():

So this would be the expression in the group SOP:

eval(hou.parm("../my_hda_expression").eval())

Hope that's what you were thinking of
Edited by friedasparagus - July 26, 2016 04:38:44
Henry Dean
User Avatar
Member
2035 posts
Joined: Sept. 2015
Offline
Hi fried,

Thanks for the suggestion.

I tried this and several versions of that, and it still doesn't work.

Maybe I don't understand what it is your suggesting.

I tried using different expression like :

a = 3
b = 2
c = a + b
return c

… in the “controling” paramter at the digital asset level…and the group sop parameter reflects the result ( without your suggestion ).

It just seems it doesn't like
lvar('PT') < 15
or variations of it.

User Avatar
Member
402 posts
Joined: June 2014
Offline
The reason why the first one is working is because you're giving houdini everything it needs to evaluate the expression i.e. you're defining all of the variables involved.

The trouble with using lvar('PT') is that the node in which the expression evaluates needs to be iterating over the geometry's components (points, prims, vertices) to make sense of the local variable ‘PT’.

In this expression:
eval(hou.parm("../my_hda_expression").eval())

the hou.parm(“../my_hda_expression”).eval() reads the parameter you set at ‘hda level’ as a string

the outer eval(…) then executes that string as an expression in the context of the group node (where PT makes sense to houdini)

Arg, did that make any sense?! maybe this little example helps…
Edited by friedasparagus - July 26, 2016 08:57:22

Attachments:
hda_expression_test.hipnc (71.3 KB)

Henry Dean
User Avatar
Member
2035 posts
Joined: Sept. 2015
Offline
Hi fried,

Yeah as I was thinking about it I thought that might be the reason - at least something like that

Although I still can't get it to work.

I'm using ( in the same way as you did in your example ) :
eval(hou.parm("../../filter").eval())

so the only difference between yours and mine is that the parameter I'm referring too is up one more level hence the extra
../
and the name of the parameter is different -
filter
.

The errors I am getting is :

Error: Unable to evaluate expression (
Traceback (most recent call last):
File “<stdin>”, line 1, in <module>
TypeError: eval() arg 1 must be a string or code object
(/obj/mygroup_test1/Inside_Border_Container/group1/filter)).

..and that same error is repeated many times which tells me it's running over all the points but can't evaluate because it's saying
arg 1 must be a string or code object

I know I'm referring to the right parameter because if I do a straight copy as relative reference I get:

ch("../../filter")

I even tried an absolute path just to see

eval(hou.parm("/obj/mygroup_test1/filter").eval())

and still no luck
Edited by BabaJ - July 26, 2016 10:16:39
User Avatar
Member
2035 posts
Joined: Sept. 2015
Offline
Ok..so I figured out why mine wasn't working…I guess I didn't fully understand what you were saying.

The spare parameter you were using as the source for the expression, eg.
lvar('PT') < 15

was in a string parameter.

In my file when I made the asset I was dragging and dropping all the paramters from the nodes and the filter parameter in the group node that is used for the expression is a float.

I should have caught on with the error message when it was saying it must be a string or code object.

What caught my eye is that when I was playing around with your source paramter I noticed that when I pressed enter the text box remained with the black background.

Yet when I was working with mine it was green. So as soon as I changed my parameter to a string it worked.

So thanks fried for responding to my post and giving me the info that led me to working out a solution.
Edited by BabaJ - July 27, 2016 09:57:51
User Avatar
Member
402 posts
Joined: June 2014
Offline
Glad to hear you got to the bottom of that one. I would add as a footnote that this is probably not the best way to structure the asset. And in general any mention of the eval() function is met with the shaking of heads and/or sharp intakes of breath, so steer clear at the cocktail party conversations

Another big catch is that eval() will scream at you if you try any variable assignment, so any multi line expressions are out.

If you get too into passing expressions around and up and down the hierarchy it can turn into a nightmare to debug also. So if you know you want to address the PT local, you can always just have a ‘threshold’ variable or something so your group node expression would be:

lvar('PT') < hou.parm("../../threshold").eval()

heck, you could even have a string parm for the local to be compared to:

lvar(hou.parm("../../local_var_name").eval()) < hou.parm("../../threshold").eval()

All that said, in this simple instance you're probably ok with eval()
Henry Dean
User Avatar
Member
2035 posts
Joined: Sept. 2015
Offline
Thanks again fried for the extra info for me to chew on
  • Quick Links