Lesson 7: What?.. you want me to do all these things to how many files!?

Sometimes you’ll come across a situation where you need to do the same thing to a load of max files and it can be a real pain in the ass to not only go through every max file and do the changes, but also to make sure all the changes are consistent and you’ve remembered to do all the changes. Here’s a quick example of a task I need to do today to about 15 files, not a major issue to do it by hand, but imagine if that was 50 or 100 max files. Basically swap one object for another in a bunch of passes, (for those that say why not use containers or xrefs, trust me it never works how you want it to when you need to swap objects!) So the first time you write this sort of script it’ll probably be slower than if you were to do it manually but you sometimes have to look at the long term and realise how much time this could save you next time you come to do something similar. It’s brilliant  when your boss comes round and asks you to do the same thing for another 30 files and you can just press one button and leave it to it!

--get the material of old object
themat = $Sphere001.material
--delete the old object
delete $Sphere001 
--merge in new object
mergemaxfile "c:\\temp\\test.max" 
--apply old material
$NewSphere.material = themat 
--change render output
 RendOutputfilename = replace RendOutputfilename (findstring RendOutputfilename "shot01") 6 "shot02"
makedir (Getfilenamepath RendOutputfilename) all:true
--set new render range
rendTimeType = 4
rendPickupFrames = "91-207"
 --Save the max file
savepath = maxfilepath + maxfilename
savepath = replace savepath (findstring savepath "shot01") 6  "shot02"
Savemaxfile savepath

So as normal, lets go through our script and see what it’s all doing, we define a new variable called ‘themat’ which we assign to the material of our old object, then we delete our old object, merge in the new one and then assign ‘themat’ material to the new object. Next we change the Render output filename….

RendOutputfilename = replace RendOutputfilename (findstring RendOutputfilename "shot01") 6 "shot02"

We’re using two new functions here, Replace() and findstring(), replace() will replace bits of a string value (that’s text to humans), with other bits, it has a few parameters, lets look at what the maxscript help file says and lets understand it.

replace <string> <from_integer> <length_integer> <new_string>

So our replace function requires 4 parameters, the string we want to change, next the ‘from_integer’, a string value is a bunch of text letters, (“a”, “b”, “c”) which can be indexed of course, if our string was a = “test” , then a[1] would be “t”, the first letter in our string in other words. So when the function requires a ‘<from_integer>’ parameter we have to tell it from what letter in our string we want to start changing things, the <length_integer> specifies how many letters we’re going to remove from our original string before we insert a new one, and the <new_string> value is as you might expect the new string we’re going to insert at our <from_integer> point.  Lets do some practical examples and see what happens.

a = "test"
replace a 1 1 "b"  --returns "best"
replace a 1 2 "b" --returns "bst"
replace a 2 1 "eee" --returns "beeest"
replace a 2 2 "eee" --returns "beeet"

Small important things to know, make sure the <from_integer> is not bigger than the length of the string, and make sure the <length_integer> is not longer than the length of the string minus the from_integer, or you’ll get errors… see below

replace a 5 1 "b" --throws an error, there is no 5th letter in "test"
replace a 1 5 "b" --throws an error, we can't replace 5 letters of a 4  letter word.

It’s important to understand as well that the replace function is returning a string, but in the 4 examples I just gave you above, the returned string isn’t being assigned to any property or variable so it’s lost to the ether.  If you actually want to replace a letter in our variable a then you need to assign it as well… ie..

a = "test"
replace a 1 1 "b"
print a --returns "test"
a = replace a 1 1 "b"
print a --returns "best"

I’ve done it a number of times where I’ve forgotten to actually assign my new string to a value and spent ages trying to figure it out.

So if you look at my original code above you’ll see instead of specifying a number value for the <from_integer>, we instead call another function, Findstring() which will return an integer. Lets look at what the maxscript help says about Findstring().

<integer>findString <string> <search_string>
Returns the index of search_string in string or undefined if not found. 

So the first bit  <integer> is telling us that this function will return an integer, it’s got 2 parameters, the string we want to search and the string we want to search for, and if it doesn’t find the string it’ll return ‘undefined’, which can cause issues in our script, lets look at some examples…

a = test
findstring a "t" --returns 1
findstring a "es" --returns 2
findstring a "s" -- returns 3
findstring a "P" -- returns undefined

So back to the line of code in question….

RendOutputfilename = replace RendOutputfilename (findstring RendOutputfilename "shot01") 6 "shot02"

We should now be able to understand that we’re assigning the RendOutputFilename to be the Render Output Filename, with the text string “shot01” replaced by “shot02”. This script is fairly simple, it won’t deal with a situation where you have “c:\test\shot01\shot01_.tga” it’ll only change the first “shot01”. We’ll get into looping/iterating changes another day.

Other limitations of this simple script will come in if the merged object has a duplicate name/material.

You could use the above script with something like Paule Neale’s excellent BatchitMax script….

http://paulneale.com/scripts/batchItMax/batchItMax.htm

Or you could write a simple loop to iterate through all the files in a folder, sometimes instead of writing complex code to be able to choose which files you want to do it on, it’s just easier to move all those files into a new folder and just run it on the content of the folder.

for o in (getfiles "c:\\test\\*.max") do
(
    loadmaxfile o quiet:true

    --paste code above here...

)

This will go through and run the above script on every max file in that folder, the only bit would be submitting to a render farm if you need it rendered as well, this get slightly complicated now because there are different rendering systems out there. Backburner in my view should either be re-written, made open-source or left in a dark cupboard under the stairs in the basement of Autodesk. It’s awful to script with, extremely limited and extremely frustrating. On the flip-side if you were to use a proper rendering system such as Thinkbox’s Deadline then you can do lots and lots of customisation and custom submission scripts.  I’ll get onto Deadline submissions another day, too complex to explain for now.

Advertisements

About davewortley

Somewhere between an artist and a programmer, I like technical things, but being creative. I love problem solving and coming up with elaborate solutions. This blog is where I shall share ideas, tips, tutorials and anything that amuses me.
This entry was posted in Lessons, MaxScript. Bookmark the permalink.

4 Responses to Lesson 7: What?.. you want me to do all these things to how many files!?

  1. Maxscript help documentation sucks. I typed in replace in the search field and nowhere near did it get close to finding the (replace) method.

    Like

  2. Alberto says:

    Amazing lessons !! very helpful, so thank you Dave !!

    I’m trying to merge 3 files named 1.max , 2.max and 3.max, then attach the objects etc…

    I tried this script but it doesn’t work, how could I do this ?

    for i = 1 to 3 do
    (
    print (“the number is:” + i as string)
    mergemaxfile “C:\\Users\\albator\\Desktop\\Test\\[i].max”
    )

    Like

    • davewortley says:

      You are currently telling max to merge a file called “[i].max” not “1.max”

      What you want to do is:
      mergeMaxFile (“C:\\Users\\albator\\Desktop\\Test\\” + i as string + “.max”)

      Like

  3. Alberto says:

    Thank you !
    I tried Maxscript a few times over the years and could never wrap my head around it.

    Your way of teaching is very helpful.

    Do you do scripts on demand ?
    As a freelancer I’d gladly pay for a script.
    Right now I’m trying to make one, it’s clear and simple in my head, but I feel it’s going to be full of hacks and not very “elegant” once written down.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s