Select Face Smoothing Group Boundaries Script

Written April 16th, 2009
Categories: Downloads, Scripts
3 comments

This script will quickly select all of the edges in your 3d Studio Max model that boarder smoothing group changes.  For example, if you have a character who’s smoothing groups change between flesh and clothing, this helps you quickly see where those changes are, and refine your smoothing groups accordingly. You can also use it to create UWV clusters based on your smoothing groups. Finally, it allows you to select all of your smoothing group boarders, or the boarders of only a particular smoothing group.

Click this link to download the Face Smoothing Group Boundaries Script. Just unzip it to your desktop or somewhere on your hard drive and run it via the Maxscript command menu in 3dsMax.

Using WireBundle

Written March 15th, 2009
Categories: Modeling, Videos
15 comments

I’ve got a real treat for you this week.  I’ve written up a script called “Wire Bundle” that makes it easy to make wires in your mechanical objects.  Like the classic “Wire Jumble”, you can select a long chain of objects for the wires to pass through.  As a new twist, you can also select a spline for the wires to pass through, making it even easier to get this awesome effect quickly.

This video shows you how to use the script.  You can download Wire Bundle here.

Scripted Clay Renders

I was thinking hard about the 3d Studio Max clay rendering tutorial I wrote a few days ago, and was pondering about what an extension might be. Then it struck me! “Gosh, wouldn’t it be cool to have a button in the 3dsMax interface that you could click, and have it automatically turn out a clean render while you go make a sandwich?”

The answer is “of course”!

The Final Step

Adding the button to your tool bar.

So let’s have a look at that. What kind of 3d Studio knowledge would we need to take that on? Well, first we need our trusty Maxscript help file (Help > Maxscript help…) and a then a healthy dose of patience. Note: While I was writing and coding for this tutorial, I hit a few snags myself, so don’t think that it’s always a piece of cake. I’ll clue you in to some of my difficulties along the way so that you can learn from my mistakes!

Step 1: Copy the basic macroscript code.

Now this is a good step 1 for any project you take on in Maxscript. For this case, you can either copy my code below or you can go into the document and search for it yourself. I’d recommend finding it yourself (or better yet, typing it in manually) because it’s a better learning experience. However, I won’t hold it against you if you want to copy it- just this once.

macroScript Clay_Renderer
category:"Custom"
tooltip:"Take a clay render"
buttontext:"Clay Render"
(
)

Let’s run through the lines of code so we get a good grip on what it means. The first line declares everything inside as a macroscript, and gives it an internal name. The category string lets 3d Studio Max easily group it with other user interface items so you can put it in the toolbar or in a modular toolbar later. The tooltip is what appears when you hover over the macroscript button when it’s in the user interface, and the button text is what the button says on it.

Step 2: Think.

Inside this codeblock, we need to put what will happen when a user clicks on it. What’re some things we want it to do? Well, hopefully you’ve read my last tutorial, so you have a good grip on the ins and outs of clay rendering. We know we want to a) apply a white material to everything in the scene, b) have the scanline renderer in charge, and c) use a skylight.

I’d like to take a theoretical aside here and talk about a major hang-up on this particular script. You’ll notice that we’re messing with the materials in the scene and the lights. These changes need to be undoable or they’ll ruin everything. Can you imagine if you took a clay render and it took all your materials off your objects? Or if your lights disappeared? I’ll be including bits of code from here on out that help make this script more applicable and safer for scenes with materials and lights already in them!

Step 3: Lay down the foundations.

macroScript Clay_Renderer
category:"Custom"
tooltip:"Take a clay render"
buttontext:"Clay Render"
(
	undo on
	(
	  -- Create a white material and assign it to everything.

	  -- Delete all the lights and create a skylight instead.

	  -- Store the current render settings, and set to scanline.

	  -- Render

	  -- Revert to the old renderer
	)
	-- Undo everything we did, leaving only the render.
)

So I’ve only made a single structural change here, which is adding the “undo on” wrapping. This makes it so that the entire macroscript takes up only a single block in 3d Studio Max’s undo history. This way any changes made within this codeblock can be undone with a single command. Neat huh?

The remaining stuff is all comments. I usually start my scripts off by hammering out comments that say what needs to get done. I recommend that you consider doing the same; it helps you stay organized and think things through. In this case, you see we need to create a white material and apply it to all the objects in the scene. Then we need to delete all the lights, which is easier than turning them off and back on again. We also have to create the shadowing skylight so that we get the smooth shading effect. After that, we can store the current render settings, and switch over to scanline. Finally, we render and then revert back to the old Renderer.

Step 4: Fill code.

macroScript Clay_Renderer
category:"Custom"
tooltip:"Take a clay render"
buttontext:"Clay Render"
(
	undo on
	(
		-- Create a white material and assign it to everything.
		WhiteMat = standard diffuse:(color 220 220 220) twosided:true
		for obj in objects do obj.material = WhiteMat

		-- Delete all the lights and create a skylight instead.
		for lux in lights do delete lux
		ThisSkylight = skylight castShadows:true rays_per_sample:12

		-- Store the current render settings, and set to scanline.

		-- Render

		-- Revert to the old renderer
	)
	-- Undo everything we did, leaving only the render.
)

So we’ve added the information regarding the material. In this case we’re creating a material called “WhiteMat” which is a standard material with a diffuse color of 220 grey and it’s two-sided. Why? Because if you think about it, a clay render doesn’t show off all the geometry if it can’t render backfacing polygons. Worse yet, even though backfacing polygons wouldn’t show up in the render, they’ll still affect the lighting solution which would create some unpleasant artifacts. It’s best to just set this parameter to true.

Next I’ve added in the code for deleting the lights and creating the skylight. What we’re basically saying in the first line is “For each light ‘lux’, delete it”. This can always be undone at the end of the script. In the next line, we create a new skylight called “ThisSkylight”, which is casting shadows at a rate of 12 rays per sample.

macroScript Clay_Renderer
category:"Custom"
tooltip:"Take a clay render"
buttontext:"Clay Render"
(
	undo on
	(
		-- Create a white material and assign it to everything.
		WhiteMat = standard diffuse:(color 220 220 220) twosided:true
		for obj in objects do obj.material = WhiteMat

		-- Delete all the lights and create a skylight instead.
		for lux in lights do delete lux
		ThisSkylight = skylight castShadows:true rays_per_sample:12

		-- Store the current render settings, and set to scanline.
		ExistingRenderSettings = renderers.production
		renderers.production = default_scanline_renderer()

		-- Render
		render()

		-- Revert to the old renderer
		renderers.production = ExistingRenderSettings
	)
	-- Undo everything we did, leaving only the render.
	max undo
)

Here we see the storage and changing of the renderer. We take this extra step because if you’re working on a scene in mental ray, but want a clay render, you shouldn’t have to go through the trouble of a) writing a totally different clay render script or b) storing your settings manually. We store the production renderer to a variable, and then set it to a fresh instance of the default scanline renderer. A fresh instance has all the default values, so we know there won’t be any kind of crazy settings getting in the way of the clay render.

Finally, we can take the render. Once that is complete, the script resets the production renderer back to what it should be, and undoes any weird changes (like deleted lights) that the script executed. We’re back to where we started except now we have an awesome clay render in the render window!

The best part of this is that now we have a button that we can place anywhere in the 3dsMax user interface that will create a clay render on command!

Hit the hotkey Ctrl+E to run the script so that it will appear as a macroscript. You can save the file to your <3dsMax Root>/UI/Macroscripts directory, and it’ll be loaded automatically every time you start 3d Studio Max. To add your new “Clay Render” button to the main toolbar, just click on the menu “Customize > Customize User Interface”. Go to the “Toolbars” tab, and from the category pulldown select “Custom”, and you’ll see your clay render button. Just drag and drop it from the “Action” window to the main toolbar, and the button will appear.

The Final Step

Adding the button to your tool bar.

And there you have it! Now you can get a clean clay render no matter what your material, lighting, or rendering setup is!

Until next time, happy rendering!

C# to Maxscript

Written November 8th, 2008
Categories: Articles, Scripting / Programming
4 comments

I figured I’d do a quick tutorial about something a little more difficult, but still very important. I’m going to take you step-by-step through integrating a maxscript document and a C# class library so that you can access the powerful and robust features of the dotnet framework in the rather limited environment that maxscript provides. This lets you do such powerful things as access databases, grab web-deployed content, and more. It is my opinion that dotnet connectivity is the best thing to ever happen to maxscript.

This tutorial is written for C# users. However, the themes here apply to any language that is part of the common language runtime (CLR) framework. If you chose to use C++, VB, etc. you should still be able to compile a class library that can integrate in much the same way.

Step 1: Make a new class library project in Visual Studio.

New Class Library

New class library creation.

So from the startup screen in visual studio, go ahead and go to File > New > Project.

Select a C# class library. I’m going to name mine “Maxscript Sandbox”.

Name Your Library

Name your library.

Step 2: Write a test class.

Now let’s write a test class for our new class library. In this screenshot I’ve written a very simple class that contains a string you pass on creation. Once the object exists, you can access the name, or you can call a function that provides you with a sentence that includes the name. Simple enough!

Rename the class to TestObject, and fill in the code you see below.

public class TestObject
{
    string Name;
    public TestObject(string thisName)
    {
        Name = thisName;
    }

    public string GetLongName()
    {
        return ("You can call me " + Name + "!");
    }
}
Step 2 Code

Insert some placeholder code.

Step 3: Compile.

From the drop-down along the top bar, change the build mode from Debug to Release. This means that the compiler will optimize the code for fast execution rather than for debugging and trying to find out what the problem is. On that note, I think there exists a way to debug the class from your script. However, it’s outside the scope of this tutorial. If you’re burning to debug, make a console app that wraps your class and tests functionality from there.

Finished Code

Change to "Release" compilation.

Now, hit F6 or go to Build > Build Solution.

Build the solution.

Build the solution to a DLL.

Step 4: Call the new object from Maxscript.

I’ve commented a lot of the code in the next image, but it’s actually a lot shorter than it looks. All you have to do is load the new class library you’ve created, instantiate the object, and then do whatever you want with it.

