Automatic material assignment by primvar

   3589   5   2
User Avatar
Member
7 posts
Joined: March 2020
Offline
Hello everyone!

I'm working on a scene where I'm importing an object made by thousands of individual pieces, and each one of them has a string prim attribute (shop_materialpath) that contains the appropriate material value (i.e. plastic, carpaint, aluminium, and so on) derived by maya's shading groups.

I imported this geometry into houdini as obj (in order to get this attribute) and saved out an USD file.

What I'd like to do is basically use this attribute value to drive the material assignments, think something like (@shop_materialpath=="carpaint" as an assignment rule).


Do you guys have any suggestions on how I should approach this?

Thanks in advance!
User Avatar
Member
7803 posts
Joined: Sept. 2011
Online
Use a vexpression on the assign material node.
User Avatar
Member
7 posts
Joined: March 2020
Offline
Hi jsmack, thanks for the answer!
I fiddled with it for a bit and finally managed to make it work!
For anyone wanting to do the same, it was actually much simpler than what I first thought:

-I created all the materials I needed with the name matching the shop_materialpath values.
-I wrote under the primitive's slot of the assign material lop the path to my main primitive: "/car/geo/**"


-Writing this expression will return the value of the primvar shop_materialpath, in my example "carPaint":

return (usd_primvarelement(0, @primpath, "shop_materialpath", @elemnum));

At this point you just need to combine this string with the primitive path of the material with the concat function and you'll have all the assignments done with just this expression!
Edited by brombe - June 12, 2022 15:44:02
User Avatar
Member
7 posts
Joined: March 2020
Offline
Well, trying this setup a bit more I'm not sure if I stumbled on a bug or if I'm doing something wrong.
It seems like if I'm trying to assign materials to too many objects (I'm seeing it happening around 90/110 primitives) it stops reading the shop_materialpath value correctly and it defaults to being empty.




If I prune enough objects to bring the count under that limit then it works again (so it's not happening because of specific objects).

In the scene graph details I can read the primvar correctly, but there's no material binding anymore.

I checked both with a modify sop and in the obj context that all my objects have a proper value and none of them have an empty string. On top of that, like I said, if I deselect a few objects to bring the count under 100ish then it starts working again.

You can see from my screenshots that at some point it just stops creating the material:binding in the scene graph details
Edited by brombe - June 13, 2022 07:03:00

Attachments:
lastObjectWorking.png (1.0 MB)
firstObjectBroken.png (1.0 MB)
warning.png (113.8 KB)

User Avatar
Staff
453 posts
Joined: June 2020
Offline
I think this may be due to your usage of @elemnum. If you change that to 0does it work?

It's perhaps worth noting that the workflow described in this thread will likely only be valid where shop_materialpathis constant across the geometry (i.e., a single piece of geo is not allowed to have two different materials).

Given that you were starting in /obj, did you consider also creating the materials there and using a Scene Import LOP to being the whole scene (geo + materials + assignments) into Solaris?
User Avatar
Member
7 posts
Joined: March 2020
Offline
Hi robp!
Yesterday I've found a different approach on tokeru's blog, so I went that route and it worked:

https://www.tokeru.com/cgwiki/index.php?title=HoudiniLops#Assign_material_Lop_with_shop_materialpath [www.tokeru.com]

Changing the @elemnum to 0 like you suggested actually worked, so thanks for the help (and yes, basically every poly of my objects all had the same value so no problems there)!

My geometry came from Maya originally, where I built the hierarchy and did the shader assignments.
I exported an obj in order to mantain the material assignments and then from houdini I exported both an alembic and an usd file to test which was working better for my case.

Following tokeru's way though, I have a question... How is it that importing an object in different ways gives you such different options?
Using a sop create/sop import gives you plenty of settings to fiddle with, but for example in my case I used an asset reference node to bring in my alembic, and I didnt have the option to "Import as single value" my attribute.

Is there another node to configure these settings later, or should I just import my alembic in sop and then bring it in lops with a sop import?
  • Quick Links