You know what happens when you’re looking at complicated stuff? You complicate stuff even more 😀 Thanks to Daniel, Martin and Lukas, they gave me this beautiful insight: windows.processPostedMessages()
Which I am sure is an implementation of what is described below.
So here’s the BEST way to do it in Maxscript 🙂
( clearlistener() delete geometry radius = 10 for x = 1 to 50 do ( for y = 1 to 10 do ( windows.processPostedMessages() obj = Sphere radius:radius pos:[x*radius*2, y*radius*2, 0] wirecolor:gray ) ) arrObj = geometry as array for obj in arrObj do ( windows.processPostedMessages() obj.material = StandardMaterial diffuse:(color (random 0 255) (random 0 255) (random 0 255)) obj.pos.z += random 0 100 redrawViews() ) )
One of the most annoying things when you create a script that needs to do some intensive or time consuming operation is that it usually leaves your 3ds Max UI or your script UI freezing (white window, not responding).
Well today while reading some of the SDK stuff I stumbled upon WindowsMessageFilter, which I’m sure is there for all the C++ gurus, fortunately for us, it’s also exposed to the .NET API which means we can use it in Maxscript too!
What this does is basically processing all the windows messages that are used to paint the windows, controls and so on, thus giving the impression the window is not blocked even when doing some other task. You will probably want to use it inside some loop when doing lots of stuff and you want to keep your UI updated.
The cool thing about this is that by UI, you can say your script rollout or… 3ds Max main window, which basically allows you to check what’s happening in the viewport and even continue to work while some other task is being done in “the background” (not exactly in the background, this is way different from using background threads).
Might not feel like a big thing but we all know that when a user is trying to do something and he simply gets a window freezing, that’s not good.
You can register whatever window handle you want, in the following example I’ve registered the 3ds Max main window, but you can easily use your rollout .hwnd property to register your rollout. You can also register multiple windows.
I’ve created a small example where you can see what is going on while being able to move around your viewport, create new geometry and so on. I hope you like it!
( clearlistener() delete geometry assembly = dotnet.loadAssembly "Autodesk.Max" g = (dotnetClass "Autodesk.Max.GlobalInterface").Instance MaxSDK = g.MaxSDK messageFilter = maxsdk.WindowsMessageFilter.Create() fn checkMessages = ( messageFilter.RunNonBlockingMessageLoop() not messageFilter.Aborted ) hwnd = windows.getMAXHWND() messageFilter.AddUnfilteredWindow (dotnetObject "System.IntPtr" hwnd) radius = 10 for x = 1 to 50 do ( for y = 1 to 10 do ( checkMessages() obj = Sphere radius:radius pos:[x*radius*2, y*radius*2, 0] wirecolor:gray ) ) arrObj = geometry as array for obj in arrObj do ( checkMessages() obj.material = StandardMaterial diffuse:(color (random 0 255) (random 0 255) (random 0 255)) obj.pos.z += random 0 100 redrawViews() ) messageFilter.ClearUnfilteredWindowList() )
Leave a Reply