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.

Apply material from material browser to selected objects, render, save jpg image

Apply material from material browser to selected objects, render, save jpg image

ADSK2007
Enthusiast Enthusiast
1,858 Views
14 Replies
Message 1 of 15

Apply material from material browser to selected objects, render, save jpg image

ADSK2007
Enthusiast
Enthusiast

Good Morning

 

I have been searching for a Max script to do the following with no luck. I was wondering if someone here can help me with this.

The scene is prepared with lights and one camera, objects are already selected in the scene with 24 materials in material browser. What I need is a script to do the steps below

 

1- Apply 1st material from Material browser to selected objects
2- Render the scene
3- Save the image in a directory with a name specified in the script. (The name needs to be modified in the script for each render)
4- Apply 2nd material from material browser to the same selected object
5- Render the scene
6- Save the image with the name specified in the script file

Repeat this until all materials in browser are rendered.

 

I appreciate any help I can get with this.

 

Best Regards

Fred

0 Likes
1,859 Views
14 Replies
Replies (14)
Message 2 of 15

denisT.MaxDoctor
Advisor
Advisor
Accepted solution

try this:

/*
print (for k=1 to 24 collect ("scene_" + formattedprint k format:"02d"))
*/

fn customRenderScene = 
(
	local nodes = selection as array
	local cam = cameras[1]
	
	local image_names = 
	#(
		"scene_01",
		"scene_02",
		"scene_03",
		"scene_04",
		"scene_05",
		"scene_06",
		"scene_07",
		"scene_08",
		"scene_09",
		"scene_10",
		"scene_11",
		"scene_12",
		"scene_13",
		"scene_14",
		"scene_15",
		"scene_16",
		"scene_17",
		"scene_18",
		"scene_19",
		"scene_20",
		"scene_21",
		"scene_22",
		"scene_23",
		"scene_24"
	)
	
	local dir = @"d:/temp/"
	local type = ".bmp"
	
	if nodes.count > 0 and iskindof cam Camera do
	(
		local bmps = for k=1 to 24 where iskindof (mat = meditmaterials[k]) Material collect
		(
			nodes.material = mat
			image_name = dir + image_names[k] + type
			format "% >> " k
			bmp = render cam:cam outputfile:image_name
			format "%\n" bmp
			
			bmp
		)
	)
)

bmps = customRenderScene()

i just generated image names, but you have to put names that you need, as well as specify output directory (dir) and image format (type)

 

0 Likes
Message 3 of 15

ADSK2007
Enthusiast
Enthusiast

Good Morning

 

Thank you very much for your help. I will give it a try and let you know if I have any problems

 

Best Regards

Adsk

0 Likes
Message 4 of 15

ADSK2007
Enthusiast
Enthusiast
Accepted solution

Hi Denis

The script is working perfectly. Thank you for your script

 

Best Regards

Adsk

0 Likes
Message 5 of 15

ADSK2007
Enthusiast
Enthusiast

Hello again

This script works great and I just wanted to add another thing to the script.

Is it possible to modify the code so that when all 24 renders are finished, the script merge another 3dsMax file and start rendering another 24 renders? Below is the steps

 

1- Assign all materials in material browser and render 24 images (just like the script you provided)

2- Once finished rendering, delete selected objects and merge another file from specified directory

3- Merge only objects that their name starts with "TUB"

4- Repeat step 1, 2 & 3

 

I need to merge 40 files into this scene and render 24 different materials on every merged objects

This will save me a lot of time if I could have the program merge objects, and render 24 hours none stop. That way the machine won't stop once all 24 renders are done

 

Thank you

Adsk

0 Likes
Message 6 of 15

denisT.MaxDoctor
Advisor
Advisor
Accepted solution

First of all:

1. Don't continue your topic if the solution is already found and marked. Not many people look into already solved topics to help.

2. Don't mark your own post as solved if it's not  a real solution.  

 

