Notifications
Clear all

[Closed] Iterate through submats to select by material

Hi guys. I’m struggling with a bit of maxscript that will select all objects that have a specific material assigned – even if that material lives way down in nested SubMaterials, either within a MultiMaterial, Two-Sided, etc.

Here is my code, which DOES work as long as the submat is only one level deep. Where it fails is if the submat it is looking for is nested with another submat. I know I need to separate it into a function that can keep iterating until there are no more submats but I just can’t seem to hash out the logic.

I realize this isn’t very elegant but here goes…

fn SelectbyMaterial MatchMat =
	(
		deselect $*
		for Obj in Geometry where Obj.material != undefined do
		(
			local Mat = Obj.material
			if Mat == MatchMat then
			(
				selectmore Obj
			) else
			(
				local NoSubmats = getNumSubMtls Mat
				if NoSubmats > 0 then 
				(
					for i = 1 to NoSubmats do
					(
						local Submat = getSubMtl Mat i
						if Submat == MatchMat then
						(
							selectmore Obj
						)
					)
				)
			)
		)
	)

Thanks for any help.

8 Replies
fn findNodesByMaterial mat nodes:  = 
(
	if nodes == unsupplied do nodes = objects
	for node in nodes where node.mat != undefined collect 
	(
		if refs.DependencyLoopTest node.mat mat then node else dontcollect
	)
)
/*
findNodesByMaterial <mat>
*/

also you can simply use

refs.dependentnodes mat

but it this case it’s not guarantied than the dependency is going through ‘material’ property

Thanks for posting but Yikes!!! That is so far over my head I barely recognize most of that as Maxscript lol. I seriously can’t even piece together the logic of what you are doing or exactly what variables to pass to that function (nodes: ). I’m not looking for a copy/paste solution here as I don’t learn anything so I’m going to try and read up and understand exactly what you are doing. If you feel like elaborating a bit, that would be great. If not, thanks anyway. I’ll see if I can figure this out.

let’s start with nodes:
#nodes is an optional argument (see mxs help – Function Parameters).

in case of my function you can specify a node list where to search. for example objects, geometry, shapes, selection, etc.

#2 is reference dependency.

every node (object) can depends on or be dependent of.

read about Dependencies in mxs help – MAXWrapper Common Properties, Operators, and Methods

refs.DependencyLoopTest <A> <B> says that object A depends on object B
in my case node’s material depends on search material. if so the node also depends on the material and needs to be collected

refs.dependentnodes collects all nodes that depends on specified object. in our case it’s a material.

Denis,
Yea, I had already stripped the nodes out for now just to keep it simple for and found in the documentation about the refs.DependencyLoopTest, etc. All completely new to me and I don’t even fully grasp collections yet so I have some homework to do. It is obviously a very different approach than where I was headed and probably much faster, I just want to completely understand what is going on before I use it. I think I can get there though now, so thank you.

Unfortunately I have to step back into my “real” job now and attend a scheduling meeting so I have to shelf this for rest of the day but I’ll pick back up in the AM. Thanks again.

using of dependency info might not be faster, but it’s a universal way to search, but it’s searching almost everywhere (only c++ makes this search fast).

with your approach you have to exactly know where to search, and it might be faster than search everywhere.

“dontcollect”!! I didn’t knew about it and have missed it several times. Thanks!

Just wanted to follow up and say thank you for this. It took a little work but I understand what’s going on now. This is some next level stuff for sure and opened up a whole new way of thinking about some of this.