Announcements

Between mid-October and November, the content on AREA will be relocated to the Autodesk Community M&E Hub and the Autodesk Community Gallery. Learn more HERE.

How to get material ID of MultiMaterial hierarchy in MaxScript?

How to get material ID of MultiMaterial hierarchy in MaxScript?

Vicent_Chen
Explorer Explorer
1,359 Views
7 Replies
Message 1 of 8

How to get material ID of MultiMaterial hierarchy in MaxScript?

Vicent_Chen
Explorer
Explorer

I need to traverse all the texture faces, and find out which material they were using.

After reading the doc about MaxScript, I can only access the material ID of a face. However, If this material ID points to a MultiMaterial, I am not able to find out which material it is using.

 

I also draw a figure to help clarify my question (and hope it works...).

The arrows from Face1 and Face2 means the material that they are using.

The arrows from MultiMaterial means the sub-materials.

 

Vicent_Chen_0-1666593014087.png

I am also wondering if this material (the MultiMaterial_1 above in figure) is legal. In my understanding, a face can only have one material ID, and there is no sub-material ID. Therefore, which standard material that Face2 is using cannot be identified...

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

denisT.MaxDoctor
Advisor
Advisor

 

 

struct ObjConnection 
(
	obj, 
	subnum = 0, 
	connections = #()
)

fn getMaterialConnection obj subnum:0 items: matonly:on = 
(
	if (not matonly or iskindof obj Material) do  
	(
		item = ObjConnection obj:obj subnum:subnum

		if items == unsupplied then items = item
		else append items item

		picks = getclassinstances (classof obj) astrackviewpick:on
		for pick in picks where pick.anim == obj do
		(
			getMaterialConnection pick.client subnum:pick.subnum items:item.connections matonly:matonly 	
		)
	)
	items
)

fn parseConnections connection prefix:"" = 
(
	format "%%(%)\n" prefix connection.obj.name connection.subnum
	for c in connection.connections do 
	(
		parseConnections c prefix:(prefix + "\t")
	)
)

-- MAKE EXAMPLE:
delete objects
gc()
updatescenemateriallib()

mapped fn nameMaterial mat = 
(
	mat.name = (classof mat) as string + "_0x" + toupper (formattedprint (random 0 0xFFFFFF) format:"06x")
)

mat = 
(
	meditmaterials[1] = mat = Standard name:"MY_MATERIAL"
	meditmaterials[2] = mm0 = Multimaterial()
	meditmaterials[3] = mm1 = Multimaterial()
	mm0[4] = mat
	mm1[4] = mm0
	meditmaterials[4] = mm2 = Multimaterial()
	mm2[1] = mat
	mm2[3] = mm0
	meditmaterials[5] = bm0 = Blend()
	bm0.map1 = mat
	bm0.map2 = mm2
	meditmaterials[6] = bm1 = Blend()
	bm1.map1 = mm1
	bm1.map2 = mm0

	nameMaterial #(mm0, mm1, mm2, bm0, bm1)
	mat
)


-- USING:
/*
--xx = getclassinstances Standard astrackviewpick:on
--for x in xx where x.anim == mat collect x.client
*/
cc = getMaterialConnection mat
parseConnections cc

 

 

 

feel free to ask if you have any questions 

0 Likes
Message 3 of 8

Vicent_Chen
Explorer
Explorer

Thanks for your reply, your script works well and successfully detects sub-materials.

 

It seems that my previous post was not that clear... Here is what I occurred:

I need to traverse all the texture faces, and find out which material they were using.

Now I can only access the material ID of a face. However, If this material ID points to a MultiMaterial, I am not able to find out which material it is using.

 

I also draw a figure to help clarify my question...

The arrows from Face1 and Face2 means the material that they are using.

The arrows from MultiMaterial means the sub-materials.

Vicent_Chen_2-1666592996689.png

 

 

 

 

 

0 Likes
Message 4 of 8

denist.dts
Explorer
Explorer

I think the arrows in your graph should point in the opposite direction if that means the direction of the connection (dependency).

0 Likes
Message 5 of 8

denisT.MaxDoctor
Advisor
Advisor

I think the arrows in your graph should point in the opposite direction if that means the direction of the connection (dependency).

0 Likes
Message 6 of 8

Vicent_Chen
Explorer
Explorer

Oh... I updated it.

The arrows from Face1 and Face2 means the MultiMaterial they are using.

The other arrows mean the sub-material relation.

 

Face1 and Face2 use the MultiMaterial_1.

MultiMaterial_1 has 2 sub-materials: Standard Material 1 and MultiMaterial_2

MultiMaterial_2 has 2 sub-materials: Standard Material 2 and Standard Material 3.

 

I am not able to find out which material Face2 is using, because I can only access its materialID(which is 2, and I can only know it is using the MultiMaterial_2).

0 Likes
Message 7 of 8

denisT.MaxDoctor
Advisor
Advisor
Accepted solution

if you know the face material id, you can get the applied material... different materials per face material id only make sense when a multi-material is applied to the object. When multi-material is sorted, the corresponding materials are applied to the face with the identifier:

getsubmtl object.material id

 

if the multi-material is not sorted, you can search and find the id in the materialIDList of the material.

k = finditem object.material.materialidlist id
getsubmtl object.material k

 

in your case a multi-material 2 is applied to face 2. The multi-material out is always the first sub-material (as I know).  

getsubmtl mat 1
Message 8 of 8

Vicent_Chen
Explorer
Explorer
Thanks again! By the way, your post listed multiple ways to get sub-material, which helps me a lot to reduce my code:)
0 Likes