How to Deploy MaxScript Scripts

Written December 1st, 2010
Categories: Articles, Scripting / Programming
1 Comment »

You’ve spent a lot of time putting together a useful MaxScript and you want the whole world to enjoy it!  Unfortunately, you’re not sure of the best way to get it into the hands of the people.  Luckily, MaxScript comes with three major techniques for deploying a script and we’re going to cover them today.  These three techniques are

  1. Executable script – run it when necessary
  2. Macroscript (optional auto-deploy) – bind it to a hotkey or menu item
  3. Scripted plug-ins – connect to the 3ds Max interface directly

We’ll be going through these examples with a simple “Select Non-Quad Polygons” script from the MaxScript documentation.

Method 1- Executable Script

The first way is best for beginners and involves coding up a script that executes in a single go.  The script below operates in that way.  It iterates across all faces in the object to select non-quadrilateral faces.  Note that this script only works for editable poly objects and will throw an error for anything else!

local face_selection = #{}
local base_obj = $.baseobject
local num_faces = polyop.getNumFaces base_obj
for f = 1 to num_faces do
(
	local num_face_verts = polyop.getFaceDeg base_obj f
	if num_face_verts != 4 do face_selection[f] = true
)--end f loop
polyop.setFaceSelection base_obj face_selection
max modify mode
modPanel.setCurrentObject base_obj
subobjectlevel = 4

In this case, when the script is run, the faces are selected and the user is unceremoniously dropped off at the object’s “Polygon Select” level.  For a script with this level of involvement, this is an appropriate deployment mechanism.  The user just runs the script whenever they need it.  The script usually sits in a folder somewhere waiting for the user to invoke it.

Method 2- Macroscript (With optional auto-deploy)

A Macroscript is a wrapper that goes around your entire script and allows it to be bound to a hotkey or made a UI item.  This deployment method is good for intermediate users and for larger scripts that are a little more involved.  Let’s try wrapping the script above into a Macroscript and see it in the 3ds Max user interface.

macroscript SelectNonQuadPolys category:"Bluesummers" \
tooltip:"Select Non-Quads"
(
	on isEnabled return
	(
		selection.count == 1 and classOf selection[1].baseobject == Editable_Poly
	)
	on execute do
	(
		local face_selection = #{}
		local base_obj = $.baseobject
		local num_faces = polyop.getNumFaces base_obj
		for f = 1 to num_faces do
		(
			local num_face_verts = polyop.getFaceDeg base_obj f
			if num_face_verts != 4 do face_selection[f] = true
		)--end f loop
		polyop.setFaceSelection base_obj face_selection
		max modify mode
		modPanel.setCurrentObject base_obj
		subobjectlevel = 4
	)--end on execute
)--end script

Notice that in this case we’ve added two important elements. The first is a check to make sure we have an editable_poly object selected.  The second is the Macroscript wrapper that allows this tool to become part of the user interface. It has a name, a tooltip, a category, and can even take on a standard or custom icon (see MaxScript documentation). If you execute the script above and then go to “Customize > Customize User Interface” and select the “Bluesummers” Category, you’ll see the script appear.  You can bind it to a hotkey or add it to a Quad Menu or rollout floater.

In order to deploy this kind of script, you’ll need to have the user drop it into their “StdScripts” folder of their 3d Studio Max installation.  This is no fun since it adds some complexity.  For most 3dsMax installations, that folder is

C:\Program Files\Autodesk\3ds Max 2009\stdplugs\stdscripts

Any scripts in this folder will be run during 3dsMax’s startup process, and when you have the Macroscript wrapper around your script then you’re effectively “registering” a new tool during startup.

You can get pretty creative during this process. For example, during startup you can register the Macroscript into the user’s interface which basically “installs” it into 3d Studio Max. Consider the following snippet from my WedTexVerts script that installs it into the 3d Studio Max UnwrapUVWs modifier UI automatically.

Macroscript <...>
(
	<...shortened...>
)
-- If the registration fails, that means it's already there.
if menuMan.registerMenuContext 0x1c413679 do
(
	local ToolsMenuIndex, ToolsMenuItem
	local ToolsMenu, WeldVertTool, UVW_MenuBar

	-- Get the main UVW menu bar
	UVW_MenuBar = MenuMan.getMenu 128 

	-- The above is not always true.  Let's check to make
	-- sure so we don't totally wreck the UI
	if UVW_MenuBar.getTitle() != "UVW Unwrap - Menu Bar"
	do throw "Critical Error: Your UI Could not be modified \
				because you have made changes to your .mnu \
				file."

	-- Get the tools index.  Should be 4th from the left.
	-- Double check the title to make sure.
	for i = 1 to UVW_MenuBar.numItems() do
		if (UVW_MenuBar.getItem i).getTitle() == "Tools" do
			ToolsMenuIndex = i

	-- Get the menu item that holds the help menu
	ToolsMenuItem = UVW_MenuBar.getItem(ToolsMenuIndex)

	-- Get the menu from the item
	ToolsMenu = ToolsMenuItem.getSubMenu()

	-- Create a menu item that calls the WeldTexvert Tool.
	WeldVertTool = (menuMan.createActionItem "WeldSelectedFloater" "Bluesummers' Tools")

	-- Add the action item to the end of the help menu.
	ToolsMenu.addItem WeldVertTool 7

	-- redraw the menu bar with the new item
	MenuMan.updateMenuBar()
)

This is a pretty complicated process, so I’ll leave it to you to read more about the MaxScript MenuMan object. You should just be aware that your users may not always be smart enough to bind up your tools to a hotkey and you can take the liberty of putting your new functionality directly into their interface.  However, you should also be extremely careful as the smallest mistake could damage the user’s interface.

Method 3- Scripted Plug-Ins

Finally, it’s possible for us to deploy scripted plug-ins. These tend to be the largest scripts of all and are basically full extensions of 3dsMax functionality. You can create render filters, meshes, modifiers, and more. You’ll basically deploy your script similarly to a Macroscript- by having your user insert the script into their 3dsMax C:/…/stdscripts/ folder. However, instead of wrapping your functionality in a Macroscript, you’ll wrap it in a scripted plug-in context.

Take a look at the code below, where the script creates a new object type called a Cuboid.

plugin geometry Cuboid
name:"Cuboid"
classID:#(0x133077, 0x54375)
category:"Scripted Primitives"
extends:Box
(
	fn fmax val1 val2 = if val1 > val2 then val1 else val2
	tool create
	(
		on mousePoint click do
		case click of
		(
			1: nodeTM.translation = gridPoint
			2: #stop
		)

		on mouseMove click do
			if click == 2 then
				delegate.width = delegate.length = delegate.height = \
				2 * fmax (abs gridDist.x) (abs gridDist.y)
	)
)

Granted this procedure takes significantly more work than the other two options, it does integrate your tools more deeply into 3d Studio Max and can be quite useful for circumstances where you want to create a “normal” extension of the tools available.

And there you have it!  Those are three awesome ways to deploy your scripts to anyone who needs them.  Happy coding!

One Response to How to Deploy MaxScript Scripts

Leave a reply


©2023 MrBluesummers.com