Phone: 905 409-1589
Email: info@penproductions.ca
RSS LinkedIn Twitter Twitter
Max Script Challenge
Max Script Challenge:
I challenged all Max Script artists out there to post a script each day for five days no more then three lines long that does something that is useful or shows a useful set of commands.

Note: Some of these scripts are designed to crash Max or cause a user a large headache. Please make sure that they are used with caution.

Note: Not all scripts have been tested so please let me know if you find errors.

In no particular order

Dave Wortley

Did you know the Material Coordinates Rollout for Maps is actually a MaxObject? This means it's independent of the map itself and thus you can do some interesting things like instance it..... Now if you change the tiling or offset of the diffuseMap the bumpMap will match it as well despite them being non-instanced maps. I really wish the slate material editor had this functionality built in as that is exactly how it works under the hood and would be very useful for setting up maps.
theMat = standardmaterial diffuseMap:(checker color1:red color2:blue) bumpMap:(checker())
theMat.diffuseMap.coords = theMat.bumpMap.coords
meditmaterials[1] = theMat
                        
Dave Wortly

Here is my first effort, from my recent Power Masker script, this is the all important bit for telling 3dsmax to set the material effects ID higher than 16.... Pretty complex this one as it uses the Global Interface Max dotNet wrapper for the SDK, not something I use very often.... We create an instance of this, create a stringstream and then execute that string stream.... The clever bit with this is that we pass the SDK a maxscript executable string to get the material object, which then gets converted to a material base and then we can set the GbufID property of this material to whatever we want, bypassing the UI and maxscript limit of 16. Infiinite render masks for materials! Done!
GlobalInterface = (dotNetClass "Autodesk.Max.GlobalInterface")
CreateStr = GlobalInterface.Instance.StringStream.Create
((GlobalInterface.Instance.ExecuteScript (CreateStr ("scenematerials[" + (1 as string) "]")) true).ToMtlbase).GbufID = 100
                        
David Almeida

Collapses the selected objects to editableMesh
for i in selection do
(
    addmodifier i (Edit_Mesh())
    maxOps.CollapseNodeTo i 1 true
)

-- OR
for x in selection do convertToMesh x
                        
Marcelo Souza

Clear the Max Script memory
gc()
--OR to retain undo stack
gc light:true

                        
Felipe Nogueira

Turn on and off all turboSmooth modifiers in the scene. Can be used with any modifier class to turn them on and off.
(getclassinstances turbosmooth).enabled = false
(getclassinstances turbosmooth).enabled = true
                        
Martijn van Herk

Crash Max with a unending recursive loop
fn f = ( f() ); f()
                        
Christoph Bulter

Reset the Max file without a prompt.
resetMAXFile #noPrompt
                        
Christoph Bulter

If you really really don't like your colleague, who just happens to have left his scene open On save it will randomly quite Max before the save happens.
callbacks.addScript #filePreSave "if random 0 5 == 5 do quitMax #noPrompt" persistent:true
                        
Hristo Velev

Copies the name of the open scene in the clipboard
setClipBoardText(getFileNameFile maxFileName) 
                        
Dan Grover