Notice that I’ve moved the .dll file that resulted from building my class library to somewhere shorter. Normally, your class library would compile to a directory within the project folder you selected when you created the project (like C:/…/Maxscript Sandbox/ Maxscript Sandbox/bin/release/Maxscript Sandbox.dll). I’ve moved that file from that incredibly long directory to something more digestable like C:/Temp/Maxscript Sandbox.dll.

Call code from Maxscript.

Call the library from Maxscript.

dotnet.loadAssembly ("C:\Temp\Maxscript Sandbox.dll")
ThisTestObject = dotNetObject "Maxscript_Sandbox.TestObject" "Burt"
print (ThisTestObject.GetLongName())

When you run this program, and the dll is in the right place, you’ll find that it outputs as though the object was a native max object. However it’s actually running in the dotnet framework. You can read more about creating objects and the syntax surrounding the Maxscript/C# connection in the documentation. This tutorial was just meant to clarify some of the logistical issues surrounding getting it working.

The final output

The final output from the script.

Until next time, happy scripting!

Tick-Based UI Updating in MaxScript

Written May 9th, 2008
Categories: Articles, Scripting / Programming
No Comments »

This is going to make all you computer science buffs cringe, but today I learned a really dirty way of managing 3dsMax UI states in a Maxscript rollout or DotNet form. By hooking up a UI refresher to a timer object, you can have your front-end refresh dozens or hundreds of times per second- probably without a performance hit!

Consider the following script:

global hForm, mCheckbox, thisTimer
(
fn whenCheckboxIsPressed a b =
(
if MCRUtils.IsCreating Box
then (Max Select; try((hForm.controls.item(0)).checked = false) catch())
else Macros.run 26615
)

fn updateUI =
(
try
(
hForm.controls.item(0)).checked = MCRUtils.IsCreating Box
) catch()
)

--Create a DotNet Checkbox
mCheckbox = dotNetObject "System.Windows.Forms.Checkbox"
mCheckbox.appearance = (dotnetClass "System.Windows.Forms.Appearance").Button
mCheckbox.text = "Box Button"
mCheckbox.location = dotNetObject "System.Drawing.Point" 0 0

--Create a DotNet Form
global hForm = dotNetObject "System.Windows.Forms.Form"
hForm.topmost = true
hForm.controls.add mCheckbox --add the Button to the Form

thisTimer = dotNetObject "System.Windows.Forms.Timer"
thisTimer.interval = 10

--Add an Event Handler for the click event:
dotNet.addEventHandler mCheckbox "click" whenCheckboxIsPressed
dotNet.addEventHandler thisTimer "tick" updateUI

hForm.show() --show the Form with the Checkbox
thisTimer.start()
)

First, we declare our important Maxscript variables globally so that they can be accessed anywhere. This is a scoping issue; use this technique to taste.

Then we declare the function for when the checkbox is pressed, and accept the sender and event args in a and b respectively. In this function, we dive into the hForm.controls collection and retrieve the control to set it’s “checked” parameter. We set a Try()Catch() block around it because the timer will continue for a short while after the window is closed. Without this expression, you’ll get an error 100 times per second and you’ll have to restart 3dsMax.

The second function is the UI update. In this case, we just set the “checked” parameter equal to a Boolean expression checking to see if the user is engaged in some activity. In this case, we want to know if the user is creating a box. For more of these cases, read the Macroscripts included in 3dsMax and you can derive all sorts of neat “Is the user doing this” type expressions.

The rest is fairly self explanatory. We just create the checkbox, and assign it the visual characteristics we need. We create the DotNet form and assign the checkbox to it, and then create the timer and give it an interval rate of 10 (that is, 1000/10 or 100x per second).

We then link up the two event handlers to functions we declared earlier (button click and update ui), and create the form.

Ta da! The button walks, talks, and acts like a macroscript button, but it’s actually being controlled by DotNet functionality. This means

  1. More robust visual design for UI items,
  2. More robust code options and possibly faster performance, and
  3. When you use my library some day, you’ll be able to get native macroscripts to work alongside your own snazzy code!

3dsMax Tab UI

Written March 7th, 2008
Categories: Articles, Scripting / Programming
No Comments »

In an effort to avoid doing homework, I’ve decided to write out a quick explanation of how you can modify 3dsMax to use UI tabs. It seems the usual solution online is to upload your UI scheme without discussion, which usually leads to people saying “Eh, I guess this’ll do.” However, this is a dangerous way of doing things because some UIs may be poorly constructed and over-write access to new features (i.e. using a Max 7 UI set up in Max 9 will deny you access to stuff like paint selection).

Let’s go through and talk about what makes tabs, and how you can make them into whatever you want!

For starters, open your defaultUI.cui or MaxStartUI.cui file in notepad or your favorite text editor. You’ll see a long list of names and values like “WindowCount=8″. Now you don’t have to know what all of these mean; just the important ones like rank, item#, and the stuff in brackets.

To begin, your’s should look something like this:

[CUIData]
WindowCount=9
[CUIWindows]
F000=S:Command Panel
...
[Command Panel]
Rank=0
SubRank=0
Hidden=0
...
[Main Toolbar]
Rank=0
SubRank=0
Hidden=0
...
...

What this file is doing is defining all the buttons, pull-downs, and toggles in your interface setup. What you want to do is define a new bar that will contain your tabs. To do this you would insert the tabs code between the end of [command panel] and the start of [Main Toolbar]. Make sure to change the values in Rank=# so that they are a) in order, and b) give a lower number to the tab panel than to the main toolbar. If the main toolbar is a higher rank, it will appear above the tabs, and vice versa.

Here’s where you would insert it:

[Command Panel]
Rank=0
SubRank=0
Hidden=0
FRect=673 182 865 1089
DRect=1204 39 1388 770
DRectPref=2147483647 2147483647 -2147483648 -2147483648
DPanel=8
Tabbed=0
TabCt=0
CurTab=-1
CurPos=8 1204 39 1388 770
CType=4
[TAB_BAR_STUFF]
Rank=1
SubRank=0
Hidden=0
...
...
[Main Toolbar]
Rank=2
SubRank=0
Hidden=0
FRect=1109 212 1181 271
DRect=0 0 1315 39
DRectPref=2147483647 2147483647 -2147483648 -2147483648
DPanel=1
Tabbed=0
TabCt=0
CurTab=-1
CurPos=1 0 0 1315 39
CType=1
ToolbarRows=1
ToolbarType=3
ItemCount=43
...

Before you proceed, some words of caution!Before you proceed, some words of caution!

  • Fudging with this file could wreck your UI. Make sure to back up your UI file before you work on it.
  • Make sure there is no space between the blocks: the UI code doesn’t like blank lines!
  • This code-block is for 3dsMax 9. Some features will not work for Max 8, and it will not really be suitable for Max2008 or 2009. Remember that this needs to be customized for you!
  • Regardless of what 3dsMax does, make sure the UI elements in each tab are in order of item number (i.e. item#=…). Keep things neat and tidy.
  • You absolutely, positively, must change the ItemCount variable to the number of items in the tab, or 3dsMax will cut off whatever other UI elements remain after that number. If you find stuff not showing up for some reason, this is a likely culprit.

If you need to add buttons that do not yet exist in the bar, you can do so through [3dsM]>Customize>Customize User Interface. Under the “Toolbars” tab, you can search for functionality (like “create spotlight” or “turbosmooth modifier”) and drag them into the tabs bar. If you need to rearrange items, access features not available through the UI editor, or do deep structural changes (like add tabs) you do so through the .cui file.

Now for the code. What you see below is the block of code to insert into your CUI file. It contains the various tabs (denoted with names like [Tab Panel__0]) and their buttons, images, and some other (irrelevant) data. Take this block and insert it between the two blocks like I described above:

[Tab Panel]
Rank=1
SubRank=0
Hidden=0
FRect=2147483647 2147483647 -2147483648 -2147483648
DRect=0 0 1280 57
DRectPref=2147483647 2147483647 -2147483648 -2147483648
DPanel=1
Tabbed=1
TabCt=10
CurTab=3
CurPos=1 0 0 1280 57
CType=1
[Tab Panel__0]
TabName="Objects"
ToolbarRows=1
ToolbarType=3
ItemCount=30
Item0=3|6|16|31|1
Item1=3|6|16|31|1
Item2=3|6|16|31|1
Item3=3|6|16|31|1
Item4=2|0|0|31|3|647394|Box`Objects Primitives|0|0|"Box"|"Box"|-1|
Item5=2|0|0|31|3|647394|Sphere`Objects Primitives|0|0|"Sphere"|"Sphere"|-1|
Item6=2|0|0|31|3|647394|Cylinder`Objects Primitives|0|0|"Cylinder"|"Cylinder"|-1|
Item7=2|0|0|31|3|647394|Torus`Objects Primitives|0|0|"Torus"|"Torus"|-1|
Item8=2|0|0|31|3|647394|Teapot`Objects Primitives|0|0|"Teapot"|"Teapot"|-1|
Item9=2|0|0|31|3|647394|Cone`Objects Primitives|0|0|"Cone"|"Cone"|-1|
Item10=2|0|0|31|3|647394|GeoSphere`Objects Primitives|0|0|"GeoSphere"|"GeoSphere"|-1|
Item11=2|0|0|31|3|647394|Tube`Objects Primitives|0|0|"Tube"|"Tube"|-1|
Item12=2|0|0|31|3|647394|Pyramid`Objects Primitives|0|0|"Pyramid"|"Pyramid"|-1|
Item13=2|0|0|31|3|647394|plane`Objects Primitives|0|0|"Plane"|"Plane"|-1|
Item14=3|6|16|31|1
Item15=2|0|0|31|3|647394|Hedra`Objects Primitives|0|0|"Hedra"|"Hedra"|-1|
Item16=2|0|0|31|3|647394|ChamferBox`Objects Primitives|0|0|"ChamferBox"|"Chamfer Box"|-1|
Item17=2|0|0|31|3|647394|OilTank`Objects Primitives|0|0|"Oil Tank"|"Oil Tank"|-1|
Item18=2|0|0|31|3|647394|Spindle`Objects Primitives|0|0|"Spindle"|"Spindle"|-1|
Item19=2|0|0|31|3|647394|Gengon`Objects Primitives|0|0|"Gengon"|"Gengon"|-1|
Item20=2|0|0|31|3|647394|RingWave`Objects Primitives|0|0|"RingWave"|"RingWave"|-1|
Item21=2|0|0|31|3|647394|Prism`Objects Primitives|0|0|"Prism"|"Prism"|-1|
Item22=2|0|0|31|3|647394|Torus_Knot`Objects Primitives|0|0|"Torus Knot"|"Torus Knot"|-1|
Item23=2|0|0|31|3|647394|ChamferCyl`Objects Primitives|0|0|"Chamfer Cylinder"|"Chamfer Cylinder"|-1|
Item24=2|0|0|31|3|647394|Capsule`Objects Primitives|0|0|"Capsule"|"Capsule"|-1|
Item25=2|0|0|31|3|647394|L_Ext`Objects Primitives|0|0|"L-Extrusion"|"L-Extrusion"|-1|
Item26=2|0|0|31|3|647394|C_Ext`Objects Primitives|0|0|"C-Extrusion"|"C-Extrusion"|-1|
Item27=2|0|0|31|4|647394|Hose`Objects Primitives|0|0|"Hose"||8|FileLinkActionItems
Item28=3|6|16|31|1
Item29=2|0|0|31|3|647394|Foliage`Objects AEC|0|0|"Foliage"|"Foliage"|-1|
[Tab Panel__1]
TabName="Shapes"
ToolbarRows=1
ToolbarType=3
ItemCount=12
Item0=3|6|16|31|1
Item1=2|0|0|31|3|647394|Lines`Objects Shapes|0|0|"Line Shape"|"Line"|-1|
Item2=2|0|0|31|3|647394|Rectangle`Objects Shapes|0|0|"Rectangle Shape"|"Rectangle"|-1|
Item3=2|0|0|31|3|647394|Circle`Objects Shapes|0|0|"Circle Shape"|"Circle"|-1|
Item4=2|0|0|31|3|647394|Ellipse`Objects Shapes|0|0|"Ellipse Shape"|"Ellipse"|-1|
Item5=2|0|0|31|3|647394|Arc`Objects Shapes|0|0|"Arc Shape"|"Arc"|-1|
Item6=2|0|0|31|3|647394|Donut`Objects Shapes|0|0|"Donut Shape"|"Donut"|-1|
Item7=2|0|0|31|3|647394|Ngon`Objects Shapes|0|0|"NGon Shape"|"NGon"|-1|
Item8=2|0|0|31|3|647394|Star`Objects Shapes|0|0|"Star Shape"|"Star"|-1|
Item9=2|0|0|31|3|647394|Text`Objects Shapes|0|0|"Text Shape"|"Text"|-1|
Item10=2|0|0|31|3|647394|Helix`Objects Shapes|0|0|"Helix Shape"|"Helix"|-1|
Item11=2|0|0|31|3|647394|Section`Objects Shapes|0|0|"Section Shape"|"Section "|-1|
[Tab Panel__2]
TabName="Compounds"
ToolbarRows=1
ToolbarType=3
ItemCount=12
Item0=2|0|0|31|3|647394|Morph`Objects Compounds|0|0|"Morph Compound Object"|"Morph"|-1|
Item1=2|0|0|31|3|647394|Conform`Objects Compounds|0|0|"Conform Compound Object"|"Conform"|-1|
Item2=2|0|0|31|3|647394|Boolean`Objects Compounds|0|0|"Boolean Compound Object"|"Boolean"|-1|
Item3=2|0|0|31|3|647394|Loft`Objects Compounds|0|0|"Loft Compound Object"|"Loft"|-1|
Item4=2|0|0|31|3|647394|Scatter`Objects Compounds|0|0|"Scatter Compound Object"|"Scatter"|-1|
Item5=2|0|0|31|3|647394|Connect`Objects Compounds|0|0|"Connect Compound Object"|"Connect"|-1|
Item6=2|0|0|31|3|647394|ShapeMerge`Objects Compounds|0|0|"ShapeMerge Compound Object"|"ShapeMerge"|-1|
Item7=2|0|0|31|3|647394|Terrain`Objects Compounds|0|0|"Terrain Compound Object"|"Terrain"|-1|
Item8=2|58|0|31|3|647394|BlobMesh`Objects Compounds|0|0|"BlobMesh Compound Object"|"BlobMesh "|-1|
Item9=2|43|0|31|3|647394|Mesher`Objects Compounds|0|0|"MesherCompound Object"|"Mesher"|-1|
Item10=2|0|0|31|3|647394|ProBoolean`Objects Compounds|0|0|"ProBoolean Compound Object"|"ProBoolean"|-1|
Item11=2|0|0|31|3|647394|Procutter`Objects Compounds|0|0|"ProCutter Compound Object"|"ProCutter"|-1|
[Tab Panel__3]
TabName="Lights & Cameras"
ToolbarRows=1
ToolbarType=3
ItemCount=15
Item1=2|0|0|31|3|647394|Target_Spotlight`Lights and Cameras|0|0|||-1|
Item2=2|0|0|31|3|647394|Free_Spotlight`Lights and Cameras|0|0|||-1|
Item3=2|0|0|31|3|647394|Omni_Light`Lights and Cameras|0|0|||-1|
Item4=2|0|0|31|3|647394|Directional_Light`Lights and Cameras|0|0|||-1|
Item5=2|0|0|31|3|647394|Target_Directional_Light`Lights and Cameras|0|0|||-1|
Item6=3|6|16|31|1
Item7=2|0|0|31|3|647394|Light_Include`Lights and Cameras|0|0|||-1|
Item8=2|0|0|31|3|647394|Light_List`Lights and Cameras|0|0|||-1|
Item9=3|6|16|31|1
Item10=2|0|0|31|3|647394|Target_Camera`Lights and Cameras|0|0|||-1|
Item11=2|0|0|31|3|647394|Free_Camera`Lights and Cameras|0|0|||-1|
Item12=3|6|16|31|1
Item13=2|71|0|31|3|647394|AreaOmni`Lights and Cameras|0|0|"mental ray Area Omni"|"mr Area Omni"|-1|
Item14=2|69|0|31|3|647394|AreaSpot`Lights and Cameras|0|0|"mental ray Area Spot"|"mr Area Spot"|-1|
Item15=2|69|0|31|3|647394|AreaSpot`Lights and Cameras|0|0|"mental ray Area Spot"|"mr Area Spot"|-1|
Item0=3|6|16|31|1
[Tab Panel__4]
TabName="Particles"
ToolbarRows=1
ToolbarType=3
ItemCount=8
Item0=2|105|0|31|3|647394|PFSource`Objects Particle Systems|0|0|"Particle Flow Source Particle System"|"Particle Flow Source"|-1|
Item1=3|6|16|31|1
Item2=2|0|0|31|3|647394|Spray`Objects Particle Systems|0|0|"Spray Particle System"|"Spray"|-1|
Item3=2|0|0|31|3|647394|Snow`Objects Particle Systems|0|0|"Snow Particle System"|"Snow"|-1|
Item4=2|0|0|31|3|647394|Blizzard`Objects Particle Systems|0|0|"Blizzard Particle System"|"Blizzard"|-1|
Item5=2|0|0|31|3|647394|PArray`Objects Particle Systems|0|0|"PArray Particle System"|"PArray"|-1|
Item6=2|0|0|31|3|647394|PCloud`Objects Particle Systems|0|0|"PCloud Particle System"|"PCloud"|-1|
Item7=2|0|0|31|3|647394|SuperSpray`Objects Particle Systems|0|0|"Super Spray Particle System"|"Super Spray"|-1|
[Tab Panel__5]
TabName="Helpers"
ToolbarRows=1
ToolbarType=3
ItemCount=12
Item0=3|6|16|31|1
Item1=3|6|16|31|1
Item2=2|0|0|31|3|647394|Dummy`Objects Helpers|0|0|"Dummy"|"Dummy"|-1|
Item3=2|0|0|31|3|647394|Grid`Objects Helpers|0|0|"Grid"|"Grid"|-1|
Item4=2|0|0|31|3|647394|Point`Objects Helpers|0|0|"Point"|"Point"|-1|
Item5=2|0|0|31|3|647394|Tape`Objects Helpers|0|0|"Tape Measure"|"Tape Measure"|-1|
Item6=2|0|0|31|3|647394|Protractor`Objects Helpers|0|0|"Protractor"|"Protractor"|-1|
Item7=2|0|0|31|3|647394|Compass`Objects Helpers|0|0|"Compass"|"Compass"|-1|
Item8=3|6|16|31|1
Item9=2|0|0|31|3|647394|Boxgizmo`Objects Helpers|0|0|"Box Gizmo (Atmospheres)"|"Box Gizmo"|-1|
Item10=2|0|0|31|3|647394|SphereGizmo`Objects Helpers|0|0|"Sphere Gizmo (Atmospheres)"|"Sphere Gizmo"|-1|
Item11=2|0|0|31|3|647394|CylGizmo`Objects Helpers|0|0|"Cylinder Gizmo (Atmospheres)"|"Cylinder Gizmo"|-1|
[Tab Panel__6]
TabName="Space Warps"
ToolbarRows=1
ToolbarType=3
ItemCount=24
Item0=2|0|0|31|3|647394|Motor`Objects Space Warps|0|0|"Motor Space Warp"|"Motor"|-1|
Item1=2|0|0|31|3|647394|Push`Objects Space Warps|0|0|"Push Space Warp"|"Push"|-1|
Item2=2|38|0|31|3|647394|Vortex`Objects Space Warps|0|0|"Vortex Space Warp"|"Vortex"|-1|
Item3=2|0|0|31|3|647394|Drag`Objects Space Warps|0|0|"Drag Space Warp"|"Drag"|-1|
Item4=2|0|0|31|3|647394|Path_Follow`Objects Space Warps|0|0|"Path Follow Space Warp"|"Path Follow"|-1|
Item5=2|0|0|31|3|647394|Pbomb`Objects Space Warps|0|0|"PBomb Space Warp"|"PBomb"|-1|
Item6=2|0|0|31|3|647394|Displace`Objects Space Warps|0|0|"Displace Space Warp"|"Displace"|-1|
Item7=2|0|0|31|3|647394|Gravity`Objects Space Warps|0|0|"Gravity Space Warp"|"Gravity"|-1|
Item8=2|0|0|31|3|647394|Wind`Objects Space Warps|0|0|"Wind Space Warp"|"Wind"|-1|
Item9=3|6|16|31|1
Item10=2|0|0|31|3|647394|FFD_Box`Objects Space Warps|0|0|"FFD(Box) Space Warp"|"FFD(Box)"|-1|
Item11=2|0|0|31|3|647394|FFD_Cyl`Objects Space Warps|0|0|"FFD(Cyl) Space Warp"|"FFD(Cyl)"|-1|
Item12=2|0|0|31|3|647394|Wave`Objects Space Warps|0|0|"Wave Space Warp"|"Wave"|-1|
Item13=2|0|0|31|3|647394|Ripple`Objects Space Warps|0|0|"Ripple Space Warp"|"Ripple"|-1|
Item14=2|0|0|31|3|647394|Displace`Objects Space Warps|0|0|"Displace Space Warp"|"Displace"|-1|
Item15=2|0|0|31|3|647394|SpaceConform`Objects Space Warps|0|0|"Conform Space Warp"|"Conform"|-1|
Item16=2|0|0|31|3|647394|Bomb`Objects Space Warps|0|0|"Bomb Space Warp"|"Bomb"|-1|
Item17=3|6|16|31|1
Item18=2|0|0|31|3|647394|SpaceBend`Objects Space Warps|0|0|"Bend Space Warp"|"Bend"|-1|
Item19=2|0|0|31|3|647394|SpaceSkew`Objects Space Warps|0|0|"Skew Space Warp"|"Skew"|-1|
Item20=2|0|0|31|3|647394|SpaceNoise`Objects Space Warps|0|0|"Noise Space Warp"|"Noise"|-1|
Item21=2|0|0|31|3|647394|SpaceTaper`Objects Space Warps|0|0|"Taper Space Warp"|"Taper"|-1|
Item22=2|0|0|31|3|647394|SpaceTwist`Objects Space Warps|0|0|"Twist Space Warp"|"Twist"|-1|
Item23=2|0|0|31|3|647394|SpaceStretch`Objects Space Warps|0|0|"Stretch Space Warp"|"Stretch"|-1|
[Tab Panel__7]
TabName="Modifiers"
ToolbarRows=1
ToolbarType=3
ItemCount=36
Item0=2|0|0|31|3|647394|Bend`Modifiers|0|0|||0|standard_modifiers
Item1=2|0|0|31|3|647394|Taper`Modifiers|0|0|||1|standard_modifiers
Item2=2|0|0|31|3|647394|Skew`Modifiers|0|0|||2|standard_modifiers
Item3=2|0|0|31|3|647394|Twist`Modifiers|0|0|||3|standard_modifiers
Item4=2|0|0|31|3|647394|Stretch`Modifiers|0|0|||4|standard_modifiers
Item5=2|0|0|31|3|647394|Noise`Modifiers|0|0|||6|standard_modifiers
Item6=2|0|0|31|3|647394|Wave`Modifiers|0|0|||7|standard_modifiers
Item7=2|0|0|31|3|647394|Melt`Modifiers|0|0|||19|standard_modifiers
Item8=2|0|0|31|3|647394|Spherify`Modifiers|0|0|||21|standard_modifiers
Item9=2|0|0|31|3|647394|Ripple`Modifiers|0|0|||8|standard_modifiers
Item10=2|0|0|31|3|647394|FFDBox`Modifiers|0|0|||9|standard_modifiers
Item11=2|0|0|31|3|647394|FFDCyl`Modifiers|0|0|||10|standard_modifiers
Item12=2|0|0|31|3|647394|XForm`Modifiers|0|0|||30|standard_modifiers
Item13=2|0|0|31|3|647394|Flex`Modifiers|0|0|||26|Standard_Modifiers
Item14=3|6|16|31|1
Item15=2|0|0|31|3|647394|Morpher`Modifiers|0|0|||23|standard_modifiers
Item16=2|0|0|31|3|647394|Skin`Modifiers|0|0|||25|standard_modifiers
Item17=2|0|0|31|3|647394|Displace`Modifiers|0|0|||17|standard_modifiers
Item18=2|0|0|31|3|647394|Optimize`Modifiers|0|0|||33|standard_modifiers
Item19=2|0|0|31|3|647394|Smooth`Modifiers|0|0|||22|standard_modifiers
Item20=2|0|0|31|3|647394|Cap_Holes`Modifiers|0|0|||28|standard_modifiers
Item21=2|0|0|31|3|647394|Linked_xform`Modifiers|0|0|||31|standard_modifiers
Item22=2|0|0|31|3|647394|Push`Modifiers|0|0|||35|standard_modifiers
Item23=2|0|0|31|3|647394|Vertex_Paint`Modifiers|0|0|||36|standard_modifiers
Item24=2|0|0|31|3|647394|MeshSmooth`Modifiers|0|0|||18|Standard_Modifiers
Item25=3|6|16|31|1
Item26=2|0|0|31|3|647394|Volumeselect`Modifiers|0|0|||3|Max_Edit_Modifiers
Item27=2|0|0|31|3|647394|Mesh_Select`Modifiers|0|0|||2|Max_Edit_Modifiers
Item28=2|0|0|31|3|647394|Edit_Mesh`Modifiers|0|0|||0|Max_Edit_Modifiers
Item29=2|0|0|31|3|647394|Edit_Patch`Modifiers|0|0|||1|Max_Edit_Modifiers
Item30=2|0|0|31|3|647394|Edit_Spline`Modifiers|0|0|||10|Max_Edit_Modifiers
Item31=2|0|0|31|3|647394|Spline_Select`Modifiers|0|0|||9|Max_Edit_Modifiers
Item32=3|6|16|31|1
Item33=2|0|0|31|3|647394|Uvwmap`Modifiers|0|0|||3|Material_Modifiers
Item34=2|0|0|31|3|647394|Unwrap_UVW`Modifiers|0|0|||5|Material_Modifiers
Item35=2|0|0|31|3|647394|Material_ID`Modifiers|0|0|||1|Material_Modifiers
[Tab Panel__8]
TabName="Modeling"
ToolbarRows=1
ToolbarType=3
ItemCount=23
Item0=3|6|16|31|1
Item1=2|0|0|31|3|647394|Edit_Spline`Modifiers|0|0|||10|Max_Edit_Modifiers
Item2=2|0|0|31|3|647394|Extrude`Modifiers|0|0|||12|standard_modifiers
Item3=2|0|0|31|3|647394|Lathe`Modifiers|0|0|||13|standard_modifiers
Item4=2|0|0|31|3|647394|Bevel`Modifiers|0|0|||16|standard_modifiers
Item5=2|0|0|31|3|647394|Bevel_Profile`Modifiers|0|0|||15|Standard_Modifiers
Item6=3|6|16|31|1
Item7=2|0|0|31|3|647394|CrossSection`Modifiers|0|0|||0|surface_tools
Item8=2|0|0|31|3|647394|Surface`Modifiers|0|0|||1|Surface_tools
Item9=2|0|0|31|3|647394|Edit_Patch`Modifiers|0|0|||1|Max_Edit_Modifiers
Item10=2|0|0|31|3|647394|Relax`Modifiers|0|0|||20|standard_modifiers
Item11=3|6|16|31|1
Item12=3|6|16|31|1
Item13=2|0|0|31|3|647394|Edit_Mesh`Modifiers|0|0|||0|Max_Edit_Modifiers
Item14=2|0|0|31|3|647394|Mesh_Select`Modifiers|0|0|||2|Max_Edit_Modifiers
Item15=2|0|0|31|3|647394|Volumeselect`Modifiers|0|0|||3|Max_Edit_Modifiers
Item16=2|0|0|31|3|647394|Face_Extrude`Modifiers|0|0|||4|Max_Edit_Modifiers
Item17=2|0|0|31|3|647394|Affect_Region`Modifiers|0|0|||14|standard_modifiers
Item18=2|0|0|31|3|647394|Push`Modifiers|0|0|||35|standard_modifiers
Item19=2|0|0|31|3|647394|MeshSmooth`Modifiers|0|0|||18|standard_modifiers
Item20=2|0|0|31|3|647394|FFDBox`Modifiers|0|0|||9|standard_modifiers
Item21=3|6|16|31|1
Item22=3|6|16|31|1
[Tab Panel__9]
TabName="Rendering"
ToolbarRows=1
ToolbarType=3
ItemCount=16
Item0=3|6|16|31|1
Item1=2|72|0|31|4|0|40029|0|0|"Environment Dialog"|"Environments"|-1|Maintoolbar
Item2=3|6|16|31|1
Item3=2|41|0|31|4|0|40367|0|0|"Render Effects"|"Effects"|-1|Maintoolbar
Item4=3|6|16|31|1
Item5=2|46|0|31|4|0|40033|0|0|"Make Preview"|"Preview"|-1|Maintoolbar
Item6=3|6|16|31|1
Item7=2|64|0|31|4|0|40403|0|0|"RAM Player"|"RAM Player"|-1|Separator
Item8=3|6|16|31|1
Item9=2|0|0|31|4|0|40312|0|0|"Material/Map Browser"||5|Material_Modifiers
Item10=2|0|0|31|4|0|50048|0|0|"Material Editor"||64|Maintoolbar
Item11=3|6|16|31|1
Item12=2|0|0|31|4|0|60010|0|0|"Render Scene"||66|Maintoolbar
Item13=2|0|0|31|4|0|50031|0|0|"Quick Render (Production)"||70|Maintoolbar
Item14=2|0|0|31|4|0|50030|0|0|"Render Last"||68|Maintoolbar
Item15=2|0|0|31|4|0|40701|0|0|"ActiveShade Floater"||8|Render

Text editing provides you with some pretty good control over the interface that you wouldn’t have from within the program. You can change “double-wide” separators to “single-wide”, which you cannot do through the UI editor in 3dsMax. You can also do stuff like change the order of buttons and add new toolbars like tabbed interfaces. However, you cannot easily change a button’s logo from the text side- you should only do that from within 3dsMax.

For the curious, single-wide separator is

Item#=3|6|16|31|1

while double-wide separator is

Item14=2|0|0|31|3|647394|Separator`Separator|0|0|"Separator"|"Separator"|-1|

That’s it for now!  Enjoy!

Designed by Alejo "Mr. Bluesummers" Grigera"
©2012 MrBluesummers.com