Search - User list
Full Version: Material to SOP in object merge
Root » SI Users » Material to SOP in object merge
NNois
Hi,
When I Object Merge, the operator wipe all materials applied directly to obj.

Does someone has a ready made custom obj merge to do that ?
anon_user_89151269
Can you post a hip or an image with the netview?
NNois
I'm sorry for the confusion…

Let's restart clean:

In houdini there's 2 way of applying materials

1. Obj way in the obj property, one material possible.
-> Just like Softimage when applying a mat to the root of the geo

2. SOP way where's the material is written in the geo as an attribute with the shader path.
-> In Soft this is just like when you apply a Material to a cluster

-> So what if a material is applied on 1 & 2 ? Well, the SOP way has simply a higher priority and that's good just like softimage.


So far so good ?? well, yes until you want to merge 2 geos, In soft there's a button to merge also the materials and works well because it takes too the root material AND the priority with the clusters

On the houdini side obj_merge wipe completly the OBJ material….

There's a script on ODforce given to Jordi Bares to solve this but this is only sloving it halfly because the script this time wipe completly the SOP materials…
http://forums.odforce.net/topic/19422-object-merge-question/?hl=%2Bobject+%2Bmerge [forums.odforce.net]

So, i'm now 2y later asking if somes had a sort of updated script with the right behavior ;-)

That's not a strange request by the way.
A simple FBX import generate this types of mixed materials…
anon_user_89151269
Ah, got it.
goldleaf
Here's one way; add this bit of Python to a shelf tool:

# Support multiple selected nodes
for n in hou.selectedNodes():
    
    # Only operate on Obj Merge SOPs
    if n.type().name() == 'object_merge':
    
        # Set variables for our nodes
        p = n.parent()
        m = p.createNode('material')
        objnode = hou.node(hou.parm(n.path()+"/objpath1").eval())
        
        # Connect the material sop to the obj merge sop
        m.setInput(0,n)
        
        # Point the material sop to the obj's material
        hou.parm(m.path() + "/shop_materialpath1").set(hou.parm(objnode.path() + "/shop_materialpath").eval())
        
        # Move it below the merge node
        m.moveToGoodPosition()
        

Now, any selected Obj Merge SOPs will get a Material SOP connected to its output, set to the Obj Node's material.

The attached hip file is an example. Note that the merged and Obj Merge'd geometries all need to have matching attributes. If they don't match, then non of the materials will render correctly.

Hope that helps!

Edit by ndickson: Fixed code block, so that the code is preserved by the forum, instead of replacing quotes, etc.
weston.slater
goldleaf
Here's one way; add this bit of Python to a shelf tool:

# Support multiple selected nodes
for n in hou.selectedNodes():

# Only operate on Obj Merge SOPs
if n.type().name() == ‘object_merge’:

# Set variables for our nodes
p = n.parent()
m = p.createNode('material')
objnode = hou.node(hou.parm(n.path()+“/objpath1”).eval())

# Connect the material sop to the obj merge sop
m.setInput(0,n)

# Point the material sop to the obj's material
hou.parm(m.path() + “/shop_materialpath1”).set(hou.parm(objnode.path() + “/shop_materialpath”).eval())

# Move it below the merge node
m.moveToGoodPosition()


Now, any selected Obj Merge SOPs will get a Material SOP connected to its output, set to the Obj Node's material.

The attached hip file is an example. Note that the merged and Obj Merge'd geometries all need to have matching attributes. If they don't match, then non of the materials will render correctly.

Hope that helps!

I'm trying to do exactly what you have here, however, i'm getting python errors when I try to execute the script. Do you have any idea what I'm doing wrong? I really appreciate any guidance!

(I seem to be having trouble uploading, so here's Drive links to the images just in case):

The Code:
https://drive.google.com/file/d/1Dr3cjunpq_rNvPVNKskRaM2VYr4t8rJD/view?usp=sharing [drive.google.com]


The Error:
https://drive.google.com/file/d/1lagdSwj5bILW8eY_raYzQ9HYt8ydjvBp/view?usp=sharing [drive.google.com]

Thanks,
Weston
neil_math_comp
Hi Weston! It looks like you have an extra right-double-quote character after the /shop_materialpath1text inside the string.
neil_math_comp
I fixed the code block in goldleaf's post that seemed not to be liked by the forum's bbcode parser, so now anyone copying the code from his post in the future should hopefully get the correct quotes.
weston.slater
I actually just caught that! Though unfortunately, it's still throwing a NoneType error for line 17; though this time it's claiming that “eval” doesn't exist?

Thanks again!
neil_math_comp
Oh, if objnodeisn't a Geometry object, there won't be a shop_materialpathparameter. I guess the script will only work if the Object Merge SOPs are merging from objects, instead of directly from SOPs. You could probably check if objnode is type geo, and if not, switch to using its parent. Putting omething like the following code before the evaluation line might work, (though I'm not great with Python, so I'm just guessing) :

        if objnode.type().name() != 'geo':
            objnode = objnode.parent()
weston.slater
That worked! Thanks a bunch, I really appreciate it!! Here's the code for anybody else curious:

# Support multiple selected nodes
for n in hou.selectedNodes():

# Only operate on Obj Merge SOPs

    if n.type().name() == 'object_merge':

        # Set variables for our nodes
        p = n.parent()
        m = p.createNode('material')
        objnode = hou.node(hou.parm(n.path()+"/objpath1").eval())

        # Connect the material sop to the obj merge sop
        m.setInput(0,n)
        
        # Move it below the merge node
        m.moveToGoodPosition()
        
        # Point the material sop to the obj's material
        if objnode.type().name() != 'geo':
            objnode = objnode.parent()
        
        hou.parm(m.path() + "/shop_materialpath1").set(hou.parm(objnode.path() + "/shop_materialpath").eval())

Edit by ndickson: Removed an indent that would have skipped Geometry objects.
neil_math_comp
I hope you don't mind that I removed an indent from that last line in your post, since otherwise it would have only set the parameter if objnodewas not a Geometry object. I don't often edit other people's posts apart from forum formatting issues, but I figure if it's intended to be a reference for others and you don't mind, it's probably worth it.
weston.slater
Absolutely! I'm still getting to grips with using python, so I appreciate any and all edits! Made the change in my scene code as well. Can't thank ya enough, you've saved me so much time
goldleaf
Thanks Neil!
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB