evaluating /obj level shop_materialpath in python

   3440   3   1
User Avatar
Member
20 posts
Joined: Sept. 2013
Offline
I have an fbx subnet with a bunch of different models that Im object merging into a separate geo network with wildcards in the object_path to grab all the file nodes in the fbx subnet, and enabling create path attribute in the object merge

I need the shop_material path to correctly point to the corresping fbx material that was created, and while most objects are read in with the shop_materialpath attribute correctly, the houdini fbx importer will randomly assign the material at the object level depending on how the model was prepped, so the resulting shop_materialpath from the object merge is missing. The textures and materials are there at the object level (in the fbx subnet) but the shop path is wrong, and thus textures break in the object merge.

so I need in a python sop to run a loop over each prim, eval the obj level shop_materialpath parameter from its path parameter (i.e. its source geo network in the fbx subnet) and append that string to the current geo shop_materialpath for the missing prims

any help is much appreciated
User Avatar
Member
191 posts
Joined: Oct. 2018
Offline
I'm no expert with python running over geo, but this was working for me:

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

# Specify names for path and shop attributes.
pathAttr = "objname"
shopAttr = "shop_materialpath"

# Check if the attributes exist.
pathExists = geo.findPrimAttrib( pathAttr )
shopExists = geo.findPrimAttrib( shopAttr )

# Create shop attribute if it doesn't exist and the path attribute does.
if pathExists and not shopExists :
    geo.addAttrib(hou.attribType.Prim, shopAttr, "")

if pathExists :
    for prim in geo.prims() :
        pathVal = prim.attribValue( pathAttr ).rsplit("/", 1)[0] # Split off the last part of the path value.
        pathNode = hou.node( pathVal )
        matNode = pathNode.parm("shop_materialpath").eval()
        absPath = pathNode.node( matNode ).path() # Convert the relative path to absolute path.
        
        prim.setAttribValue( shopAttr, absPath ) # Set the shop attribute value.
else :
    raise hou.NodeWarning("Path attribute doesn't exist.") # Raise a warning if the path attribute doesn't exist.

Not sure if it's the same for every fbx, but the material path on my imported fbx was a relative path so that's why I have the extra step to convert it to an absolute path. If yours is already absolute, you can skip that and just plug in the matNode to the setAttribValue.

And if you've got tons of geo and it becomes slow, maybe pack the geo by the path attribute, then run it and unpack the geo transferring the shop_materialpath? I haven't worked with it enough to know if python gets slow or not…
User Avatar
Member
20 posts
Joined: Sept. 2013
Offline
That worked, thank you! I fiddled with your code a bit to work with my files and it works like a charm

I previously got it working with a long complicated setup that I realize now is slightly unnecessary cause FBX is just unpredictable and odd

thanks for the help
User Avatar
Member
191 posts
Joined: Oct. 2018
Offline
No problem. I realized you can also simplify the code after posting by putting

if not shopExists :
    geo.addAttrib(hou.attribType.Prim, shopAttr, "")

inside the “if pathExists” condition instead of having it's own condition
  • Quick Links