Confused by Net Render Syntax


saving to PNG is easy enough - set the filename extension to “.png”
8-bit is the more difficult bit - have a play with the PNGio interface:

showinterfaces PNGio
  Interface: ipngio
	   getType enums: {#paletted|#true24|#true48|#gray8|#gray16
	<void>setType <enum>type
	   type enums: {#paletted|#true24|#true48|#gray8|#gray16}
	<void>setAlpha <boolean>useAlpha
	<void>setInterlaced <boolean>Interlaced

However, I’m not entirely clear on how / if this actually gets stored with the scene file for file output straight out of the render (i.e. not handled yourself by saving the bitmap via scripting). Max is severely lacking the bitmap i/o access as far as that goes.


Again code will help. Most of the time when using a pickbutton the code is executed after the pick using the on <pickbutton> picked <arg> do <expr> syntax. In which you would do the rotation on the <arg> and not the button object.

As for the whole file extension thing, it has apparantly fixed itself. However, I was wondering if there was any way to specify that wou want to safe an 8-bit png?
This is available through the PNG (Portable Network Graphics) Interface. This should do what you want:

ipngio.setType #true24



Which is part of the reason I have moved to the 3dsmaxcmd route, as you can define the output parameters that are sent with the file for some types of files. However, there are limitations to the 3dsmaxcmd route as well, like no include maps option.



Again code will help. Most of the time when using a pickbutton the code is executed after the pick using the on <pickbutton> picked do syntax. In which you would do the rotation on the and not the button object.

This isn’t quite what I need. The purpose of the script is to render the scene, rotate an object, render again, in a For Loop. The pickbutton is so the user can select the object they want to rotate. I need to be able to rotate the picked object later on, not right when it’s picked.


Ok it looks like you need to assign the picked object to a variable:

on selObj picked obj do (
pickObj = selObj.object

From there you should be able to call your rotation code on pickObj.

rot_obj = eulerangles 0 0 45				
rotate pickObj rot_obj

Hope that helps,


I’m having a bit of trouble implementing the rotation, though I don’t think it’s being caused by the Pickbutton. It keeps returning the error “No ““rotate”” function for undefined.” This happens even if I nake a new Maxscript containing only the rotation command and name the object I want to rotate directly.

Also, it says it doesn’t recognise

ipngio.setType #true24

Is there some specific place it needs to go, or something I need to open?


Hard to diagnose without seeing a file and code. If its returning undefined then you are calling rotate on something that has no object assigned to it.



Sorry trying to do too much at once. It should be:

portable_network_graphics.setType #true24



This is frustrating. Rotating the object is the last hurdle, and after getting it to net render it should be easy. I assign the clicked object to the variable PickedONJ, like you suggested. I print it immediately and it comes back

$Plane:Plane01 @ [67.962395,-1.970469,-29.78515

But then in the For loop the script thinks it’s undefined, Is it getting dumped? Is it not getting carried into the loop?

On the bright side, that PNG thing isn;t returning an error anymore, so it seems to be working


Can’t answer it without seeing the code where you are assigning the object and the for loop code. It could also be a scope issue you may need to define PickedONJ as a global variable.



Okay, here’s the whole thing (My apologies to any actual programmers I offend) :stuck_out_tongue:

dirArray = #(" back ", " back left ", " left ", " front left ", " front ", " front right "," right "," back right ") --these are automatically appended to the end of the Sequence Name to create the filename, for the different views (Assumes you start with the character's back to you)
totalAngles = 0 --keeps track of how many individual jobs have been sent to Backburner. This number is automatically appended to the Job Name, to keep track of them

createDialog myWin

rollout myWin "Sprite Renderer" width:432 height:287
	checkbox symClick "Render One Side Only (For Symmetrical Models)" pos:[93,16] width:245 height:15 --you can flip the existing frames to get the other side. Hooray for efficiency!
	pickbutton selObj "Choose Control Object" pos:[156,136] width:120 height:24 toolTip:"Choose the character's parent object. The script will rotate it on the Z axis to create the different views"

	button btnGo "Go to it!" pos:[168,163] width:98 height:24
	edittext fileName text:rendOutputFilename  pos:[32,56] width:284 height:24
	label lbl2 "Filepath:" pos:[192,40] width:48 height:16
	label lbl3 "Sequence Name" pos:[168,88] width:96 height:16
	edittext seqName "" pos:[32,104] width:368 height:24
	edittext errorBox "" pos:[81,192] width:275 height:21 enabled:false
	button btnReset "Reset Control Object" pos:[156,232] width:120 height:32
	button btnPath "Browse" pos:[325,56] width:74 height:26
	on selObj picked obj do
	--if the user did not cancel the picking...
	 if obj != undefined do
		 --display the name of the object on the button:
		 pickedObj = obj
		 print pickedObj
		 selObj.text =
	on btnGo pressed do
		if selObj.object != undefined and seqName.text != "" do --if acontrol object and sequence name are chosen
			case symClick.checked of
				true: renderNum = 5
				false: renderNum = 8
			for i = 1 to renderNum do

				print (seqName.text + dirArray [i])
				/*Get and then connect to the manager*/
				mngr = NetRender.GetManager() -- get an instance of the manager
				if mngr.connected == false do -- check if you are already connected
				  mngr.connect #automatic "" platform:#32-- connect to the manager if not already connected and force 32bit mode
				  --platform is an undocumented parameter used to connect to the manager for access to 32bit or 64bit jobs. You can only connect to one at a time.
				/*Now that we have access to the manager we need to prepare the job for submission*/
				job = mngr.newJob() -- create a new job
				suffix = totalAngles as string = (seqName.text + suffix) -- assign a name to the job. this should be a unique name, replace this string with what you want.
				/*From here you can set just about anything else you need.*/
				job.includemaps = true -- set includemaps to true for the job
				job.frameoutputname = (fileName.text + dirArray [i] + ".png") -- here you supply the output information for this job. Replace the string with what you want.

				print job.frameoutputname
				/*Once done setting your render parameters you need to simply submit the job*/
				portable_network_graphics.setType #true24
				totalAngles = totalAngles + 1
-- 				selObj.object.wirecolour
				 rot_obj = eulerangles 0 0 45
				 rotate pickedObj rot_obj
				--selObj.object.rotation.z_rotation  = selObj.object.rotation.z_rotation + 45
			print totalAngles
		if seqName.text == "" do
			errorBox.text = "You need a sequence name"
		if selObj.object == undefined do
			errorBox.text = "You need to choose a control object"
		if pathIsNetworkPath fileName.text == false do
			errorBox.text = "Net Render requires a network path"
	on btnReset pressed do
	on btnPath pressed  do
		fileName.text = getSaveFileName caption:"Save As:" initialDir:getOpenFileName

  1. You should create your dialog after you define your rollout, not before.
  2. You need to define pickedObj as a local or global variable in the macroscript or the rollout, that way it is available outside of the scope of the on picked event.
  3. You need to replace all selObj.object with pickedObj, calling selObj.object outside the on picked event could cause scope issues.

Try those and see if it helps,


That’s fantastic, Monkey! That fixed everything. The script works almost perfectly now. The only thing now is that I can’t get it to render anything but frames 1-100. I tried setting rendtimetype to 2 in the net render code you gave me, to no avail. Am I putting it in the wrong place? Or better yet, is there a way to just pull the current selection from the Render Scene Dialogue?


First you need to add to your netrender code job.fromFrame and job.toFrame. These control the start and end frame of the job being submitted/altered. If you want to pull from the render dialog you would use:

job.fromFrame = rendStart
 job.toFrame = rendEnd

However, you will probably need to close the render scene dialog if it is open, because changes from the dialog aren’t updated to maxscript calls until its closed or you call renderSceneDialog.commit() (NOTE: not everything in the dialog can be updated using the commit command). So some code to help there add this before your render loop:

dialogOpen = renderSceneDialog.isOpen()
 if dialogOpen == true do
   dialogOpen = true

Then add this after your render loop:

if dialogOpen == true do

The first set of code creates a dialogOpen variable and sets its value to true if the render scene dialog is open and false if it is closed. If dialogOpen is true then we set the variable to true and close the dialog. Now you would run your render loop. Then after the jobs are submitted we open the dialog back up if it was open before.

Hope that does it,


Monkey, I can’t thank you enough for all your help with this. The app is still a little rickety, but I’m the only on who has to use it anyway. You have no idea how much time this is going to save me.

I really hate to ask for anything at this point, but the PNGs still aren’t rendering as 8-bit, even with the code you gave me to set the type to 24. Is there a specific place the code needs to go?

also, I can’t seem to alter the Nth frame settings, or import them from the Render Scene Dialogue.

edit: Oh, right. Job.nthFrame. Because it’s not like we’ve used job. for every other thing we’ve worked on :stuck_out_tongue:


Thanks Pixel_monkey!

Copy/pasted and it works. Just saved me some time. :slight_smile:


Glad I could help Mathew, its good to know that I can save some other people some time. I have spent quite a bit of time investigating net render solutions.

For the most part now I have been using 3dsmaxcmd.exe to submit my jobs, because it offers some options that aren’t available from the net render interface. Stuff like Output format parameters (only limited formats supported), single frame rendering, split scanlines, plus most of the other things I need. For proper submission management I use a combination of the net render interface (to check existing jobs, etc) and then 3dsmaxcmd.exe to submit new jobs. So far it has been working really well.



Thanks for the advise. I might have to go in the direction later.

I’ve used Deadline and RPManager before for a couple of years. They work great, but I’ve always wanted a one click render button. Something smart that can process all the Max files for a project, figure out if it has changed, update character rigs with new animation, and submit everything to the farm.

All from one click :slight_smile:

Maybe I’m dreaming, but I got files rendering now. Thanks for the help :slight_smile:


Dreaming if you want it to magically happen without doing any work. You may look at Paul Neale’s BatchItMax script. You should be able to use the net render or 3dsmaxcmd.exe method with it. You will have to figure out the animation loading, and the “if it has changed” from someone else, since I don’t do that in day to day work. My guess is you won’t get a totally automated system, ie you may need to move files to a folder rather than having it know that something has changed, but it all should be possible.

Coll, did you ever get the png settings working? If not was everything else working as you need?



This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.