material editor node parent and children

material editor node parent and children

Anonymous
Not applicable
3,141 Views
7 Replies
Message 1 of 8

material editor node parent and children

Anonymous
Not applicable

Hello,

Is there an "easy" way to do the following:

- get the parent and child of a given material editor name. Say you have bitmap>somenode>someothernode>material

you work on 'somenode' and you really need to know what is the child and what is the parent. 

This task is driving me crazy... The farest I managed to get was to assume starting from the material and slowly going node by node down the tree, collecting prop names and executing convoluted strings to check which slot(s) is/are in use... And this is only going to get messier.

I couldn't find anything either in the docs or using google for that matter (nothing useful at least, always examples assuming nodes are of a known type and there is no more than one child or parent).

Thank you

0 Likes
Accepted solutions (1)
3,142 Views
7 Replies
Replies (7)
Message 2 of 8

blakestone
Collaborator
Collaborator

I do not fully understand exactly what you're trying to achieve however the following script includes two functions which return all the children of the specified parent name and returns all the parents which have a material with the specified child name.

 

(
	fn find_parent child = (
		local parents = #()
		for mat in sceneMaterials where classOf mat == multimaterial do (
			for sub in mat.material where sub.name == child do (
				append parents ("Parents: " + mat.name)
			)
		)
		return(parents)
	)
	
	fn find_children parent = (
		local children = #()
		for mat in sceneMaterials where classOf mat == multimaterial and mat.name == parent do (
			for sub in mat.material do (
				append children ("Children: " + sub.name)
			)
		)
		return(children)
	)
	
	print (find_parent "material_child") -- lists all parent materials which has a child material with this name
	print (find_children "material_parent") -- lists all child materials of the specified parent material
)
0 Likes
Message 3 of 8

denisT.MaxDoctor
Advisor
Advisor

as i could understand you well you want to know a relation between two materials: how is "parent" and who is "child".

right?

there is no such thing for materials like parent-child dependency. But there is dependency itself. So you can check how two nodes depend to each other. 

you show use : refs.dependencylo

refs.dependencylooptest mat_A mat_B

-- if you get TRUE it means A depends on B (B is a "child" of A)
-- if you get FALSE it means that A doesn't depend on B. B might be a parent of A or might not have any dependency with A

-- if you want to check is B a "parent" of A do:

refs.dependencylooptest mat_B mat_A

see also refs.Dependents and refs.DependsON

0 Likes
Message 4 of 8

Anonymous
Not applicable

Hello DenisT and thank you for your answer.

I'll try to be a bit more specific about what I'm trying to achieve.

I'm currently working on a converter and although converting nodes that I actually can has been pretty straightforward, now is the time to 'cleanup' nodes I cannot support. But I need to retain proper texture<>texture, texture<>material, material<>material connections.

This is where I fail. No matter which direction I crawl the shading tree (left>right or right>left, at some point I'm stuck as I cannot get the outut_socket in any way so far so I need to check 2 nodes down or 2 nodes up, which happens to be a lot of code an quite slow using the only way I managed to get this to work so far (basically listing node's input slots, checking for them to be undefined or not, picking the first NOT undefined and so on).

 

I think if I could get your functions to get parents and children to adapt to my script, that might work. I'm still trying tho 🙂 I've been learning maxscript for the first time in a crash-course during the last month and a half only so pardon my ignorance if I'm missing something way easier than I thought!

0 Likes
Message 5 of 8

Anonymous
Not applicable

I tested the refs.dependencylooptest way but the problem seem to be that it doesn't stop at the immediate child or parent, but crawl all the way up or down the shading tree and that the node is a child and parent of itself (at least in my findings).

In the following example there is from down to up the tree:

 

bitmap > color map > color correct > standard material

 

Using this code:

fn delete_and_relink =
(
	local mk_scene_nodes_all = join mk_scene_nodes mk_scene_nodes_unsupported
	local child_node  = undefined
	local middle_node = undefined
	local parent_node = undefined
	
-- here I loop in my unsupported nodes array for i in mk_scene_nodes_unsupported do ( middle_node = i
-- here I check against all nodes, supported or not for child for j in mk_scene_nodes_all do ( if ( refs.dependencyLoopTest middle_node j ) then ( child_node = j print ( middle_node as string + " CHILD is: " + child_node as string ) ) if ( refs.dependencyLoopTest j middle_node ) then ( parent_node = j print ( middle_node as string + " PARENT is: " + parent_node as string ) ) else () ) ) ) on testbtn pressed do ( delete_and_relink() )

