Nothing is ever finished…

Last week I released a little script called the VRay Material Override Excluder. Just to prove nothing is ever finished, even the name has changed since I last blogged about it on here.

Updates include, support for VRay Material Override Include/Exclude list from the render settings, get the material from there too, override XRefScene object materials and use multiple wildcard entries to filter out material names that you don’t want to exclude.

I really hope all this power will encourage you to be more organised with your scenes!

You’ll hear a lot from software companies talking about ‘Agile’ developments these days, and being responsive and being able to improve and quickly add new bits to plugins/scripts/software is really important to be competitive and relevant.

I love the power of crowd-sourcing for ideas, you are never smart enough to think of every use-case scenario, you will never find all the bugs yourself, and you don’t have every different version of max to test your tools with. It’s something about 3dsmax users in particular which makes them so passionate about using the software, they care, it’s why Autodesk will never be able to kill off 3dsmax.  I put up a script on a website and instantly I get feedback, ‘this doesn’t work as I expect’, ‘oh it can’t do this?’, ‘it would be awesome if it could do this…!’ In the matter of one week I pretty much doubled the code size whilst putting in protection to make sure the script would never crash and would work in every situation and have some new functionality.  What I lose in publicly releasing this scripts I gain massively in feedback, it’s a huge amount more powerful and with the enthusiasm and persistent drive to want more and better tools I find it helps me stay focused on getting the tool finished rather than being resigned to the scrap-heap of scripts I have somewhere on my old laptop.

The next thing is how do I make this script professional? It started as a 10 line bit of code on the Chaosgroup forum… now it’s 700 lines long and can do so much. But it’s still a script in a rollout. There’s no API, you can’t assign hot-keys to the main functionality, and if you are doing chalk setups every day as part of your job you may want a one-click button to set all your options. This is where setting up a script as a struct is such a good idea.  I will at some point soon convert this script and expose the functions within the script so that you can make your own tools that interface with it.  It’s a change in style I started to adopt a few months ago whilst working on some personal ideas with some 3d friends, learning from people like Daniel Santana from YCDIVFX, I’ve been building struct scripts with APIs so that they can be used by other TDs in their tools.

To be continued…

Posted in 3dsmax, MaxScript | Leave a comment

Chalk Mat Switcher

Do you use the Vray Material Override to do chalk renders and wish that it would allow you to exclude certain materials? Like VRayLightMtl and any refractive materials like glass? Well now you can using this little script.  It sets up a Shell Material which allows you to switch from one material setup to another. So even if those pesky VRayLightMtls and refractive materials are within Multi-sub materials then you’ll still be able to exclude them. Give it a go, test it out and let me know how it works for you! Cheers to Fraggle from the Chaosgroup forums for giving me the motivation to do this one, I’m sure I’ll find a use for it at some point too. It should be easy enough to hack it for Mental Ray or other renderers.


Choose the Material Editor Sample Slot you want to get your Chalk Shader from, that’s down bottom left in Slate or one of the sample slots in the Compact-Material-Editor.  Keep the excludes on for whichever materials you want to preserve (let me know if you want more there). You can keep refractive materials and automatically desaturate refraction / fog / exit colour/maps.

You can choose to keep opacity maps/bump maps/ displace maps this will work with nested materials, multi-sub, VrayBlends etc… You can also exclude by a material name, and using Wildcards you can exclude all materials which have glass in their name for instance by putting in *glass* into the name exclude box.

You can also get your the objects you have in your include/exclude List in the VRay Material Override Exclude Dialog.


Press ‘Create Chalk Setup’ and your scene is now ready to render with chalk materials on, you can press ‘Go Material’ at any point to return to the original materials, and press ‘Go Chalk’ to go back to rendering chalks. Press ‘Remove Chalk Setup’ to revert back to how your scene was, even if you close and reopen the script.

Hold Shift on the ‘Go Chalk’ and ‘Go Material’ buttons to turn just the selected objects to Chalk or Material.


