foreach iterate over files in folder?

   9381   9   1
User Avatar
Member
271 posts
Joined: March 2012
Offline
Hi all,
I'm trying to iterate over files in a folder and I can't seem to figure it out. My method so far is to try and add an attribute useing python, then use a foreach to iterate over it. But that's not really working, because I don't want to add an attribute to every point, prim or vertex…but I can only have a single entry for a detail attribute. (i.e. I'd need multiple entries for the fodlers).

Any ideas?
User Avatar
Member
392 posts
Joined: Nov. 2008
Offline
You can use python.
In attached example:
First generate some geometry for testing (ROP driver in create_geo node)
and then look how it's loaded in load_geo.

Attachments:
pz_iter_over_folder.hip (95.8 KB)

User Avatar
Member
271 posts
Joined: March 2012
Offline
Thanks for the reply…this does seem to do what I want…except that I can't seem to get it to work when I modify it.
I can get a list of the files, but I seem to have some real problems with getting expressions/python to work in string parameters.
Most of the time it just fails and I don't know why.
Your python parameters show up as red, and when I take the same code and put it into another parameter, mine is not red and it doesn't work.
User Avatar
Member
392 posts
Joined: Nov. 2008
Offline
To set python expression:
First put keyframe in parameter (it turns green).
Then in RMB menu switch expression language to Python (it turns red).

Also check if you are editing expression or result of it (Background color of Parameter's label show you if you are in editing or result mode. If there is different background color under parameter's label you are in editing mode). Left click on label switch between editing and result mode.

(If you edit python expression in result mode you got as result string with “quotes” at both sides instead of executable python code)
User Avatar
Member
271 posts
Joined: March 2012
Offline
Ah yes…I now have the ability to code python - thanks

What I'm having trouble with now though, is getting various parameters into other bits of python code. For example, I have this bit of code inside my for loop to determine the parameter called ‘fname’:
hou.node('../../control').evalParm('file')

Which returns something that looks like a python list, but if I then do something like

len(list(hou.pwd().evalParm('fname')))

it returns the length of the string…not the length of the list


Side note: I can never remember the correct expression to get the current index value inside a for loop. I'm currently trying

stamp(“.”, “FORVALUE”, 0)

But it always returns zero

Thanks for the help!
Edited by - July 2, 2014 16:59:53
User Avatar
Member
392 posts
Joined: Nov. 2008
Offline
Maybe there is better way but adding eval() works:

len(eval(list(hou.pwd().evalParm('fname'))))

It transfer returned string to working python list. (I used it in load_files sop node in example file above)

There is good example file in help explaining for each cycle (try to search: ForEachExamples)
User Avatar
Member
271 posts
Joined: March 2012
Offline
Changed it to
len(eval(hou.pwd().evalParm('fname')))

and it works…the previous code, which is almost identical except for the ‘list’ part.

len(eval(list(hou.pwd().evalParm('fname'))))

I must admit, I'm confused as to why the top one works, but the bottom one does not. If the fname parameter returns a string, then passing it to a list should work ok…and if it returns a list object, then it should still work.

Any idea why it doesn't?
User Avatar
Member
392 posts
Joined: Nov. 2008
Offline
I tested it today and you are right.
hou.pwd().evalParm('fname') returns string.


So then:
list(hou.pwd().evalParm('fname'))list() converts that string into list of letters.


But
eval(hou.pwd().evalParm('fname'))interprets this string as python code and evaluates it.


Compare:
string = ""
print list(string)
print eval(string)
I'm sorry for confusion in previous post.
User Avatar
Member
271 posts
Joined: March 2012
Offline
I've tried implementing this, but I've run into another problem - it is insanley slow.
So slow, that I've had to cancel it before it has completed.

Currently, I'm trying to create a string attribute, copy the file name to it using copy stamping, then use it later. But it just takes so long that it's completely impractical, and I really don't know what the problem is.

I've attached my latest attempt - obviously you'll have to change the folder directory and extension.

Attachments:
pz_iter_over_folder_171.hip (95.8 KB)

User Avatar
Member
392 posts
Joined: Nov. 2008
Offline
It depends what you want to do.
You can cache result of foreach sop. You can set Max Iteration to one, test your setup and then run it overnight on all files.

Or you can insert file sop inside foreach sop, do your stuff on single loaded object and save it with another file sop, all that still inside foreach. So you can make simple file converter this way.

You can also use a little different technique, create points, load file paths and save it as string attribute on points. So you will end up with couple of points where each have attribute pointing to different path. Then you can use this attribute to load only desired files (iterate over points, delete unwanted points etc..)
Look at this video: https://vimeo.com/99354544 [vimeo.com]
  • Quick Links