Community
3ds Max Programming
Welcome to Autodesk’s 3ds Max Forums. Share your knowledge, ask questions, and explore popular 3ds Max SDK, Maxscript and Python topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

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

14 REPLIES 14
SOLVED
Reply
Message 1 of 15
ADSK2007
1160 Views, 14 Replies

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

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

14 REPLIES 14
Message 2 of 15
denisT.MaxDoctor
in reply to: ADSK2007

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)

 

Message 3 of 15
ADSK2007
in reply to: denisT.MaxDoctor

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

Message 4 of 15
ADSK2007
in reply to: denisT.MaxDoctor

Hi Denis

The script is working perfectly. Thank you for your script

 

Best Regards

Adsk

Message 5 of 15
ADSK2007
in reply to: denisT.MaxDoctor

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

Tags (3)
Message 6 of 15
denisT.MaxDoctor
in reply to: ADSK2007

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

Message 7 of 15

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

Message 8 of 15
ADSK2007
in reply to: denisT.MaxDoctor

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

Message 9 of 15
denisT.MaxDoctor
in reply to: ADSK2007


@ADSK2007 wrote:

Again, that you for your great help

 


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

Message 10 of 15
ADSK2007
in reply to: denisT.MaxDoctor

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

Message 11 of 15
denisT.MaxDoctor
in reply to: ADSK2007


@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.

 

Message 12 of 15
ADSK2007
in reply to: denisT.MaxDoctor

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

 

Cheers

Adsk

Message 13 of 15
ADSK2007
in reply to: ADSK2007

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()

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

 

 

Message 14 of 15
denisT.MaxDoctor
in reply to: ADSK2007

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*"

Message 15 of 15
ADSK2007
in reply to: denisT.MaxDoctor

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

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report