fn customRenderScene dir: prefix:"" = 
(
	local nodes = selection as array
	local cam = cameras[1]
	
	local image_names = 
	#(
		"scene_01",
		"scene_02",
		"scene_03",
		"scene_04",
		"scene_05",
		"scene_06",
		"scene_07",
		"scene_08",
		"scene_09",
		"scene_10",
		"scene_11",
		"scene_12",
		"scene_13",
		"scene_14",
		"scene_15",
		"scene_16",
		"scene_17",
		"scene_18",
		"scene_19",
		"scene_20",
		"scene_21",
		"scene_22",
		"scene_23",
		"scene_24"
	)
	
	if dir == unsupplied do dir = @"d:/temp/"
		
	local type = ".bmp"
	
	if nodes.count > 0 and iskindof cam Camera do
	(
		num_mats = 24
		
		for k=1 to num_mats where iskindof (mat = meditmaterials[k]) Material do
		(
			if keyboard.escpressed do (return false)
			
			nodes.material = mat
			image_name = dir + (prefix + image_names[k]) + type
			format "\t% >> " k
			bmp = render cam:cam outputfile:image_name
			format "%\n" bmp
			
			bmp
		)
		return true
	)
	return false
)
--bmps = customRenderScene()


fn mergeAndRender dir: = 
(
	dir = "d:/temp/test_for_delete/variants/" -- path for source files 
	files = getfiles (dir + "*.max")
	
	out_render_path = "d:/temp/test_for_delete/images/" -- path where to save render (must exist!!!)
	
	pattern = "box*" -- pattern for objects to load
	
	out = false
	
	for file in files do
	(
		if out or (out = keyboard.escpressed) do
		(
			format "\t\tCANCELED BY INTERRUPTION\n"
			return ()
		)
		
		format "file: % ...\n" file 
		if (getFileAttribute file #readonly) then
		(
			format "\tSKIPPED AS READONLY\n"
		)
		else
		(
			all_names = getMAXFileObjectNames file quiet:on
			names = for name in all_names where matchpattern name pattern:pattern collect name
			with printallelements on format "\tnodes:%\n" names	
				
			delete selection
			mergemaxfile file names #select #alwaysReparent #deleteOldDups #useSceneMtlDups quiet:on
			
			prefix = tolower (getFilenameFile file) + "_" 
			
			res = customRenderScene dir:out_render_path prefix:prefix
			
			if not res then
			(
				format "\n\t\tINTERRUPTED BY CONDITION\n"
				return #abort
			)
			else
			(
				format "\tDONE\n"
			)
		)
	)
	#done
)

/********** USING *************

mergeAndRender()

*****************************/

check my comments and setup the script as you need. Ask questions if you have any.

 

 

 

PS. For everyone who might be interested in this script:

 

this is not a good example how to make tools, it's only a quick and dirty snippet of a script for immediate needs

0 Likes
Message 7 of 15

denisT.MaxDoctor
Advisor
Advisor

PPS: i skip on merge all files marked by #readonly attribute (in case if you need re-render only specific files)

0 Likes
Message 8 of 15

ADSK2007
Enthusiast
Enthusiast

Hi Denis

I got what you said and won't re-open / add to an already closed post again.

Again, that you for your great help

Best Regards

Adsk

0 Likes
Message 9 of 15

denisT.MaxDoctor
Advisor
Advisor

@ADSK2007 wrote:

Again, that you for your great help

 


let us know how it works, as well as any bugs found.

0 Likes
Message 10 of 15

ADSK2007
Enthusiast
Enthusiast

Denis

Won't be able to test the script now as I am in the middle of rendering. I will test it tomorrow morning with a dummy file.

My only concern is, (since I am naming all render images as ex. PAT-01, PAT-02, etc.) will my previous rendered images be re-written when the next merged objects start rendering?  Will it over write PAT-01, PAT-02, etc.?

I am not expert in scripting and won't be able to test it until tomorrow but that's what worried me

 

Cheers

Adsk

0 Likes
Message 11 of 15

denisT.MaxDoctor
Advisor
Advisor

@ADSK2007 wrote:

My only concern is, (since I am naming all render images as ex. PAT-01, PAT-02, etc.) will my previous rendered images be re-written when the next merged objects start rendering?  Will it over write PAT-01, PAT-02, etc.?

 


i add prefix to every image file based on source filename (lower case). In your case it will look:

source file - "a.max"

        images: "a_PAT-01", "a_PAT-02", "a_PAT-03", etc.

source file - "Test.max"

        images: "test_PAT-01", "test_PAT-02", "test_PAT-03", etc.

 

			prefix = tolower (getFilenameFile file) + "_" 
			
			res = customRenderScene dir:out_render_path prefix:prefix

 

you can change this rule if you want

 

PS. Forgot to say.. You may interrupt the batch process by pressing ESCAPE. It might not interrupt a current render process (it depends on your system settings), but breaks loop cycles.

 

0 Likes
Message 12 of 15

ADSK2007
Enthusiast
Enthusiast

Got it, thank you. I'll post tomorrow my results

 

Cheers

Adsk

0 Likes
Message 13 of 15

ADSK2007
Enthusiast
Enthusiast
Accepted solution

Ok, I just did a test and the script does nothing. This is what I changed in your script

1- Placed all remaining Max files (33 files that need to be merged and rendered) in "c:/temp/"

2- Set Max directory to "c:/temp/"

2- For rendering path I also gave "c:/temp/"

3- Pattern for Objects to load is "3_4SQ*"

4- All Materials are named properly in the script (same as what I have in my mat Browser)

5- Changed file format to Local type = ".jpg"

6- Created a dummy file selected 3 objects that need their material to change

7- Ran the script

8- Nothing is happening - don't know what I did wrong

below is the script modified with new names and path

-----------------------------------

fn customRenderScene dir: prefix:"" =
(
local nodes = selection as array
local cam = cameras[1]

local image_names =
#(
"ANTIQUE BRASS",
"ANTIQUE COPPER",
"ANTIQUE GOLD",
"BRUSHED CHROME",
"BRUSHED NICKEL",
"BRUSHED STAINLESS STEEL",
"SATIN BRASS",
"SATIN BRONZE",
"SATIN COPPER",
"SATIN CHAMPIGNE",
"SATIN GOLD",
"SATIN CHROME",
"SATIN NICKEL",
"POLISHED CHROME",
"POLISHED NICKEL",
"POLISHED STAINLESS STEEL",
"POLISHED BRASS",
"POLISHED COPPER",
"POLISHED ALUMINUM",
"MATTE ALUMINUM",
"MATTE IRON",
"OIL RUBBED BRONZE",
"MATTE BLACK",
"MATTE WHITE"
)

if dir == unsupplied do dir = @"C:/temp/"

local type = ".jpg"

if nodes.count > 0 and iskindof cam Camera do
(
num_mats = 24

for k=1 to num_mats where iskindof (mat = meditmaterials[k]) Material do
(
if keyboard.escpressed do (return false)

nodes.material = mat
image_name = dir + (prefix + image_names[k]) + type
format "\t% >> " k
bmp = render cam:cam outputfile:image_name
format "%\n" bmp

bmp
)
return true
)
return false
)
--bmps = customRenderScene()


