Notifications
Clear all

[Closed] How to get if statements to work with multiple checkbox options?

So I’m trying to modify this export script for all these files we got a dump for on a project we picked up. A lot of them have a version number on the end, that right now I’ve set up the script to trim them off. But I don’t know if all the files in the future will have this version number, so I want to add a button that if is checked on, removed the version number from the file name, and if it’s not, it doesn’t do anything, because if you’re working on a file without a version number on it, it’s going to trim off stuff I don’t want it to.

Right now, I was trying to add in an if/else statement that set up a string variable for the file name, that then a later if/else statement could use to name the file depending if you are exporting out a mesh or an animation file. The problem when I try this is it then gets an error saying undefined Boolean, and I’m assuming the string is only existing inside the if statement, and the next if statement can’t use it. So how can I get it so that the name can export out correctly based on if that button is or is not checked, within this script?

Also, before the check box for exporting out file type worked where if it was checked off, it’d export out a mesh and animation file. If it was checked on it would export out just an animation file. I’ve tried to modify it so that it’s two buttons, one for mesh and one for animation so I don’t have to keep deleting extra files. That part works. The part that doesn’t yet is that I would like for it to give you a message that nothing is checked and to check one of the boxes to export if neither box is selected. I can’t figure this part out though. I tried it as an else statement, but right now if you only have one of the two selected, it still gives you the error message. How can I set this up for specifically when neither button is checked?

Here’s the code I’m trying to use. Any help is greatly appreciated because I don’t have much more time after this week to work on this thing, and I’d like to leave a sturdy exporter for this project in my wake at least. And I am just picking up Max script right now, so more specific is helpful. I know Mel decently if those analogy help as well. Thanks all.

function md5export = (
	cursel = GetCurrentSelection()
	mesh = cursel[1]
	if mesh == undefined do
	(
		messagebox "no object selected"
		return undefined
	)
	if (((classof mesh.baseobject) as string) != "Editable_mesh") do
	(
		max modify mode
		modPanel.setCurrentObject $.baseObject
		modPanel.addModToSelection (Edit_Mesh ()) ui:on
		maxOps.CollapseNodeTo $ 2 off
	)
	if g_remove_version_number then
	(
		TempFilenameOnly = getFilenameFile (maxFilePath  + maxFileName)
		trimmedStr = trimright TempFilenameOnly "vV1234567890"
		trimmedStr = trimright trimmedStr "_"
		
	)
	else
	(
		TempFilenameOnly = getFilenameFile (maxFilePath  + maxFileName)
		trimmedStr = TempFilenameOnly
		
	)
	if g_export_mesh_only then
	(
	

		outfilename = getsavefilename filename:trimmedStr caption:"Save MD5" types:"MD5mesh (*.md5mesh)|*.md5mesh"
		if outfilename != undefined do
		(
			outfile=createfile outfilename
			animfilename = copy outfilename
			endindx = findstring animfilename ".md5mesh"
			
			if (outfile!= undefined and animfile != undefined) do
			(
				md5 = md5exportobj mesh
				format "%" (md5[1] as string) to:outfile
				format "%" (md5[2] as string) to:animfile
			--	format "%
" (md5[1] as string)
			--	format "%
" (md5[2] as string)
				close outfile
				close animfile
			)
		)
	)

	if g_export_anim_only then
	(
		
		animfilename = getsavefilename filename:trimmedStr caption:"Save MD5anim" types:"MD5anim (*.md5anim)|*.md5anim"
		if animfilename != undefined do
		(
			animfile = createfile animfilename
			if (animfile != undefined) do
			(
				md5 = md5exportobj mesh
			--	format "%" (md5[1] as string) to:outfile
				format "%" (md5[2] as string) to:animfile
			--	format "%
" (md5[1] as string)
			--	format "%
" (md5[2] as string)
			--	close outfile
				close animfile
			)
		)
	
	)

	else
	(
		messagebox "Check the box of which file type you would like to export. Select at least one box for Mesh and/or Animation."
	)
)
8 Replies

Since I assume the option variables like g_remove_version_number etc. are all defined somewhere outside the function and not in a higher scope, your fastest solution would be to pass them as arguments to the function.

Something like

function md5export g_remove_version_number g_export_mesh_only g_export_anim_only = 
(
... 
)--end function

Then you can call that function and pass the boolean values as 3 arguments and the rest should work. Of course, you could rename them to be shorter variables, and replace the variables in the IF statements with the shorter argument names. But that’s optional.

Yeah, those are defined in the rest on the script. And I was using the naming structure there as I didn’t want to change any of the existing ones as not to break anything in the part that actually exports out the various matrix for the mesh and animation.

I’m not sure I quite follow you on this. I tried adding that line to the beginning of the function, but that obviously isn’t right to get it working correctly. Are you saying to do a function for each combo of buttons that’s checked on?