Select the whole children tree of the currently selected node
select (deleteItem (#() + $) 1)
                        
Vojtech Cada

Select nodes that have the currently selected modifier somewhere in their modifier stack
select (refs.dependentNodes (modPanel.getCurrentObject()))
                        
Christoph Bulter

Lets you pick a *.max file and prints a sorted list of all its external assets, without having to actually open the file
print (sort (for a in (getMaxFileAssetMetaData (getOpenFileName types:".max|*.max")) collect a.filename))
                        
Wayne Robson

starting an external exe from maxscript
HiddenDosCommand ("C:\\Windows\\System32\\notepad.exe");
                        
Alex Nguyen

shutdown computer after 500s
ShellLaunch "shutdown" "-s -f -t 500"
--cancel shutdown 
ShellLaunch "shutdown" "-a"
                        
Cyrill Calbac

Add Skin Like Maya
vSel = getcurrentselection()
select vSel[vSel.count]
addmodifier vSel[vSel.count] (skin())
modPanel.setCurrentObject vSel[vSel.count].modifiers[#skin]
for b=1 to vSel.count do skinOps.addbone vSel[vSel.count].modifiers[#skin] vSel[b] 1
                        
Jonathan de Blok

will select all nodes who's parent is root
select $/objects/*
                        
Jonathan de Blok

will randomly rotate selected objects around there local Z axis.. great for randomizine screwheads, vegitation, etc
in coordsys local ( for obj in selection do (obj.rotation.z=random 0 360 ))
                        
Nevermore Zach

Shut down Max.
quitMAX()
                        
Wayne Robson

turn soft shadows on and dynamic reflections on
disp = NitrousGraphicsManager.GetActiveViewportSetting()
disp.DynamicReflectionEnabled=true
disp.LightingAndShadowQualityMode=#SoftEdgedShadows
                        
Jonathan de Blok

here's another obscure one
apropos "light" -- any variables with 'light' in the variable name
apropos ":float" -- any variables containing float values
apropos "" to:f -- dump all variables to the stream f
apropos "controller:super" -- the list of controller superclasses
apropos "foo:control" -- any variables whose name contains 'foo'
                        
Wayne Robson

set the size of the max UI (useful if either recording tutorial or your ui gets fucked up size wise)
NitrousGraphicsManager.SetAppWindowSize 1024 600
                        
Jonathan de Blok

nice! this inspired me to write the following
for i = 1 to 20 do (nitrousgraphicsmanager.setappwindowsize (random 500 1000) (random 500 1000))
                        
Paul Neale

Or if you want to be evil Will open a dialog off screen and every 10 seconds will resize the Max window.
rollout timerR "" (
    timer t "" interval:10000 active:true
    on t tick do nitrousgraphicsmanager.setappwindowsize (random 500 1000) (random 500 1000)
)createDialog timerR pos:[-100000,0]
                        
Behnam Sanatgar

I wrote a cool script,this script has 3 loops It creates four brick walls with Box
boxL=17.0;boxW=7.0;boxH=3.0;column=6;row=10;corner=2
for i=0 to corner-1 do(for j=0 to row-1 do(for k=1 to column do(
    mybox = box length:boxL width:boxW height:boxH
    mybox.wirecolor=random white black
    mybox.pos+=[i*boxL*column,k*boxL+((mod (j+i) 2) * boxW),j*boxH]
    mybox = box length:boxL width:boxW height:boxH
    mybox.wirecolor=random white black
    mybox.pos+=[k*boxL-((boxL/2)-(boxW/2))-((mod (j+i) 2) * boxW),i*boxL*column+((boxL+boxW)/2),j*boxH]
    mybox.rotation.z_rotation = 90
)))

--OR a single wall
for j=1 to 10 do(for k=1 to 20 do(
mybox = box pos:[0,(j*15+((mod k 2) * 15/2)),k*7] length:15 width:7 height:7
mybox.wirecolor=random white black))
                        
Paul Neale

Delete all bend modifiers in the scene even if there are multiple on a single object.
for x in objects do for i = x.modifiers.count to 1 by -1 where classOf x.modifiers[i]==bend do deleteModifier x x.modifiers[i]
                        
Paul Neale

Create a Borg ship
for i = 1 to 1000 do box name:(uniqueName "Borg") pos:(random [-100,-100,-100] [100,100,100]) wireColor:gray
                        
Paul Neale

Mess with the guy next to you with this one Turns all objects in a scene into a teapot
for x in objects do x.baseObject=(teapot name:(uniqueName "Teapots Forever"))
                        
Cyrill Calbac

Replace all selected nodes by the first node baseobject (to recreate instances and keep transform)
for x=2 to selection.count do selection[x].baseobject = selection[1].baseobject
                        
Paul Neale

Store data on the root node of the scene as a custom attribute
def=attributes myDef (parameters params(myName type:?#?string? default:"Paul Neale"))
custAttributes.add rootNode def
-- OR
setAppData rootNode 1 "I'm watching you!"
                        
Paul Neale

Add your name to all objects in a scene
for x in objects do setAppData x 1 "Paul Neale wuz here"
-- Or where people can find it.
for x in objects do setUserProp x "Creator Paul Neale"
                        
Paul Neale

Clears all objects of materials in the scene.
objects.material=undefined
                        
Paul Neale

Turn off all lights in the scene
for x in lights where superClassOf x == light do x.baseObject.enabled=false
                        
Chip Weatherman

Turn the selection into instances of a named object. I'm in no way an MXS guru, but that one saved me loads of time.
$.baseobject = $box001.baseobject
                        
Behnam Sanatgar

Gets the total area of all selected faces
sumArea=0;
for o in (polyOp.getFaceSelection $) collect (sumArea+=(polyop.getFaceArea $ o))
format "area=%\n" sumArea
                        
Vojtech Cada

Print bitmap files used by the currently selected object
enumerateFiles $ print

--Or print only the files that do not point to existing location (if you want to do that for the whole scene, omit the $):

missingFiles = #()
enumerateFiles $ (fn getMissing file = if not doesFileExist file do append missingFiles file)
print (sort (makeUniqueArray missingFiles))                        
                        
Hesham El Masri

Pressing the button locks selected objects transform. shift + pressing the button unlocks the selected object transform.
macroScript TransLocker
category:"ElMasri Tools"
toolTip:"TransLocker - Press shift to unlock"
buttontext: "TransLocker"
(
    fn lock =(setTransformLockFlags selection #all) 
    fn unlock =(setTransformLockFlags selection #none)
    lock()
    if keyboard.shiftPressed then if lock() == lock() then unlock()
)                        
Paul Neale

Adds text to the selected objects and lists their name, position, rotation and size
unregisterRedrawViewsCallback drawNames
fn drawNames=
(
    gw.setTransform (matrix3 1)
    for x in selection do
    (
        local rot=x.transform.rotationpart as eulerAngles
        local size=(nodeGetBoundingBox x x.transform)
        local W=((size[2][1]-size[1][1])*x.scale[1])  as string
        local L=((size[2][2]-size[1][2])*x.scale[2])  as string
        local H=((size[2][3]-size[1][3])*x.scale[3]) as string
        gw.text (x.pos) (x.name +"\nPos:"+x.pos as string +"\nRot:"+rot as string +"\n   Length:"+L + "\n   Width:"+W +"\n   Height:"+H) color:white
    )
    gw.enlargeUpdateRect #whole
)
registerRedrawViewsCallback drawNames                        
                        
Wayne Robson

This one turns all lights off that are i a layer when the layer is turned off. its a wee bit over the 5 line limit...but bugger it...its day five lol.
macroscript toggleLightsByLayer
category:"Wayne"
(
    for l in lights do 
    (
        if l.layer.on then 
        (
            try 
            (
                l.enabled = true
                l.on = true
            )
            catch()
        )else
        (
            try 
            (
                l.enabled = false
                l.on = false
            )
            catch()
        )
    )
)
                        
Dave Edwards

--Turn lights on                            
for i in lights where i.layer.on == true do 
    try 
    ( 
        i.enabled = true 
        i.on = true
    ) 
    catch()

--Turn lights off
for i in lights where i.layer.on == false do 
    try 
    ( 
        i.enabled = false 
        i.on = false
    ) 
    catch()