Remove all Unassigned Materials ?

   1956   14   1
User Avatar
Member
1013 posts
Joined: 4月 2017
Offline
Is there an easy way to select all materials that are not assigned?

-Olviier
User Avatar
Member
7849 posts
Joined: 9月 2011
Offline
what do you mean by this?
User Avatar
Member
1013 posts
Joined: 4月 2017
Offline
Lets say I created 30 materials. 28 of them are assigned to geo nodes. 2 are simply not assigned to anything. Curently, the only way I have is to right-click on each materials individually and click on View Dependencies.... Is there a way to automatically select all unassigned materials?
User Avatar
Member
313 posts
Joined: 10月 2016
Offline
Sure there is. Hypothetically you could:

Swlect the parent node with materials. Then run your code snippet.

Read all children nodes into a list. Usually I store their node_path, but you just need something to start with.

Find what Python method or methods that can be used to distinguish if a node is assigned. You already mentioned dependencies.

Define a new list. Now use a for loop to go through the first list of all nodes in your list. Add the nodes that don’t match your criteria or the inversion thereof (using ”if not”).

When you have your new list you can either set them as selected or just delete them.

My question is basically how much help would you need to implement that? If you are specific someone can likely help you if needed.

Cheers!
Interested in character concepts, modeling, rigging, and animation. Related tool dev with Py and VEX.
User Avatar
Member
1013 posts
Joined: 4月 2017
Offline
Oh, I see. I thought there'd be a simple method. I don't know how to script in python so I'll just use some elbow grease instead. Thanks for the info, I apreciate it!

-Olivier
User Avatar
Member
313 posts
Joined: 10月 2016
Offline
Not saying there is not an already built-in method, but just that I’m not aware of such. The Python approach would work.

There was a day I neither knew what Python was as well.

Could you provide a dummy file with your setup? It just makes everything more efficient.

Cheers!
Edited by SWest - 2023年10月15日 07:31:21
Interested in character concepts, modeling, rigging, and animation. Related tool dev with Py and VEX.
User Avatar
Member
64 posts
Joined: 4月 2022
Offline
nodes_to_remove = []
for vop_type in hou.vopNodeTypeCategory().nodeTypes().values():
    for node in vop_type.instances():
        if node.parent().isMaterialManager():
            no_refs = True
            for parm in node.parmsReferencingThis():
                if parm.node() != node:
                    no_refs = False
                    break
            if no_refs:
                nodes_to_remove.append(node)

if nodes_to_remove:
    ids = hou.ui.selectFromList( [ node.name() for node in nodes_to_remove ],
                                 default_choices=range(len(nodes_to_remove)),
                                 title="Remove Unused Materials", column_header="All Unused Nodes",
                                 clear_on_cancel=True, height=hou.ui.scaledSize(500) )
    
    [ nodes_to_remove[id].destroy() for id in ids ]
Edited by anon_user_95266836 - 2023年10月15日 08:55:50
alexeyvanzhula.gumroad.com
User Avatar
Member
64 posts
Joined: 4月 2022
Offline
In this example, a list of all material nodes that are not used anywhere is displayed. You can disable the nodes that need to be kept by clicking on them with Ctrl.
alexeyvanzhula.gumroad.com
User Avatar
Member
8630 posts
Joined: 7月 2007
Offline
if you Show Dependencies you will see if a material has outgoing dependencies (little arrow) or not so you can also delete them visually by selecting and deleting the ones without
Tomas Slancik
FX Supervisor
Method Studios, NY
User Avatar
Member
257 posts
Joined: 7月 2013
Offline
node.dependents(include_children = True) → tuple of hou.Node

Return a tuple of nodes that are reference this node, either through parameter expressions, referring to the node by name, or using expressions which rely on the data generated by this node

So loop over your main material nodes, if nothing depends on them it's an unused material. (assuming material stylesheets are not used)
More code, less clicks.
User Avatar
Member
64 posts
Joined: 4月 2022
Offline
Jonathan de Blok
So loop over your main material nodes
This will not be an automatic search across entire scene.
alexeyvanzhula.gumroad.com
User Avatar
Member
7849 posts
Joined: 9月 2011
Offline
olivierth
Lets say I created 30 materials. 28 of them are assigned to geo nodes. 2 are simply not assigned to anything. Curently, the only way I have is to right-click on each materials individually and click on View Dependencies.... Is there a way to automatically select all unassigned materials?

