Notifications
Clear all

[Closed] Script…Groups To Materials??

I’m hoping someone knows of a script (or could possibly make one?) that will take all of the Groupings and make them into Materials. So if I have an object with the Groups: Window, WindowFrame and WindowPanes…then the script would automatically take the group name and apply a Material of the same name to that group. So now my Window group would have a Window material applied to it, the WindowFrame group would have a WindowFrame material applied to it…and just a regular plain jane Standard material would be perfect.

Thanks so much for your help.

14 Replies

the question is – where does the tool get these materials? material library? material editor?

How about the “Standard” shader from Materials in the Material Editor.

1 Reply
(@denist)
Joined: 10 months ago

Posts: 0

in the material editor only 24 materials can be stored… it might be multi-materials of course, but it’s still a limitation

ok. the script itself is simple… i use meditmaterials as a material library. but any material library might be use as well… here is a tool.


try(destroydialog ApplyGroupMaterialsDialog) catch()
rollout ApplyGroupMaterialsDialog "Group Materials" width:200 
(
	mapped fn applyGroupMaterial node = if isgrouphead node and (mat = meditmaterials[node.name]) != undefined do 
	(
		members = for member in (join #() node) where isgroupmember member and not isgrouphead member collect member  
		members.material = mat
	)
	button apply_bt "Apply Group Material" width:190 align:#right offset:[8,0]
	on apply_bt pressed do undo "Apply Group Material" on 
	(
		applyGroupMaterial selection
		redrawviews()
	)
)
createdialog ApplyGroupMaterialsDialog

create scene with groups, put specific material for every group in material editor with the same name as a group.
select what you want to apply material to and press the button.

Thank you DenisT for helping me out, it is really most appreciated.
I believe that I am not explaining correctly what I am wishing for so let me try another road.

Lets say that you create a Box, a Cylinder and a Torus on stage and then convert them to editable polys, now export them as obj’s. If you open that obj with a UV program/app you see that you have 3 groups (Box001, Cylinder001, Torus001) and 3 materials (wire_088199225, wire_140088225, wire_141007058).
The script I am looking for would be applied before I exported the above. It would automatically change the material wire_088199225 to material Box001, material wire_140088225 to material Cylinder001 and material wire_141007058 to material Torus001… or whatever those groups were named as then the materials would also be named as. The actual physical shader inside of Max is not important as I am applying Materials in another app. If it is easier to have everything made into a multi-sub object material so we don’t run out of material space, that is cool too.
It doesn’t matter if the group to material conversion is automatic (all groups even those hidden), or if it is to what’s selected on stage, or to what is physically on stage…whatever is easiest. If I had my druthers I would probably say for convert to what’s selected.

If by chance your already created script does what I just got done asking for, then my apologies I am too dense to make it happen. Could you provide a brief step by step?

Thanks again for your time and help.

Try this and tell me what you think.
This script supports Primitives, E-Poly, E-Mesh, E-Patch and shapes.
If object have only one material ID then script will assigne Standardmaterial named as object and diffuse color is same as object wirecolor.
In case where object contains more then one mtlID then script will assigne Multimaterial with randomized diffuse colors for submaterials.


 try(destroyDialog ::bgaRoll)catch()
 rollout bgaRoll "• • •"
 (
 	fn getMtlIDList sel = if isKindOf sel GeometryClass or isKindOf sel Shape do
 	(
 		local idArr = #(), getNFP, getMtlID, isShepe = false
 		local objClasses = #(Editable_Poly,PolyMeshObject,Editable_Patch,Editable_mesh,TriMesh)
 		sel = if isKindOf sel GeometryClass and canconvertto sel objClasses[4] and finditem objClasses (classof sel) == 0 then snapshotAsMesh sel else sel
 		case of 
 		(
 			(isKindOf sel objClasses[1] or isKindOf sel objClasses[2]): (getNFP = polyop.getNumFaces ; getMtlID = polyop.getFaceMatID)
 			(isKindOf sel objClasses[3]): (getNFP = patch.getNumPatches ; getMtlID = patch.getPatchMtlID)
 			(isKindOf sel objClasses[4] or isKindOf sel objClasses[5]): (getNFP = getNumFaces ; getMtlID = getFaceMatID)
 			(isKindOf sel Shape): (idArr=#(1) ; isShepe = true)
 		)
 		if isShepe then idArr else (for i = 1 to (getNFP sel) where findItem idArr (idNum = getMtlID sel i) == 0 do append idArr idNum)
 		if isKindOf sel objClasses[5] do delete sel
 		return (sort idArr)
 	)	
 
 	checkbox cb "Consider Only Selected Objects" pos:[5,5]
 	button btn_mat "Assign Materials" pos:[5,25] width:190 height:20
 	button btn_wire "Randomize Wirecolor" pos:[5,50] width:190 height:20
 	
 	on btn_mat pressed do
 	(
 		local collections = if cb.checked and selection.count != 0 then selection else objects
 		for o in collections do
 		(
 			if (idArr = getMtlIDList o) != undefined do
 			(
 				if idArr.count == 1 then (o.material = Standardmaterial name:o.name diffuse:o.wirecolor) else
 				(
 					o.material = multiSubMaterial \
 					materialList:(for i = 1 to idArr.count collect Standardmaterial name:(o.name+"_Sub"+i as string) diffuse:(clr = random black white ; clr.s = 255. ; clr)) \
 					materialIDList:idArr
 				)
 			)
 		) ; free collections
 	)
 	on btn_wire pressed do
 	(
 		local collections = if cb.checked and selection.count != 0 then selection else objects
 		for o in collections do o.wirecolor = (clr = random black white ; clr.s = 255. ; clr) ; free collections
 	)
 )
 createDialog bgaRoll 200 75 10 110 style:#(#style_titlebar, #style_sysmenu, #style_toolwindow)
 

in short… you simply need a tool that sets or renames existing materials of specified nodes with the same name as a node:


try(destroydialog MaterialsOpsDialog) catch()
rollout MaterialsOpsDialog "Material Ops" width:200 
(
	mapped fn nameMaterial node = if node.mat != undefined then node.mat.name = node.name else node.mat = Standard name:node.name diffuse:node.wirecolor 

	button apply_bt "Name Materilas" width:190 align:#right offset:[8,0]
	on apply_bt pressed do undo "Name Materilas" on nameMaterial selection
)
createdialog MaterialsOpsDialog

DarkEdge, do you just want to apply basic materials with matching names to objects?

If so, that’s pretty simple:

for obj in selection do (obj.material = (StandardMaterial name:obj.name))

You mention “groups” which I think is confusing matters – how are your objects actually set up?

3 Replies
(@gazybara)
Joined: 10 months ago

Posts: 0

You forget that some objects have more then one FaceMtlID’s. Only assigning standard (single) material is the bad choise. In my example you can see solution for that problem.

(@selectnone)
Joined: 10 months ago

Posts: 0

Yeah, but that depends on what the original poster is actually looking for –

If each object just needs one material with a specific name, then there’s no need to over-complicate

(@denist)
Joined: 10 months ago

Posts: 0

the solution is incomplete. who said that Shape can’t have multiple material ids?

Yup. Not need to but just in case…
Cheers!

If use shape with “Enabled In Viewport” checked he can export shape as geometry with material. In my code I not use any mtlID checking for Shape but only set to 1 (mean 1 material)

Page 1 / 2