1 Reply
(@bobo)
Joined: 11 months ago

Posts: 0

No, I proposed to modify the existing code

function md5export = (
	cursel = GetCurrentSelection()
	mesh = cursel[1]
	if mesh == undefined do
	(
		messagebox "no object selected"
		return undefined
	)
...

to something like

function md5export g_remove_version_number g_export_mesh_only g_export_anim_only = (
	cursel = GetCurrentSelection()
	mesh = cursel[1]
	if mesh == undefined do
	(
		messagebox "no object selected"
		return undefined
	)

which injects the variables as arguments into the function and makes them valid booleans instead of undefined.

Unless I misunderstood your problem.

The correct way to solve this would be to have a local scope of the script where the switch variables are declared in the beginning, then the function is defined, then the UI is defined and calls the function. But since you complained you were running out of time, I proposed the simplest solution available without actually learning MAXScript…

I had tried that but that doesn’t work either.
I get the error –Argument count error: md5export wanted 3, got 0.

And without the bit you suggested I get the error –Type error: if-test requires BooleanClass, got: undefined

Again, I think it’s because of the if statement around if g_remove_version_number then and the answer from that string not going down to the next if statement that needs it in if g_export_mesh_only then, where it needs the variable trimedStr for the filename. (But maybe that’s what this is supposed to do but I’ve screwed something up?)

I’m gonna post the code again with the buttons bit below it so you can see what the buttons are too in case that helps at all.

function md5export = (
	cursel = GetCurrentSelection()
	mesh = cursel[1]
	if mesh == undefined do
	(
		messagebox "no object selected"
		return undefined
	)
	if (((classof mesh.baseobject) as string) != "Editable_mesh") do
	(
		max modify mode
		modPanel.setCurrentObject $.baseObject
		modPanel.addModToSelection (Edit_Mesh ()) ui:on
		maxOps.CollapseNodeTo $ 2 off
	)
	if g_remove_version_number then
	(
		TempFilenameOnly = getFilenameFile (maxFilePath  + maxFileName)
		trimmedStr = trimright TempFilenameOnly "vV1234567890"
		trimmedStr = trimright trimmedStr "_"
		
	)
	else
	(
		TempFilenameOnly = getFilenameFile (maxFilePath  + maxFileName)
		trimmedStr = TempFilenameOnly
		
	)
	if g_export_mesh_only then
	(
	

		outfilename = getsavefilename filename:trimmedStr caption:"Save MD5" types:"MD5mesh (*.md5mesh)|*.md5mesh"
		if outfilename != undefined do
		(
			outfile=createfile outfilename
			animfilename = copy outfilename
			endindx = findstring animfilename ".md5mesh"
			
			if (outfile!= undefined and animfile != undefined) do
			(
				md5 = md5exportobj mesh
				format "%" (md5[1] as string) to:outfile
				format "%" (md5[2] as string) to:animfile
			--	format "%
" (md5[1] as string)
			--	format "%
" (md5[2] as string)
				close outfile
				close animfile
			)
		)
	)

	if g_export_anim_only then
	(
		
		animfilename = getsavefilename filename:trimmedStr caption:"Save MD5anim" types:"MD5anim (*.md5anim)|*.md5anim"
		if animfilename != undefined do
		(
			animfile = createfile animfilename
			if (animfile != undefined) do
			(
				md5 = md5exportobj mesh
			--	format "%" (md5[1] as string) to:outfile
				format "%" (md5[2] as string) to:animfile
			--	format "%
" (md5[1] as string)
			--	format "%
" (md5[2] as string)
			--	close outfile
				close animfile
			)
		)
	
	)

	else
	(
		messagebox "Check the box of which file type you would like to export. Select at least one box for Mesh and/or Animation."
	)
)--end function




rollout floaterMD5Export "Petz MD5 Exporter" width:160 height:300
(

	checkbox chk1 "reversenormalschk" pos:[16,24] width:16 height:16 
	label lbl3 "reverse face-normals" pos:[32,24] width:112 height:16
	spinner spn3 "" pos:[96,72] width:48 height:16 range:[0,100,1] type:#integer scale:1
	label lbl4 "Mapchannel:" pos:[16,72] width:64 height:16
	GroupBox grp1 "Character Export" pos:[8,8] width:144 height:216
	button btn1 "Export..." pos:[32,192] width:88 height:24 toolTip:"Export the currently selected object"
	

	button info_button "Unfreeze All" pos:[8,234] width:144 height:32 toolTip:"read some info here"
	
	checkbox flipverticaltexcoords "Checkbox" pos:[16,48] width:16 height:16 checked:true
	label lbl5 "flip vertical texcoords" pos:[32,48] width:112 height:16
	spinner bindpos_frame_spn "" pos:[96,96] width:48 height:16 range:[0,10000,0] type:#integer
	label lbl6 "Bindpos Frame:" pos:[16,96] width:80 height:16
	checkbox export_mesh_only_chk "Checkbox" pos:[16,120] width:16 height:16 checked:true
	label lbl17 "export md5mesh" pos:[32,120] width:112 height:16
	checkbox export_anim_only_chk "Checkbox" pos:[16,144] width:16 height:16 checked:true
	label lbl13 "export md5anim" pos:[32,144] width:112 height:16
	checkbox remove_version_number "Checkbox" pos:[16,168] width:16 height:16 checked:true
	label lbl18 "remove version #" pos:[32,168] width:112 height:16

	on btn1 pressed do
	(
		g_timerange = #((animationRange.start.frame as integer), (animationRange.end.frame as integer))
		g_bindpos_frame = bindpos_frame_spn.value
		g_mapchannel = spn3.value
		g_reversenormals = chk1.checked
		g_flipverticaltexcoord = flipverticaltexcoords.checked
		g_export_anim_only = export_anim_only_chk.checked
		g_export_mesh_only = export_mesh_only_chk.checked
		g_remove_version_number = remove_version_number.checked
		md5export()
	)



	on info_button pressed do
	(
		unfreeze objects
	)
)

-- create the rollout window and add the  rollout
if MD5ExportFloater != undefined do
(
	closerolloutfloater MD5ExportFloater 
)
MD5ExportFloater = newRolloutFloater "MD5 Export" 190 302
addRollout floaterMD5Export MD5ExportFloater 


I’m using this for now, where the naming bit is all together, and that works fine. It’s when I separate the naming bits between two if statements that it seems to break.

if g_export_anim_only then
	(
		TempFilenameOnly = getFilenameFile (maxFilePath  + maxFileName)
		trimmedStr = trimright TempFilenameOnly "vV1234567890"
		trimmedStr = trimright trimmedStr "_"
		animfilename = getsavefilename filename:trimmedStr caption:"Save MD5anim" types:"MD5anim (*.md5anim)|*.md5anim"
		if animfilename != undefined do
		(
			animfile = createfile animfilename
			if (animfile != undefined) do
			(
				md5 = md5exportobj mesh
			--	format "%" (md5[1] as string) to:outfile
				format "%" (md5[2] as string) to:animfile
			--	format "%
" (md5[1] as string)
			--	format "%
" (md5[2] as string)
			--	close outfile
				close animfile
			)
		)
	
	)
1 Reply
(@bobo)
Joined: 11 months ago

Posts: 0

Of course you do – because you don’t read what I write
I told you to CALL THE FUNCTION WITH THE SAME ARGUMENTS.
Now your function wants 3 arguments, and you are not giving them to it from the line where the function is being called. The whole idea is this:

You had some functions like

fn someFunction = 
( 
if something1 then dosomething() 
if something2 then dosomethingelse()
)

and when you called it like

someFunction() 

from another function it complained that something1 and something2 were undefined.

So I asked you to change the code to

fn someFunction something1 something2 = 
( 
if something1 then dosomething() 
if something2 then dosomethingelse()
)

Now you have to call this function with the added arguments

somefunction something 1 something2

but you did not modify the line

	on btn1 pressed do
	(
		g_timerange = #((animationRange.start.frame as integer), (animationRange.end.frame as integer))
		g_bindpos_frame = bindpos_frame_spn.value
		g_mapchannel = spn3.value
		g_reversenormals = chk1.checked
		g_flipverticaltexcoord = flipverticaltexcoords.checked
		g_export_anim_only = export_anim_only_chk.checked
		g_export_mesh_only = export_mesh_only_chk.checked
		g_remove_version_number = remove_version_number.checked
[B]		md5export g_remove_version_number g_export_mesh_only g_export_anim_only[/B]  -->THIS LINE!
	)

If any of the other g_* variables are needed inside the export function, you could add them to both places, too.

As I mentioned, the alternative would be to add () around the whole code and pre-declare all these variables in that scope BEFORE both the function and the UI body, like this:

(
global MD5ExportFloater
local g_remove_version_number, g_export_mesh_only, g_export_anim_only

function md5export = (
	cursel = GetCurrentSelection()
	mesh = cursel[1]
	if mesh == undefined do
	(
		messagebox "no object selected"
		return undefined
	)
	if (((classof mesh.baseobject) as string) != "Editable_mesh") do
	(
		max modify mode
		modPanel.setCurrentObject $.baseObject
		modPanel.addModToSelection (Edit_Mesh ()) ui:on
		maxOps.CollapseNodeTo $ 2 off
	)
	if g_remove_version_number then
	(
		TempFilenameOnly = getFilenameFile (maxFilePath  + maxFileName)
		trimmedStr = trimright TempFilenameOnly "vV1234567890"
		trimmedStr = trimright trimmedStr "_"
		
	)
	else
	(
		TempFilenameOnly = getFilenameFile (maxFilePath  + maxFileName)
		trimmedStr = TempFilenameOnly
		
	)
	if g_export_mesh_only then
	(
	

		outfilename = getsavefilename filename:trimmedStr caption:"Save MD5" types:"MD5mesh (*.md5mesh)|*.md5mesh"
		if outfilename != undefined do
		(
			outfile=createfile outfilename
			animfilename = copy outfilename
			endindx = findstring animfilename ".md5mesh"
			
			if (outfile!= undefined and animfile != undefined) do
			(
				md5 = md5exportobj mesh
				format "%" (md5[1] as string) to:outfile
				format "%" (md5[2] as string) to:animfile
			--	format "%
" (md5[1] as string)
			--	format "%
" (md5[2] as string)
				close outfile
				close animfile
			)
		)
	)

	if g_export_anim_only then
	(
		
		animfilename = getsavefilename filename:trimmedStr caption:"Save MD5anim" types:"MD5anim (*.md5anim)|*.md5anim"
		if animfilename != undefined do
		(
			animfile = createfile animfilename
			if (animfile != undefined) do
			(
				md5 = md5exportobj mesh
			--	format "%" (md5[1] as string) to:outfile
				format "%" (md5[2] as string) to:animfile
			--	format "%
" (md5[1] as string)
			--	format "%
" (md5[2] as string)
			--	close outfile
				close animfile
			)
		)
	
	)

	else
	(
		messagebox "Check the box of which file type you would like to export. Select at least one box for Mesh and/or Animation."
	)
)--end function




rollout floaterMD5Export "Petz MD5 Exporter" width:160 height:300
(

	checkbox chk1 "reversenormalschk" pos:[16,24] width:16 height:16 
	label lbl3 "reverse face-normals" pos:[32,24] width:112 height:16
	spinner spn3 "" pos:[96,72] width:48 height:16 range:[0,100,1] type:#integer scale:1
	label lbl4 "Mapchannel:" pos:[16,72] width:64 height:16
	GroupBox grp1 "Character Export" pos:[8,8] width:144 height:216
	button btn1 "Export..." pos:[32,192] width:88 height:24 toolTip:"Export the currently selected object"
	

	button info_button "Unfreeze All" pos:[8,234] width:144 height:32 toolTip:"read some info here"
	
	checkbox flipverticaltexcoords "Checkbox" pos:[16,48] width:16 height:16 checked:true
	label lbl5 "flip vertical texcoords" pos:[32,48] width:112 height:16
	spinner bindpos_frame_spn "" pos:[96,96] width:48 height:16 range:[0,10000,0] type:#integer
	label lbl6 "Bindpos Frame:" pos:[16,96] width:80 height:16
	checkbox export_mesh_only_chk "Checkbox" pos:[16,120] width:16 height:16 checked:true
	label lbl17 "export md5mesh" pos:[32,120] width:112 height:16
	checkbox export_anim_only_chk "Checkbox" pos:[16,144] width:16 height:16 checked:true
	label lbl13 "export md5anim" pos:[32,144] width:112 height:16
	checkbox remove_version_number "Checkbox" pos:[16,168] width:16 height:16 checked:true
	label lbl18 "remove version #" pos:[32,168] width:112 height:16

	on btn1 pressed do
	(
		g_timerange = #((animationRange.start.frame as integer), (animationRange.end.frame as integer))
		g_bindpos_frame = bindpos_frame_spn.value
		g_mapchannel = spn3.value
		g_reversenormals = chk1.checked
		g_flipverticaltexcoord = flipverticaltexcoords.checked
		g_export_anim_only = export_anim_only_chk.checked
		g_export_mesh_only = export_mesh_only_chk.checked
		g_remove_version_number = remove_version_number.checked
		md5export()
	)



	on info_button pressed do
	(
		unfreeze objects
	)
)

-- create the rollout window and add the  rollout
if MD5ExportFloater != undefined do
(
	closerolloutfloater MD5ExportFloater 
)
MD5ExportFloater = newRolloutFloater "MD5 Export" 190 302
addRollout floaterMD5Export MD5ExportFloater 

)
 lo1

Bobo, I just wanted to say you are a freaking saint.

Ah. Thanks for explaining that more in depth. I had read what you said before, but I didn’t really know what call the function with the same arguments meant, so I had no idea that’s what I had to do. But I think I understand what’s doing now thanks to your break down.

Seems to be working now, so thanks so much for the tip. Off to dump this on the server for anybody else that might need it.

And hopefully I won’t need to do any more scripting like this in Max any time soon without hitting the basic stuff first. Again, thanks for your patience and breaking that down in a way I could start to understand.

Glad it worked!
Don’t feel discouraged from your first experience, dealing with other peoples’ code is not easy even for me.