What if the material is assigned to geometry on disk, or assigned procedurally using a wrangle? It seems like too high of a burden to conclusively prove a material is unassigned.
User Avatar
Member
257 posts
Joined: 7月 2013
Offline
Alexey_Vanzhula
Jonathan de Blok
So loop over your main material nodes
This will not be an automatic search across entire scene.

If you get all instances of the relevant material types is should be scene wide.

So once you've gathered a list of relevant material nodes using the node.dependents(..) is an easy way to check if they are used somewhere.

(it's the same method as the OP uses manually using the UI)
More code, less clicks.
User Avatar
Member
64 posts
Joined: 4月 2022
Offline
Jonathan de Blok
Alexey_Vanzhula
Jonathan de Blok
So loop over your main material nodes
This will not be an automatic search across entire scene.

If you get all instances of the relevant material types is should be scene wide.

So once you've gathered a list of relevant material nodes using the node.dependents(..) is an easy way to check if they are used somewhere.

(it's the same method as the OP uses manually using the UI)

I forgot about the dependents method and used hou.Node.parmsReferencingThisinstead. Thank you for the tip. But why consider the type of relevant materials? We could just go through all the free vop nodes that are located at the root of the vop network. Such nodes are most likely materials. That’s if we are talking about a completely automatic search for materials for users who don’t know Python. Although, of course, this won’t work if materials are assigned in VEX.

nodes_to_remove = []
for vop_type in hou.vopNodeTypeCategory().nodeTypes().values():
    for node in vop_type.instances():
        if node.parent().isMaterialManager() and not node.dependents():
            nodes_to_remove.append(node)

if nodes_to_remove:
    ids = hou.ui.selectFromList([ node.name() for node in nodes_to_remove ],
                                default_choices=range(len(nodes_to_remove)),
                                title="Remove Unused Materials", column_header="Unused Nodes",
                                clear_on_cancel=True, height = hou.ui.scaledSize(500))
    
    [ nodes_to_remove[id].destroy() for id in ids ]
Edited by anon_user_95266836 - 2023年10月17日 07:40:35
alexeyvanzhula.gumroad.com
User Avatar
Member
257 posts
Joined: 7月 2013
Offline
Alexey_Vanzhula
Jonathan de Blok
Alexey_Vanzhula
Jonathan de Blok
So loop over your main material nodes
This will not be an automatic search across entire scene.

If you get all instances of the relevant material types is should be scene wide.

So once you've gathered a list of relevant material nodes using the node.dependents(..) is an easy way to check if they are used somewhere.

(it's the same method as the OP uses manually using the UI)

I forgot about the dependents method and used hou.Node.parmsReferencingThisinstead. Thank you for the tip. But why consider the type of relevant materials? We could just go through all the free vop nodes that are located at the root of the vop network. Such nodes are most likely materials. That’s if we are talking about a completely automatic search for materials for users who don’t know Python. Although, of course, this won’t work if materials are assigned in VEX.

nodes_to_remove = []
for vop_type in hou.vopNodeTypeCategory().nodeTypes().values():
    for node in vop_type.instances():
        if node.parent().isMaterialManager() and not node.dependents():
            nodes_to_remove.append(node)

if nodes_to_remove:
    ids = hou.ui.selectFromList([ node.name() for node in nodes_to_remove ],
                                default_choices=range(len(nodes_to_remove)),
                                title="Remove Unused Materials", column_header="Unused Nodes",
                                clear_on_cancel=True, height = hou.ui.scaledSize(500))
    
    [ nodes_to_remove[id].destroy() for id in ids ]


Yeah you're right, that would work. I quickly skimmed though the categories and couldn't find a suitable material type category to target, but checking all nodes if they are in a material manager node sounds like a good approach, could even be a blunt oneliner:

unused_nodes = list(filter(lambda node: node.parent().isMaterialManager() and not node.dependents()  , 
hou.node("/").allSubChildren()))
More code, less clicks.
  • Quick Links