[Sidefx-houdini-list] Reading files inside folder via node?

Dan Wills gdanzo at gmail.com
Mon Jan 22 07:17:18 EST 2018

G'day Fabricio,

I wrote all the cut-out section below before I realised, with FBX you can't
use the File Sop, so I think maybe pretty-much none of this will apply :/
Still, 'twas fun writing it so might as well still send it :) .. but feel
free to skip to the end if it's not helpin' ya :P

I think a good approach for this kind of thing (these days) is to get all
the String values into Vex/attributes as soon as possible. You might have
an Attribute Vop (or Wrangle) with a String Parameter on it, containing an
expression (Python is easiest afaik, probably not fastest) that evaluates
to one big String containing all the filenames.

A very simple Python expression on the big-String parm might look something

"|".join( __import__("os").listdir( "/your/PATH" ) )

Worth noting, if you go longer than one statement (or, line, which kinda
forces your hand when you need to use import statements) in your expression
then you have to switch to returning the value as if the expression were
the body of a method:

import os
return "|".join( os.listdir( "/your/PATH" ) )

This will list *everything* in the directory, including other directories!
To limit it to matching files, In the 'os.path' module: there are the
useful 'isfile()' and 'join()' methods, here's how they might look to get
all *actual files* where the filename ends with ".fbx" from a directory:
(*) long-ish List Comprehension but still fairly readable! : )

import os
root_dir = "/your/PATH"
ext = ".fbx"
return "|".join( [ os.path.join( root_dir, thing )
                   for thing in os.listdir( root_dir )
                   if os.path.isfile( os.path.join( root_dir, thing ) )
                   and thing.endswith( ext ) ] )

(Apologies if the Python formatting is all messed up! it's all set to
monospace and looks right from 'ere!)

You might also like to check out the 'glob' Python module (which can bring
support for patterns like "thingA_*_v075.fbx").

Note that I've used "|" as the joiner and separator here - I am
purposefully avoiding using "\n", which might otherwise seem logical, as
that seems to have some bugs at the moment!

After this brings the big String into Vex you can split it into a String
Array using the 'Split String' Vop (or Vex function) with '|' specified as
the separator. Then you can store the resulting array on the Geometry
however you'd like. I'd recommend doing the split in a Detail Vop/Wrangle
though, so that it runs exactly once - and then storing the resulting
String Array as a single Detail attribute ('Bind Export' in Vops).

This way of storing the list of filenames will let you easily pull values
out of the String Array downstream in another Vop/Vex node using 'Import
Detail Attribute'.

In an 'Attribute Vop'/Wrangle set to iterate either Points or Primitives -
if you contrive that the number of Points (or Primitives) is the same as
the length of the array, then you can (for example) use the ptnum or
primnum global variables as the array index with the "Get Element" Vop (or
square-brackety wrangle) to put one filename on each Point or Primitive.

Later, once your Points (or Prims) each have their individual file-path
String values, you should be all set to get all the files loaded via either:

A Copy Stamp ('stamps' expression on the filename String of a File Sop?)
A Foreach-Loop netsack, which might probably be faster? (might be
multi-threaded even? or eventually might be..)

Querying the Point (or Primitive) value via Vex (Bind or Import
Point/Primitive Attribute) is generally going to be faster then going via
ye-olde (single-threaded) Hscript-expressions: 'points()' or 'prims()'..
but the values usually have to bust out onto a parameter on another node in
the end anyway, so there frequently seems to be no way to avoid it. If
there's a way to use vexpressions (the whole '@thing' thing), then that is
likely the fastest.

So,.. I've now realised that you've actually got the double-whammy of
working on a set-of-files *and* they are FBX format! So because the File
Sop doesn't seem to read FBX over time (seems to only import 1 frame for
me, though I am on non-commercial.. dunno?) You'll probably need a whole
'nother layer of messing around with automation to do this. There might be
help in the form of the hom method:

hou.hipFile.importFBX( fbx_file_name, merge_into_scene=True,
import_into_object_subnet=True, etc ).

Maybe a short Python script might at least get all the FBXs imported into
one scene for processing?

If your intention is to convert each file individually then you might like
to use the Wedge Rop to drive all of this - it's *super* useful for
batch-processing sets of things! If you want to try that but get stuck, let
me know :)

I hope some of that is helpful! Best of luck!

On 21 Jan. 2018 2:26 am, "Fabricio Chamon" <fabricio.chamon at gmail.com>

Hey smart people,

I`m looking for a way to read files from a folder and store as an array
attribute on a geometry..would that even be possible?

The "script" node runs a python file, am I able to pass over parameters to
a python function or something ? Just to contextualize: I'm creating a
crowd agent and building a clip library for it. I have this folder full of
fbx's and as it is right now I need to create an "agent" node for each fbx,
then bake out the clip to disk. I'd like to automate this process by
looping over files inside folder instead of manually creating a node for
each animation, all from inside the node network, so each time I create a
new fbx it is just a matter of re-cooking the output.

I have had this need on many occasions before, like merging files or
tracing geometry.. so that would be a multi purpose thing really.

Sidefx-houdini-list mailing list
Sidefx-houdini-list at sidefx.com

More information about the Sidefx-houdini-list mailing list