fn mergeAndRender dir: =
(
dir = "c:/temp/" -- path for source files
files = getfiles (dir + "*.max")

out_render_path = "c:/temp/" -- path where to save render (must exist!!!)

pattern = "3_4SQ*" -- pattern for objects to load

out = false

for file in files do
(
if out or (out = keyboard.escpressed) do
(
format "\t\tCANCELED BY INTERRUPTION\n"
return ()
)

format "file: % ...\n" file
if (getFileAttribute file #readonly) then
(
format "\tSKIPPED AS READONLY\n"
)
else
(
all_names = getMAXFileObjectNames file quiet:on
names = for name in all_names where matchpattern name pattern:pattern collect name
with printallelements on format "\tnodes:%\n" names

delete selection
mergemaxfile file names #select #alwaysReparent #deleteOldDups #useSceneMtlDups quiet:on

prefix = tolower (getFilenameFile file) + "_"

res = customRenderScene dir:out_render_path prefix:prefix

if not res then
(
format "\n\t\tINTERRUPTED BY CONDITION\n"
return #abort
)
else
(
format "\tDONE\n"
)
)
)
#done
)

/********** USING *************

mergeAndRender()

*****************************/

 

 

0 Likes
Message 14 of 15

denisT.MaxDoctor
Advisor
Advisor
Accepted solution

pattern = "3_4SQ*" 

 

this is the thing. 

 

pattern is a prefix of node names we need to merge. following your original post it must be "TUB*"

0 Likes
Message 15 of 15

ADSK2007
Enthusiast
Enthusiast

Ok, I just changed the node name from 3_4 TUBE to TUB and ran the script. It seems to work ok now.

Thank you for your great help Denis. I am going to accept the solution

Cheers

Adsk

0 Likes