Posted by MaxStation, 13 June 2011 1:00 am
In the post recovering_3ds_max_files i talked about merging in objects to recover a scene file, in the comments Alex asked whether it would be possible to use MAXScript to automate this. That is indeed possible, there are two MAXScript commands that we'll use:
getMAXFileObjectNames - to get a list of object names from a filemergeMAXFile - to do merge the actual merge
First of all the script (you can download it from here as the blog mangles the code a bit, the light theme of the Area (upper right corner) makes it easier to read the code - or just open the file with the MAXScript editor)
max file new
-- ** to recover from object n:
-- ** set start to one higher than the last successful entry in the log file
-- ** and cancel the file new dialog when you run the script
start=1
file=getOpenFileName types:"Max(*.max)|*.max|All|*.*|"
lg=createFile (file+"-log.txt")
print "start" to:lg
osn = getMAXFileObjectNames file
for i = start to osn.count do
(
print i to:lg
print osn[i] to:lg
flush lg
oss=#()
append oss osn[i]
result=mergeMAXFile file oss #noRedraw #AutoRenameDups #useMergedMtlDups #alwaysReparent
if result==false then print "failed" to:lg
else print "success" to:lg
flush lg
nn=(trimRight file ".")+"merge-"+(i as string)+".max"
print ("saving "+nn)
saveMaxFile nn useNewFile:false
)
print "finished" to:lg
close lg
redrawViews()
So how does the script work?
It does a file new and asks for the file to recover. It then gets a list of the objects names from that file and loops through them, merging the objects in one by one, every time it prints a message in a log file and save the file under a different name.
If 3ds Max crashes at some point you can open the last saved file, edit the MAXScript so that it starts at the object number that's one higher than the last one (so that the crashing object is skipped) and then run the script again. Make sure you select cancel on the file New dialog.
The details
First it does a file new. Then it set the object to start at to the first object in the scene (arrays in MAXScript start at 1). If you'd like to restart at object 6000 change the 'start=1' line to reflect that.
max file new
-- ** to recover from object n:
-- ** set start to one higher than the last successful entry in the log file
-- ** and cancel the file new dialog when you run the script
start=1
It brings up a dialog and asks you for the file to recover.
file=getOpenFileName types:"Max(*.max)|*.max|All|*.*|"
It opens a log file.
lg=createFile (file+"-log.txt")
print "start" to:lg
It gets the list of object names from the file.
osn = getMAXFileObjectNames file
It loops through all the objectnames starting at the value start was set in the first paragraph.
for i = start to osn.count do
It prints the object number and object name to the logfile and flushes it to disk (so that we know where we were if 3ds Max crashes at any point - without flushing the data might not get written to disk).
print i to:lg
print osn[i] to:lg
flush lg
The mergeMAXFile can take an array of object names, so the current object name is put in an array.
oss=#()
append oss osn[i]
And finally we get to merge an object in (file is the .max file we're trying to recover, oss is the list of object names to recover). #noRedraw stops 3ds Max from redrawing the scene (that should speed to process up a bit), #AutoRenameDups automatically renames duplicates, #useMergedMtlDups uses the file materials if there duplicates and #alwaysReparent always reparents the objects.
result=mergeMAXFile file oss #noRedraw #AutoRenameDups #useMergedMtlDups #alwaysReparent
Depending on whether the mergeMAXFile command returns success or failure it logs that in the log file and flushes the log file.
if result==false then print "failed" to:lg
else print "success" to:lg
flush lg
It then puts a name together and saves the scene (so that we have a starting point if 3ds Max crashes). It does that by stripping off the .max extension using trimRight, then adds the string "merge-", the object number and finally appends ".max".
nn=(trimRight file ".")+"merge-"+(i as string)+".max"
print ("saving "+nn)
saveMaxFile nn useNewFile:false
That's the end of the loop. Once done it print "finished" to the log file, closes the log file and redraws the viewports.
print "finished" to:lg
close lg
redrawViews()
For more details on the MAXScript commands see MAXScript Help 2012/
Please only report comments that are spam or abusive.
1 Comment
pixelerator7
Posted 13 June 2011 7:08 pm
Add Your Comment
You must be logged in to post a comment. Login or Register here