Get it here on ScriptSpot!

Posted in Uncategorized | Leave a comment

Sometimes there is a simpler way…

A few weeks ago I needed to have a dynamic way of selecting all the Face/Material IDs of an object and deleting everything else. My first thought was, well the Poly_Select modifier has a select by Face/Material ID. However that isn’t dynamic, if your underlying mesh changes, the Poly Select doesn’t update…. sigh.

I thought about a scripted approach with an Edit Poly modifier, but decided that was going to be too slow.

In the end I had a demo of Genome from Thinkbox (an awesome tool, if not a bit scary at first). And I made a cool little custom modifier that allowed me to select by Material ID, or select by not the Material ID.

This worked, but then the other day I realised I had over-engineered the solution. There’s a modifier which I use over and over again to make things procedural, and it’s one of 3ds Max’s most powerful tools. Volume Select allows you to keep things procedural, you can create volume shapes to recreate the manual process of going into a sub-selection and drawing out a marquee to select polygons, you can use Soft-Selection as well which is always nice. You can also select by a map material which is super useful, especially as it supports 3d maps. However the one feature I’d completely forgotten about is that it can also select by material ID! You can also Invert the selection in this modifier and thus use a DeleteMesh modifier (Again one that is under-used by most people because they don’t realise when you have a stack-selection it become very useful!)

select_by_material_ID_1 select_by_material_ID_2

Posted in 3dsmax | Leave a comment

A chance to heckle me…

I’m really pleased to be invited to give a talk at EUE (End-User-Event) in Holland this coming June. I plan to give a slightly technical talk and show some secret things I’ve been working on for the last couple of years.

If you’re based in Europe, I cannot rate this event highly enough! 250 3ds max artists in a pub, in a beautiful Dutch city. You’ll learn loads, meet some amazing people, make connections and contacts that will be infinitely useful.

Book your ticket now whilst the air-fares are cheap!

Posted in Uncategorized | 1 Comment

pFlow – Put Nodes on the Same Layer as the PFlow Source

Ever wanted to have PFlow nodes on the same layer as your PFlow Source object? But you don’t see them in the scene explorer and can’t select them in the viewport.

Well here’s a script that can do it!

—-This script puts all the Pflow events and nodes on the same layer as the PFlow Source Object

fn getPFlowChildren theNode theSource =
thechildren = for o in getpropnames theNode where (getnodebyname o) != undefined collect (getnodebyname o)
for o in theChildren do
theSource.layer.addNode o
getPFlowChildren o theSource

if classof o == Event do
for n in (refs.dependentNodes o) do theSource.layer.addNode n

for o in getclassinstances PF_Source do
theFlow = (refs.dependentnodes o)[1]
getPFlowChildren theFlow theFlow
for theNode in (refs.dependentNodes theFlow) do
theFlow.layer.addNode theNode

Posted in Uncategorized | 5 Comments

Sub-Object Isolate Toggle

One of those things which is possible when you know where the buttons are, but it should really be on a hot-key. Assign this to a shortcut key to be able to isolate within subobject mode, Vertex/Face/Element 🙂

–Toggles Isolation of editable Poly subobject face selection
if isEPolyIsolate == undefined do global isEPolyIsolate = false

if selection.count == 1 and classof selection[1] == Editable_Poly do
if not isEPolyIsolate then
with redraw off
actionMan.executeAction 0 “40044”
$.EditablePoly.Hide #CurrentLevel
actionMan.executeAction 0 “40044”
isEPolyIsolate = true
$.EditablePoly.unhideAll #CurrentLevel
isEPolyIsolate = false

Posted in Uncategorized | 1 Comment

Lesson 14: Key principles of understanding working with MaxScript

Here are the key principles to working with MaxScript, you need to know about all the things listed below to be able to understand how to write scripts. Here is a brief overview and description of each thing, I’ll try get around to linking everything to the relevant section on my blog.

Value Types

These are the key types of variables in maxscript.

String – “Text, always within quotations marks, \ is an escape characterm \t would be a tab, to avoid this you can type\\t or put@ before the first quotation”
Integer – A whole Number, 1,2,3 typing in 1.2 as integer would give you 1, typing 1.8 as integer would also give you 1, rounding does not take place automatically you need to write a function for it.
Float – A non-whole number, 1.2232 for example.
Boolean – a True or False value
Point2 – two values, [x,y], 2-dimensional position for bitmaps for example or [width,height], values are float within…. [1.23,5]
Point3 – three values, [x,y,z] or [r,g,b] this is a 3-dimensional position or colo(u)r value.
Color – expressed as (color 128 128 128) or (color 128 128 128 255), it’s either an RGB value with an assume alpha value of 255 (solid), or an RGBA value.
Box2 – This is an area of a 2d space, (Box2 x y w h), x-position, y-position, width and height
StringStream – Like a string value, but better for memory for large values, and formatting values.
FileStream – A StringStream value that is written/read from a file.
Array – A collection of values, this can be a mix of types: #(1,1.2,abc,”test”)

Class System

You need to be able to understand how the class system works in max, how things are sub-classes of superclasses, and which category

ClassOf – Find what class a max object belongs to, ie Classof $VRayLight001 returns VRayLight
SuperClassOf – findout what Superclass an object belongs to, SuperClassOf $VRayLight001 returns Light
GetClassinstances – get an array of all the objects which are of the specified class, getClassInstances VRaylight returns #(VrayLight001,VRayLight002)

Inspecting Things

ShowProperties – Shows the properties of the object, showProperties (Box()) will show all properties that can be set Box001.height =1o for example
ShowMethods – Shows the Methods associated with the object, treat theses as functions for targeted objects. layer.getlayerbyname “test”, note that there is no = , you’re not setting a value you’re calling a function.
ShowInterfaces – will show the Properties and the Methods associated with the object

Iterating and Looping

For i Loops – Iteration loops going through a numeric sequence, for i = 1 to 1000 by 2 do…..
For o Loops – For variable in collection do… for o in objects do o.boxmode = true
Collecting Loops – For when you want to go through an array and filter the items. ar_Objs = (for o in objects where o.boxmode collect o)

Functions – Call a function with arguments – testFunction valA valB – and understand how to return a value.

Understanding the Help File

To be able to learn more you’ve got to be able to understand what <BOOL>, <VOID> mean in the help file.

Posted in 3dsmax, Lessons, MaxScript | 2 Comments

Overdriving Max

I don’t know why you’d really want to but I’ve seen a few people getting annoyed at the Render Size limit in max of 32768 x 32768, this limit in Max is not because Max can’t render any larger, it’s just because the spinner you use to set your render size has an internal range limit of 1-32768. You can actually force max to render bigger by over-driving this value using maxscript.

Close your Render Scene Dialog

Put this into your maxscript listener

RenderWidth = 100000

Open up your Render Scene Dialog again….

It will read 32768, but if you press render you’ll get a 100000px wide render.

Beware memory usage, but if you’re just rendering something in scanline, or using Deadline to Tile Render then you can use this to get a bigger render.


This trick can often work with other parts of max and other renderers where the UI will restrict the value but you can over-drive the value, for example it may be a sampling setting or subdivision setting that is old and limited in the UI.

A very practical usage I found of this lately was to make the Normalize_Spline segment length less than 1.0, the UI is limited to 1.0 but via maxscript you can set it to much smaller.

Posted in 3dsmax, MaxScript | 1 Comment

Lesson 11: What’s Bugging me? Part 2

According to my search engine page view requests it seems that lots of people are Googling these error messages so I thought I’d chuck a few more in to help people in their time of need.