For now this function does not delete and relink but that's its goal.

The output is:

 

"Material #25:Standard CHILD is: Material #25:Standard"
"Material #25:Standard PARENT is: Material #25:Standard"
"Material #25:Standard CHILD is: Map #4:Bitmap"
"Material #25:Standard CHILD is: Map #2:Color Correction"
"Material #25:Standard CHILD is: Map #3:Color Map"
"Map #4:Bitmap PARENT is: Material #25:Standard"
"Map #4:Bitmap CHILD is: Map #4:Bitmap"
"Map #4:Bitmap PARENT is: Map #4:Bitmap"
"Map #4:Bitmap PARENT is: Map #2:Color Correction"
"Map #4:Bitmap PARENT is: Map #3:Color Map"
"Map #2:Color Correction PARENT is: Material #25:Standard"
"Map #2:Color Correction CHILD is: Map #4:Bitmap"
"Map #2:Color Correction CHILD is: Map #2:Color Correction"
"Map #2:Color Correction PARENT is: Map #2:Color Correction"
"Map #2:Color Correction CHILD is: Map #3:Color Map"
"Map #3:Color Map PARENT is: Material #25:Standard"
"Map #3:Color Map CHILD is: Map #4:Bitmap"
"Map #3:Color Map PARENT is: Map #2:Color Correction"
"Map #3:Color Map CHILD is: Map #3:Color Map"
"Map #3:Color Map PARENT is: Map #3:Color Map"

as you can see this is not exactly what I'm after. Each node is a parent/child of itself and a given node will have as parent and children ALL the nodes up or down the tree.
Although if I could stop at the immediate parent and child, the problem of deleting the 'middle' node so it's parent and child have a direction connection is still open.

0 Likes
Message 6 of 8

denisT.MaxDoctor
Advisor
Advisor
Accepted solution

i probably understand what you are looking for... you want to know where (which client has this node)  a node used.

if it's material - what slot of sub-material, if it's texture - what bitmaptexture node and where is in the material... right?

 

ok... in this case your friend is 

getclassinstances with astrackviewpick option (see details in the mxs help, and search this or CGTalk forum for examples).

 

brief example:

 

mat = multimaterial numsubs:2
m = mat[1] = standard()
ii = getclassinstances (classof m) astrackviewpick:on
for i in ii do format "parent:% anim:% subnum:% subanim:%\n" i.client i.anim i.subnum i.client[i.subnum]

same idea for bitmaptrxtures... but you have to search but name and bitmap texture filename after that. that's the best way via MXS

Message 7 of 8

Anonymous
Not applicable

Awesome Denis.T, it looks like I'm going to be able to work my way from there. Many thanks!

0 Likes
Message 8 of 8

Anonymous
Not applicable

Well if someone is interested in doing such thing, here my working code. It only considers the first valid input_socket, doing otherwise would mean knowing what each child and parent node is capable of. Possible but not the goal here. If your "middle" node has just one input socket anyway, works like a charm.

 

fn get_parent x =
(
	getParents = getClassInstances ( classof x ) asTrackViewPick:on
	
	for i in getParents do
	(
		if ( superClassOf i.client == textureMap ) or ( superClassOf i.client == material ) then
		(
			if ( i.client != undefined ) then
			(
				parent = i.client
				return parent
			)
			else
			(
				return undefined
			)
		)
	)
)
	
fn get_child x =
(
	free submaps_count
	free submaps_names
	gc
	
	submaps_count = getNumSubTexmaps x
	
	submaps_names = #()

	for i = 1 to submaps_count do
	(
		if ( ( getSubTexmap x i ) != undefined ) then
		(
			append submaps_names ( getSubTexmap x i )
		)
	)
	
	child = submaps_names[1]
	
	return child
)

fn delete_and_relink =
(
	global child
	global current
	global parent
	
	local unsupported_nodes -- This is your array or unsupported nodes, construct it the way you want
	
	for i in unsupported_nodes where ( superClassOf i == textureMap ) and ( classof i != Bitmaptexture ) do -- it was required to get rid of the Bitmaptexture class for me, otherwise bitmap type nodes return an extra parent to themselves
	(
		current = i
		
		index = getNumSubTexmaps i
		
		get_parent current
		
		get_child current
		
		setSubTexmap parent 1 child
		setSubTexmap current 1 undefined
	)
	
	free unsupported_nodes
	gc
)

 

0 Likes