[Closed] MAXScript Speed
G’day all,
I’m doing some visualisation for an oil company, and I’m running into some interesting speed issues with my .ms files. While I can’t post my actual code, here’s something akin to what I’m trying to do:
fn createcones =
(
for i = 1 to 1000 do
(
c = cone()
c.pos = [0,0,i-500]
)
)
fn changecones =
(
start = timestamp()
undo off
(
for c in $cone* do
(
c.material = standard diffuse:(color 64.0 64.0 64.0 ) selfIllumAmount:2.0 opacity:2.0
)
gc()
)
end = timestamp()
format "changecones() took % seconds
" ((end-start)/1000.0)
)
Nice and simple – with the actual project I’m using something in the order of 180,000 objects, so speed is of the essense.
My problem is with repeated execution of the above code – works entirely adequately the first time around, then slows down with every subsequent call.
Here’s some typical results:
changecones()
changecones() took 2.078 seconds
OK
changecones()
changecones() took 3.469 seconds
OK
changecones()
changecones() took 5.656 seconds
OK
changecones()
changecones() took 10.125 seconds
OK
changecones()
changecones() took 17.984 seconds
OK
A six minute turnaround for 180,000 objects isn’t great, but I can live with it – nearly an hour to do the same tweaking of the data just because I’ve run it 5 times? Not so good!
If anyone can point out a better way or if I’m making some boneheadedly obvious mistake, I’d greatly appreciate it!
Happy New Year All!!
I’m not a pro at MaxScript, so take my advice with some salt…
But I already hit a problem with large number of polys on screen that are being modified… Or simply a large ammount of object.
The problem I had was the viewport refresh… Every action the script take that affect the scene call for a refresh… unless you disable it.
use :
[b]disableSceneRedraw/b
at the start of your script and
[b]enableSceneRedraw/b
at the end to disable and enable the viewport refresh.
The bad side to that is, if your script crash, the viewport stay disabled. You can turn it back on in many way. Personnaly I do a Hold and a Fetch.
Print out sceneMaterials.count. Looks like you’re creating 1000 new materials every time you run the script and they’re probably still in the scene. You’re better off assigning a mat on object creation and then manipulating that mat when needed.
edit: just confirmed this. Every time I ran the script in 2008, sceneMaterials.count uped by 1000.
There is a thread somewhere around about how to solve this – Max does not update its internal material database unless you perform a file i/o of the Max file. We found out that the simplest way to force an update of the sceneMaterials.count is to perform a “dummy” save selected, something like
saveNodes #() (GetDir #scene + "\\_Temp.max")
deleteFile (GetDir #scene + "\\_Temp.max")
This saves an empty file to disk and deletes it afterwards, but this forces Max to update as if a real save was performed. Calling holdMaxFile() will have the same effect, but would take much longer…
U.S.S. Speed, focomoso & Bobo – Thanks so much guys – I’ve shaved a heap of time off the update function, but it’s still growing – I think I’ve got a problem with my object creation.
I made this little function:
fn conetest iterations num_cones =
(
disableSceneRedraw() -- thanks U.S.S. Speed!
for i = 1 to iterations do
(
start = timestamp()
for j = 1 to num_cones do
(
c = cone()
c.pos = [0,0,j]
)
end = timestamp()
format "iteration % took % seconds
" i ((end-start)/1000.0)
)
EnableSceneRedraw()
)
and some results:
conetest 5 400
iteration 1 took 2.078 seconds
iteration 2 took 2.594 seconds
iteration 3 took 3.156 seconds
iteration 4 took 3.718 seconds
iteration 5 took 4.375 seconds
OK
is ‘c’ not being cleaned up or something?
thanks again for all your help – it’s been invaluable so far!
slight change – I removed the local variable c in the inner loop – I do my post creation manipulation based on the object’s name, so it’s not necessary. Now it looks like this:
for j = 1 to num_cones do
(
cone pos:[0,0,j] boxmode:true
)
which doesn’t seem to improve performance much (if at all)
cheers
try adding undo off before you start your i loop to disable the undo buffer for your cone creation and possibly speed things up even more
if it’s just for viewport update, perhaps view and adjust object color instead of the materials. Then if you need to, before rendering apply materials.
I have times : Windows xp sp2. max9. 3.0ghz Dual Pen.
13.8 seconds for the supplied script.
0.64 for just changing the .wirecolor Parameter…
This is with the screen enabled.
If you need to store other data quickly on the objects, I would consider AppData calls, they’re very fast…
0.68 changed .wirecolor and two setAppData calls.
0.86 changed .wirecolor, .visibility and two setAppData calls.
for c in $cone* do
(
c.wirecolor = ( color 20 20 20 )
c.visibility = 0.5
setappdata c 3445 "Data1"
setappdata c 3446 "Data2"
)
It’s definitely a material thing… looping test.
changecones() took 0.719 seconds
changecones() took 0.703 seconds
changecones() took 0.703 seconds
changecones() took 0.719 seconds
changecones() took 0.703 seconds
changecones() took 0.703 seconds
changecones() took 0.75 seconds
changecones() took 0.734 seconds
changecones() took 0.751 seconds
changecones() took 0.735 seconds
changecones() took 0.719 seconds
Hope this helps…
Man I love this community! Thanks so much for the help everyone, and Kramsurfer – thanks for going to the trouble of actually running and improving things yourself!
truly we work in an industry populated with awesome people