viewport.setcamera = newCam
>> MAXScript Rollout Handler Exception: -- Unknown property: "SetCamera" in #Struct:viewport(

This is quite easy to do as it seems like you need to set a property to to tell the viewport which camera it should be, where as actually it’s a method function so you want to pass it an argument, see below how it should be.

viewport.setcamera newCam
fn myfunction arg
-- Error occurred in anonymous codeblock; filename: Y:\; position: 2023; line: 10
 -- Syntax error: at (, expected =
 -- In line: (

Another of the sometimes hard to trace bracket problems, it’s an easy mistake to make but can take bloody ages to spot why, when you’ve just missed out an = sign…. sigh…

fn myfunction arg =

doesfileexist (getdir #maxroot) + "plugins\\Test.dlx"
-- No ""+"" function for true

It can be quite easy to forget to bracket things in a way which leaves no confusion to a computer, in the example above it thinks it needs to evaluate doesfileexist and then add this to “plugins\\Test.dlx” not add (getdir #maxroot) to “plugins\\Test.dlx”. I’m always in favour of putting in extra brackets to make damn sure you know what order things will be processed in.

doesfileexist ((getdir #maxroot) + "plugins\Test.dlx")
ObjsIwant = for o in objNames where matchPattern o pattern:"*mesa*" collect o
mergeMAXFile "c:\\project\\ep002_background_02.max" Objsiwant

and this is the error:

-- Error occurred in anonymous codeblock; filename: c:\project\; position: 203; line: 3
 -- No "map" function for undefined

No ‘Map’ for undefined means the for loop doesn’t know what it’s looking in, in this case objNames wasn’t defined beforehand., so instead of the for loop looking in an array the loop was trying to use an unknown value which wasn’t an array it was just ‘undefined’

show standardmaterial()
 -- Argument count error: show wanted 1, got 2

Whenever you want to call the Show (or ShowProperties) function remember if you’re creating an instance to get the properties of you need to encase it in brackets.

show (StandardMaterial())

It’s worth noting that you are creating instances doing this, this is quite obvious when you try using a node/object type.

show (Sphere())

You’ll now have a sphere in your scene at [0,0,0]

s = CREATE_XML_Xmesh_test_01_.MS
 -- Unknown property: "MS" in undefined

This can be a silly thing when you’ve simply forgotten to put quotation marks around a string value.

s = "CREATE_XML_Xmesh_test_01_.MS"
Posted in Lessons, MaxScript | Leave a comment

Lesson 13: It’s all a matter of Scale (not just for maxscripters)

Please excuse the epic ranting rambling of this post, been writing bits of it for weeks, It’s not just for script writers, it’s for everyone who uses 3dsmax, It’s really worth a read and very very important to understand and I wish all 3ds max artists would understand this to avoid lots of common unnecessary problems.

We use a lot of Turbosquid models and model collections and one of the most annoying things is to find that scale hasn’t been taken into consideration, also I see a lot of posts on CGTalk that complain about the way max’s viewport isn’t working properly, getting clipping planes and weird behaviour when trying to move verts, and often this is all to do with using inappropriate unit scale. So here is a quick guide to scale in 3ds Max, and why it is so very important to understand it.

In max you have display units and system units, there is a key difference between the two and it’s very important to use the correct one.

System Units are the important ones, these are the ones that determine what a generic max unit equates to. As a general rule it’s good to put your system unit scale to match the scale of your object. So if you are working on a large environment covering hundreds of metres then you probably want to set it to metres, if you are working on something like a car then centimetres would be more appropriate. If you are working on something very small like a watch or a diamond ring then you probably want to work in millimetres.

Here’s a quick visual example showing how the system scale can mess up your clipping planes if you use it incorrectly.

A 10x10x10cm box, and in 3 different unit setups, look at how using the a smaller scale system unit setup can allow you to get really close to the tiny chamfer on the object.


Continue reading

Posted in 3dsmax, Lessons, MaxScript | 2 Comments