Jump to content
Memo

Referencing a parameter expression as a string to be evaluated on chil

Recommended Posts

I'm creating an OTL, and in the OTL I have a ropnet with a bunch of geometry render nodes. What I want, is from the main interface of the OTL a user can choose an arbitrary name, click Render and all of the geometry sequences are exported one after the other into a folder with the arbitrary name, into subfolders with fixed names. I've tried a few things and got close, but not as clean as I like. I have a bunch of questions regarding this.

 

e.g. folder structure:

- my_arbitrary_folder_name

   - fluid_raw: contains bgeo sequence for raw fluid data

   - fluid_cleaned: contains bgeo sequence for cleaned fluid data

   - fluid_reduced: contains bgeo sequence for reduced fluid data

   - triangulated: contains bgeo sequence for triangulated fluid data

etc.

 

So on my ropnet interface I have:

- a string parameter called folder_name

- a string parameter called full_path which I have entered: $JOB/geo/$HIPNAME/`chs("folder_name")`

 

Then inside the ROP for each of my render nodes I've entered the following into the SOP Path: `chs("../full_path")`/$OS/$F4.bgeo

 

This works pretty well. However if I decide to change the final output filename format (e.g. if I want to do $F5 instead of $F4, or include the $OS in the filename like $OS.$F5) I have to go through all my geometry render nodes, and copy paste my new expression of `chs("../full_path")`/$OS/$OS.$F5.bgeo in there. Ideally that expression would be on the ROP as well, but I couldn't figure out how to do that.

 

 

Q1.

I'd kind of like to write on the parent node (i.e. the ropnet):

$JOB/geo/$HIPNAME/`chs("../folder_name")`/$OS/$F4.BGEO

 

And then have this copied as a string to the child nodes (i.e. geometry nodes) and evaluated there. But what happens right now is the $OS is evaluated on the parent node (into 'ropnet1') and comes across as a string. I couldn't figure out any combination of ticks, backticks or apostrophe's to solve this. 

(See EXPRESSION_EVAL_TEST in the attached file)

 

P.S. I've actually ditched this approach now (see below), but I'm still curious to see what the answer is just for future reference as I can see it being handy.

 

 

 

 

I've ditching the approach above (using $OS), and I'm now collating all of the fixed subnames (entered manually) in the main interface as well, so I enter on my main interface:

folder_name: e.g. preset1. folder name where all other subfolders go. I'll change this regularly while playing with different presets. 

file_name: $F4.bgeo. I'll probably set this once for a project.

name1,2,3,4,5: names for each of the sub folders, again I'll probably set this once for a project. 

 

Then from this I create:

parent_path: $JOB/geo/$HIPNAME/`chs("folder_name")` (e.g. D:/waves/houdini/geo/roptests.hipnc/preset1)

And then a full path for each of the subfolders:

`chs("parent_path")`/`chs("name1")`/`chs("file_name")`

`chs("parent_path")`/`chs("name2")`/`chs("file_name")`

`chs("parent_path")`/`chs("name3")`/`chs("file_name")`

etc.

 

 

Q2.

How can I automate this for each of the full_paths? Copy/pasting the formula and then changing a number 1, 2, 3, is annoying. 

 

 

Q3.

Then in my readfile nodes, I enter the path:

`chs("../../full_path1")`

`chs("../../full_path2")`

`chs("../../full_path3")`

 

and the exact same for the Geometry render nodes in my ropnet.

 

There is still too much copy/paste and manual editing for my liking. I would like to just set an index on the readfile nodes via a custom parameter, and have everything updated,

e.g. the equivalent of: 

chs("../../full_path" + chs("index") )

 

I got as far as:

chs("../../full_path`chs("index")`" )

which gives me 

chs("../../full_path1" )

which as a string is correct, but obviously that isn't evaluated, as soon as I put backticks around it it breaks (I guess they can't be nested).

