Home Technical Talk

Maxscript to change the diffuse and ambient colour of all materials.

polycounter lvl 5
Offline / Send Message
deohboeh polycounter lvl 5
for obj in selection do
 ((
	 int $.i = $.material.materialList.count;
	if ($.i) do
	 	 for mat in $.material.materialList do
		 $.diffuse = color 255 255 255 
		 $.ambient = color 255 255 255
else	(
		$.diffuse = color 255 255 255 
		$.ambient = color 255 255 255
	)
 ))

Absolute noob here with absolute noob question:

Why is this not working?

This script is supposed to change the diffuse and ambient colour of all the materials even the multimaterials.

it gives me the Error:

-- Error occurred in anonymous codeblock; filename: ; position: 205; line: 8
-- Syntax error: at else, expected <factor>
-- In line: else (


Any help is much appreciated! :)

Replies

  • monster
    Options
    Offline / Send Message
    monster polycounter
    There are several errors in your script, but the logic is sound.
    This should help you out.
    (
    	--FUNCTION TO TEST AND UPDATE A PROPERTY
    	fn SetColor mat prop col =
    	(
    		if isProperty mat prop do
    		(
    			setProperty mat prop col
    		)
    	)
    
    	--FUNCTION TO CHANGE THE PROPERTY OR RECURSE
    	fn ChangeMaterialColor mats col =
    	(
    		for mat in mats do
    		(
    			if classof mat == MultiSubMaterial then
    			(
    				ChangeMaterialColor mat col
    			)
    			else
    			(
    				SetColor mat #diffuseColor col
    				SetColor mat #ambientColor col
    			)
    		)
    	)
    	
    	--CHANGE ALL MATERIALS
    	ChangeMaterialColor SceneMaterials white
    )
    
  • deohboeh
    Options
    Offline / Send Message
    deohboeh polycounter lvl 5
    monster wrote: »
    There are several errors in your script, but the logic is sound.
    This should help you out.
    (
    	--FUNCTION TO TEST AND UPDATE A PROPERTY
    	fn SetColor mat prop col =
    	(
    		if isProperty mat prop do
    		(
    			setProperty mat prop col
    		)
    	)
    
    	--FUNCTION TO CHANGE THE PROPERTY OR RECURSE
    	fn ChangeMaterialColor mats col =
    	(
    		for mat in mats do
    		(
    			if classof mat == MultiSubMaterial then
    			(
    				ChangeMaterialColor mat col
    			)
    			else
    			(
    				SetColor mat #diffuseColor col
    				SetColor mat #ambientColor col
    			)
    		)
    	)
    	
    	--CHANGE ALL MATERIALS
    	ChangeMaterialColor SceneMaterials white
    )
    

    Thank you so much Juan! :poly136:

    The script works perfectly and I also got to learn some new things!

    Could you tell me what the errors in my script were? It would be awesome if I could know where I went wrong! :D
  • rollin
    Options
    Offline / Send Message
    rollin polycounter
    several. Best is you would try to debug your script yourself error by error..

    As a start: the first error tells you that the 'else' statement is in a wrong place .. and that is because it must follow an if

    you can write:

    if ... then
    ...
    else
    ...

    or you can write:

    if ... then
    (
    ...
    ...
    ...
    )
    else
    (
    ...
    ...
    ...
    )

    but you can not write:

    if ... then

    ... ( <- bc here is the end of the 'if' if you don't use brackets )
    ... ( <- if there should be an else it must stand here)
    ...

    else
    (
    ...
    ...
    ...
    )
  • monster
    Options
    Offline / Send Message
    monster polycounter
    Here's some comments.
    [COLOR="Green"]--NOTHING WRONG WITH THIS LINE, EXCEPT IN MAXSCRIPT IF YOU HAVE AN ELSE CLAUSE YOU NEED TO USE "THEN" NOT "DO"[/COLOR]
    for obj in selection do
    [COLOR="Green"]--THE BRACKET DOESN'T NEED TO BE DOUBLE UP[/color]
     ((
    [COLOR="Green"]	 --YOU DON'T DECLARE VARIABLES IN MAXSCRIPT OR END LINES WITH A SEMI-COLON
    	 --"$.i" HAS NO MEANING. THIS WOULD BE THE CORRECT WAY TO WRITE THIS LINE
    	 -- i = $.material.materialList.count
    	 --HOWEVER THIS WOULD THROWN AN ERROR ON A STANDARD MATERIAL
    	 --ALSO YOU ARE ONLY GETTING THE CURRENT SELECTED OBJECTS MATERIALS[/COLOR]
    	 int $.i = $.material.materialList.count;
    [COLOR="green"]	 --AGAIN "i" IS NOT A PROPERTY OF $ (SELECTED OBJECT)
    	 --YOU DON'T NEED BRACKETS BETWEEN IF/DO[/COLOR]
    	if ($.i) do
    [COLOR="green"]	 --IN MAXSCRIPT YOU NEED A BRACKETS IF YOUR EXPRESSION IS MORE THAN ONE LINE
    	 --(
    		--THIS LINE IS TECHNICALLY CORRECT, BUT ASSUMES WE HAVE A MULTIMATERIAL
    		--IT WOULD ALSO LOOP THE SELECTED OBJECT'S MATERIAL NOT ALL MATERIALS[/COLOR]
    	 	 for mat in $.material.materialList do
    [COLOR="green"]		 --(
    		 --AGAIN $ IS THE SELECT OBJECT NOT A MATERIAL
    		 --DIFFUSE IS NOT A MATERIAL PROPERTY "DIFFUSECOLOR" AND "DIFFUSEMAP" ARE PROPERTIES
    		 --SEVERAL COLORS ARE PREDECLARED IN MAXSCRIPT.
    		 --mat.diffuseColor = white[/COLOR]
    		 $.diffuse = color 255 255 255 
    [COLOR="green"]		 --mat.ambientColor = white[/COLOR]
    		 $.ambient = color 255 255 255
    [COLOR="green"]		 --)
    	 --)
    	--ELSE ONLY WORKS WITH IF/THEN[/COLOR]
    	else	(
    [COLOR="green"]	--SAME ISSUES AS ABOVE, BUT NOT ALL MATERIAL TYPES HAVE DIFFUSECOLOR PROPERTIES[/COLOR]
    		$.diffuse = color 255 255 255 
    		$.ambient = color 255 255 255
    	)
     ))
     
    [COLOR="green"] --WHILE YOU ARE TRYING TO HANDLE THE DIFFERENCE BETWEEN MULTI AND STANDARD MATERIALS, YOU AREN'T HANDLING ALL SCENE MATERIALS.
     --AND YOU NEED RECURSION TO HANDLE MULTIMATERIALS INSIDE OF MULTIMATERIALS[/COLOR]
    
  • deohboeh
    Options
    Offline / Send Message
    deohboeh polycounter lvl 5
    rollin wrote: »
    several.

    Thanks for the help Till! I tried to debug it but I didnt know that then was a necessity. I think I glossed that over. Thanks again! :D
    monster wrote: »
    Here's some comments.

    Thanks again Juan! :D This has been super informative! I didn't know about the proper syntax of maxscript. I think I'll go read some more into it! From now on $ is for defining properties. :)
  • d1myan
    Options
    Offline / Send Message
    d1myan polycounter lvl 3
    monster said:
    There are several errors in your script, but the logic is sound.
    This should help you out.
    (
    	--FUNCTION TO TEST AND UPDATE A PROPERTY
    	fn SetColor mat prop col =
    	(
    		if isProperty mat prop do
    		(
    			setProperty mat prop col
    		)
    	)
    
    	--FUNCTION TO CHANGE THE PROPERTY OR RECURSE
    	fn ChangeMaterialColor mats col =
    	(
    		for mat in mats do
    		(
    			if classof mat == MultiSubMaterial then
    			(
    				ChangeMaterialColor mat col
    			)
    			else
    			(
    				SetColor mat #diffuseColor col
    				SetColor mat #ambientColor col
    			)
    		)
    	)
    	
    	--CHANGE ALL MATERIALS
    	ChangeMaterialColor SceneMaterials white
    )
    
    Hi. How to modify this script for Vray Material ?

  • monster
    Options
    Offline / Send Message
    monster polycounter
    Sorry, I don't use Vray. But you can change the property names in line 22 and 23 to the vray property names.

    To find the Vray property names you can probably select one object with a vray material and run this command:

    show $.material

  • d1myan
    Options
    Offline / Send Message
    d1myan polycounter lvl 3
  • Eric Chadwick
    Options
    Offline / Send Message
    Consistently helpful through the years, that's our monster. Thumbs up!
  • Justo
    Options
    Offline / Send Message
    Justo polycounter
    Juan Monster Martinez is the bessst.  
  • monster
    Options
    Offline / Send Message
    monster polycounter
  • d1myan
    Options
    Offline / Send Message
    d1myan polycounter lvl 3
    Hi. Now the script for Vray
    (
    there was another problem:
    mat 1 = multimaterial
    mat 2 = Vray2SidedMtl
    how to change the color in the material 3 ?
    I understand you don't work with Vray, but can you tell me the basis?
    I can't build

  • monster
    Options
    Offline / Send Message
    monster polycounter
    Instead of looping the scene materials, we can just collect all the materials of a class.

    In the following code you you need to replace standardmaterial with the class name of the VRay materials. You can get the class of a VRay material by applying it to an object and running this snip: 
    classof $.material


    (
    setProperty (getclassinstances standardmaterial) #diffuseColor black
    )

  • d1myan
    Options
    Offline / Send Message
    d1myan polycounter lvl 3
    All work, Thanks.
    Still the latest question:
    in scene one object
    As off "show shaded Material in viewport" in all bitmaps and material ?

    found a similar, but not the
    http://forums.cgsociety.org/archive/index.php?t-1083444.html
  • tmiller
    Options
    Offline / Send Message
    monster said:
    There are several errors in your script, but the logic is sound.
    This should help you out.
    (
    	--FUNCTION TO TEST AND UPDATE A PROPERTY
    	fn SetColor mat prop col =
    	(
    		if isProperty mat prop do
    		(
    			setProperty mat prop col
    		)
    	)
    
    	--FUNCTION TO CHANGE THE PROPERTY OR RECURSE
    	fn ChangeMaterialColor mats col =
    	(
    		for mat in mats do
    		(
    			if classof mat == MultiSubMaterial then
    			(
    				ChangeMaterialColor mat col
    			)
    			else
    			(
    				SetColor mat #diffuseColor col
    				SetColor mat #ambientColor col
    			)
    		)
    	)
    	
    	--CHANGE ALL MATERIALS
    	ChangeMaterialColor SceneMaterials white
    )
    
    How would you go about assigning different random colors to materials instead of all white?
Sign In or Register to comment.