Notifications
Clear all

[Closed] help: convert the classof material

can anybody tell me how can convert the classof material…
for example i have many object in my scene and more classof materials
when i convert the material from using the object’s the script make material for every object’s it make the many same material for every… so
i thinking to use loop for sceneMaterials…
like…
stndrd_mat = for i in sceneMaterials where classof i == Standardmaterial collect i
but i can’t make i to be other material like…
i=RaytraceMaterial

4 Replies

[size=2]scenematerials is read-only so you’d have to do it via objects $.material = raytracematerial () or you can copy them into the material editor like this

for i = 1 to scenematerials.count where classof scenematerials[i] == standardmaterial do
(
meditmaterials[1] = scenematerials[i]
meditmaterials[1] = raytracemateral ()
)

[/size]

1 Reply
(@system)
Joined: 11 months ago

Posts: 0

thank you for replay

but i thinking like that but i asking myself what if [size=2]scenematerials have more than 24 it’s will make a problem and i can’t to use the selection $.material becouse i do it already but i found max make many copy of the same material however this material.
for example if i have two objects and they have material raytrace if i use the $.material i will have the same two material to this objects.

i need to solve this problem by convert the node of material… and at last i found something like that in vray macroscripts … vray made the macroscript to convert material to others in vray but i still trying to understand it from yesterday i trying to use it in my script like i want… but if someone have a good plane … it’s a welcome…
[/size]

Material conversion in Max is not so easy to perform. In fact when you convert a material to an other type you have to reassign all the bitmaps/textures/maps and the additional informations.
Also, when you convert a material I always recommend the artist to save the scene with the old materials, because after conversion they are lost.
And of course, you cannot modify scene materials like you did. You have to use obj.material to set the converted material (parsing all scene node objects). This is why old materials are lost Material Editor is just used to edit materials, not to store them

So, in your code you have to convert all the materials of a scene and assign them to the objects using them. Not: convert all the materials used by the scene objects because one material can be used by several nodes.
This is different and your code will be fastest.

Here is a macroscript I’ve coded. It was used in a video game production that got cancelled. The code is provided as is:

macroScript BATCH_DXMATERIAL_CONVERSION
 	category:"PHOENIX"
 	buttonText:"Convert Selection to DX Material"
 	toolTip:""
 (
 
 -- Convert a standard material to a Rayman Material
 -- Return the new material created
 fn std2rayman oldmat bSuffix =
 (
 	local newmat = undefined
 
 	newmat = Rayman_Material()
 	
 	newmat.name = oldmat.name
 	
 	if( bSuffix ) do
 	(
 		newmat.name += "_dx"
 	)
 	
 	-- Get diffuse map
 	diffusemap = oldmat.diffuseMap
 	if( diffusemap != undefined ) do
 	(
 		if( classOf diffusemap == bitmaptexture ) do
 		(
 			-- Set properties for the first texture
 			newmat.Map1File	  = diffusemap.filename
 			newmat.Map1FileShort = diffusemap.filename
 		)
 	)
 	
 	newmat
 )
 
 -- Return an array containing the materials from the selection
 fn getMtlsFromObjects Objs =
 (
 	MtlsArray = #()
 	
 	for obj in Objs do
 	(
 		-- Append a material once
 		Idx = findItem MtlsArray obj.material
 		if( Idx == 0 ) do
 		(
 			append MtlsArray obj.material
 		)
 	)
 	
 	MtlsArray
 )
 
 -- Process all objects in Objs
 fn ProcessObject Objs Mtls =
 (
 	ObjectsToUpdate = Objs
 	
 	local bDXSuffix
 	
 	if( querybox("Export with \"_dx\" suffix ?") title:"DX Material Conversion" ) then
 	(
 		bDXSuffix = true
 	)
 	else
 	(
 		bDXSuffix = false
 	)
 	
 	for Mtl in Mtls do
 	(
 		if( classof Mtl == standardMaterial ) then
 		(
 			newmtl = std2rayman Mtl bDXSuffix
 			if( newmtl != undefined ) do
 			(
 				-- Assign material to all the objects having material newmultimtl
 				for obj in ObjectsToUpdate do
 				(
 					if( obj.material == Mtl ) do
 					(
 						obj.material = newmtl
 					)
 				)
 			)
 		)
 		else if( classof Mtl == multimaterial ) then
 		(
 			newmultimtl = multimaterial numsubs:Mtl.numsubs
 			newmultimtl.name = Mtl.name
 			
 			if( bDXSuffix ) do
 			(
 				newmultimtl.name += "_multidx"
 			)
 			
 			-- Parse all materials of the multimaterial
 			for i = 1 to Mtl.materialList.count do
 			(
 				-- Convert current submap only if standardmaterial
 				if( classof Mtl.materialList[i] == standardMaterial ) do
 				(
 					 newmtl = std2rayman Mtl.materialList[i] bDXSuffix
 					 if( newmtl != undefined ) do
 					 (
 						 newmultimtl.materialList[i] = newmtl
 						 newmultimtl.names[i] = Mtl.names[i]
 						 newmultimtl.materialIDList[i] = Mtl.materialIDList[i]
 					 )
 				)
 			)
 			
 			-- Assign material to all the objects having material newmultimtl
 			for obj in ObjectsToUpdate do
 			(
 				if( obj.material == Mtl ) do
 				(
 					obj.material = newmultimtl
 				)
 			)
 		)
 	)
 )
 
 on execute do
 (
 	local SelObjects, SceneObjects
 	
 	SelObjects   = (getCurrentSelection() as array)
 	SceneObjects = (objects as array)
 	
 	--Mtls = sceneMaterials
 	Mtls = ((getMtlsFromObjects SelObjects) as array)
 	
 	if( SelObjects.count > 0 ) then
 	(
 		ProcessObject SceneObjects Mtls
 		
 	)
 )
 
 )
 

i found good idea to solve it try it i wait the comment


 stndrd_mat = for i in sceneMaterials where classof i == Standardmaterial collect i
 for i=1 to stndrd_mat.count do
 (
 	obj_mat = for o in objects where o.material == stndrd_mat[i] collect o
 	new_mat = Brazil_Advanced ()
 	new_mat.bmtl_Cs_color = stndrd_mat[i].diffuse
 	new_mat.name = "Brazil Convert " + stndrd_mat[i].name as string
 	for o in obj_mat do
 	(
 	o.material = new_mat
 	)
 )