Is this possible? Also is this the right way to do it? It looks super messy. 

 

roptests.hipnc

Share this post


Link to post
Share on other sites
Guest mantragora

It may be only my feeling, but I really don't understand what you are asking about. Your OTL is a total mess that doesn't help either. Split in on simpler cases and ask again.

1. Do you know that you can use multi-line expressions with both, Python and HScript? Easier to read, easier to maintain.

2. Have you thought about storing Python module on your asset and than calling some function from it and passing node that is calling it as an argument?

This in you OTL/PythonModule:

def SetFrame(node):
    return '{0}_{1}'.format(node.name(), int(hou.frame()))
and than inside you asset on your null parameter

this = hou.pwd()
parent = this.parent()

return parent.hdaModule().SetFrame(this)
Thanks to this you will get your correct node name plus current timeline frame. Edited by mantragora

Share this post


Link to post
Share on other sites

Hi, thanks for the answer.

 

did you get a chance to look at the hip file I sent? there's only about 4 nodes per network, I don't know how that can be made any simpler!

Share this post


Link to post
Share on other sites
Guest mantragora

Hi, thanks for the answer.

Code example is for your EXPRESSION_EVAL_TEST. If you don't know what I showed here, I can add example scene with OTL.

EDIT: Added example.

EXPRESSION_EVAL_TEST.zip

 

did you get a chance to look at the hip file I sent? there's only about 4 nodes per network, I don't know how that can be made any simpler!

I don't get this:

How can I automate this for each of the full_paths? Copy/pasting the formula and then changing a number 1, 2, 3, is annoyin

What you have to copy paste there? I'm lost on which part you have to manually copy/paste/update each time. You are annoyed because to get FullPath on another fileSOP you have to add specific number to it?

Edited by mantragora

Share this post


Link to post
Share on other sites

Memo selam, hoşgeldin :-)  

 

Hscript is indeed a bit too odd to decrypt.

I'll give more direct answers to your questions.

For "is there a beter way", I'm sure there are a million of them, and it looks like mantragora's method of storing python modules in the OTL might be one.

 

Q1)

chs() automatically expands the strings, so $OS gets replaced as you query it.   ( http://goo.gl/OBHxQy )

You need to query the unexpanded string, then expand within the new node. So in python, so can do it like:

hou.expandString( hou.parm("../NULL_CONTROLLER/parm").unexpandedString() )

(And to be able to use python expressions, you used to need to put a keyframe first, I think that is still the case)

 

 

Q2) 

I guess I would either traverse a ready-made node tree with python and assign the values, or just build the node-trees from scratch using python, putting in the expressions as you go.

 

Q3)

This is also quite easier to do in a python expression, as:

hou.parm( "../../full_path%d" %hou.parm( "index").eval() ).eval()

Best of luck in your houdini adventures!

Edited by cosku

Share this post


Link to post
Share on other sites

@mantragora

Thanks for the example, it's very helpful. I Was actually asking for generic way of referencing strings from parameters and evaluating on the target node, but I think I will ditch HSCRIPT forever and just stick with python for everything if I can. So much cleaner and predictable (with a HOM and autocomplete etc like a proper development environment!)

 

@cosku,

merhabalar :)

Thanks, yes that makes sense, and it seems again python to the rescue!

 

I've set my default scripting language to be python now in my preferences and hopefully things will be a bit easier :)

Share this post


Link to post
Share on other sites

The purpose of the backtick is to allow you to evaluate an expression from a string parameter when you do not have a channel. If you always right-click on the parameter and choose edit expression. This should create a channel (green) for you regardless of whether it's a float or string parameter. Then you never need to use backticks. The reason why hscript exprs are going to be around still is because python is *slow*, especially for ch()/chs() references.

Share this post


Link to post
Share on other sites

@cpb that doesn't work for me. But it doesn't matter, i'm just going python everywhere, and writing things out explicitly, it's working so far. 

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

×