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

Fabricio Chamon fabricio.chamon at gmail.com
Mon Jan 22 07:52:41 EST 2018


thanks Sandy and Dan. wow, super extensive info Dan, much appreciated guys!
thanks a lot.

it ended up being easier than I tought, I used a simple python node that
lists (and filter) files from my base directory, then adds the filepaths to
a detail attribute on geometry, like this:

*import os*

*node = hou.pwd()*
*geo = node.geometry()*

*agentName = "stadium_male"*
*basepath = "[path]/[to]/[my]/[fbx]/" + agentName*
*files = os.listdir(basepath)*
*fbxFiles = list()*
*attrib = geo.addAttrib(hou.attribType.Global, "MotionFiles", files)*

*for file in files:*
*    if file.endswith("fbx"):*
*        fbxFiles.append (basepath + "/" + file);*

*geo.setGlobalAttribValue("MotionFiles", fbxFiles)*


My final goal was actually not to import using the file node, sorry I
didn't write that up in my previous email.. the fbx path should be fed into
an agent sop (or agentClip sop), that reads the animation clip, which then
has to be baked to disk (.bclip format, exported from the agent rop node).
The reading from attribute and feeding into agent sop node part should be
easily done now inside a for-loop.

Now I'm struggling with how to bake the clip to disk, as the agent rop has
to be inside a rop network obviously, so I can't connect that in the
for-loop stream. Alternatively, I'll dig the factory nodes to try and
understand how Houdini converts fbx->bclip format and write a vex code to
handle file conversion/export.

thanks once again guys.

2018-01-22 10:17 GMT-02:00 Dan Wills <gdanzo at gmail.com>:

> 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
>
> ------->8-------
> 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
> like:
>
> "|".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?)
> or:
> 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.
> -------8<-------
>
> 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!
> Dan
>
> On 21 Jan. 2018 2:26 am, "Fabricio Chamon" <fabricio.chamon at gmail.com>
> wrote:
>
> 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.
>
> suggestions?
> _______________________________________________
> Sidefx-houdini-list mailing list
> Sidefx-houdini-list at sidefx.com
> https://lists.sidefx.com:443/mailman/listinfo/sidefx-houdini-list
> _______________________________________________
> Sidefx-houdini-list mailing list
> Sidefx-houdini-list at sidefx.com
> https://lists.sidefx.com:443/mailman/listinfo/sidefx-houdini-list
>


More information about the Sidefx-houdini-list mailing list