Python + MXS


#261

Hi there!

First of all: Thank you all for this great thread. It helped me VERY much.
I learned how to use a python script in maxscript! yay!
I learned how to send maxscript-commands to 3ds max from python! yay!
(both over COM)

That really helped me out, thx!!!

…but now i’m stuck. :frowning:

I have a python application (a GUI built with wxPython) and like i said, i can send maxscript-commands to 3ds max. so i can create objects or get all selected objects and things like that. Now i want the gui to update itself if for example in 3dsmax the selection has changed (or on any other event). How can i do that?

I tried to execute a pythonscript from maxscript, which gets an instance of my GUI and executes a method that updates the GUI. 3ds max crashed… i think because 3dsmax was still waiting for a return value when the gui tried to update (and therefore connected to 3dsmax) and BAM! Okay, next thing i tried was using thread to update the GUI asynchronously. Well, 3dsmax didnt crash but nothing happend. At least i dont see anything. I think this approach is a dead end. Perhaps the GUI should poll 3dsmax but that’s not a nice solution, either…

So, how can i send an event from maxscript to a python GUI? Has anyone done something similiar? What’s the (best) solution?

Greetings,
Az


#262

Try creating a COM server inside your Python app, and connecting to it from MaxScript (with createOLEObject). There’s some details on making Python COM servers earlier in this thread. Getting bi-directional COM going in one app can be tricky, but it’s definitely doable.


#263

The last few days i learned much about COM but i’m not sure i got it all right. So if i am mistaken, please correct me!
Links for information to COM:
http://oreilly.com/catalog/pythonwin32/chapter/ch12.html
http://www.zanshu.com/ebook/74_python-programming-on-win32/pythonwin32_snode222.html

The COM Server is called ‘server’, but i think it is a bit misleading, because it only publishes an object that can be used by other processes. You can execute the methods of this object, but it is always a new instance. Btw: The default seems to be that this method runs in the thread you called it from (inProc).

If i call python from maxscript, the class i published per COM is intanciated and i have no way to get the instance of my GUI, except communicating with my GUI thread per inter process communication. For example with the pythonmodule asyncore/asynchat see this link or with a library like pyro or twisted. Right?

But this seems a bit complicated. Starting a pyro server, registering a PythonCom server, calling the pythoncomserver in maxscript that then calls the pyro server which then triggers an event in the GUI…
Is this the way to go?

I didn’t find anything about establishing a connection from maxscript directly.

One thing makes me wonder though:
If i send a command to maxscript from python (using the maxscriptcode in the first post of this thread), it is like sending a command to a server. But how does it work? This direction is so easy, why is the direction back to a python GUI so complicated?

I feel like i missed something. Some option that i can set when registering the pythoncom server, so everything works like i want it to. :smiley:

If i get it working, i hope i can post a minimalistic example here to contribute something usefull to this thread.


#264

Hi at all,
I tryed but python gived me error because it doesn’t found max application.
I try to search max.application to regedit but I don’t found nothing…
I don’t know what I wrong…

what could it be?

thx a lot :slight_smile:


#265

See my post above. Max does not register any COM servers for itself by default, you have to tell it to do that. The registerPythonCom.ms script I mentioned will do that for you.


#266

Yes I found it… I did and everything run good!!! thx!!! :slight_smile:


#267

I have run registerPythonCom.ms from GDC2008_AdamPletcher_PythonSamples.zip in 3dsmax 2009 x64 on vista. I get this error:

command_from_python()
 OK
 -- Error occurred in create_reg_key(); filename: D:\3DS Scripts\registerPythonCom.ms; position: 530
 --  Frame:
 --   key_name: "MAX.Application"
 --   key_value_name: ""
 --   key_value_type: #REG_SZ
 --   key_value: "OLE Automation MAX Application"
 --   reg_key: undefined
 --   HKey: HKEY_CLASSES_ROOT
 --   called in anonymous codeblock
 --  Frame:
 --   max_version: "11"
 --   create_reg_key: create_reg_key()
 --   reg_key: undefined
 --   write_sub_key_data: write_sub_key_data()
 -- Type error: HKey requires HKey, got: undefined
 create_python_return_value()
 command_from_python()
 OK

Is there a problem to create reg keys without admin rights???
Where can i find the last scripts from you?


#268

I have run registerPythonCom.ms from GDC2008_AdamPletcher_PythonSamples.zip in 3dsmax 2009 x64 on vista. I get this error:

command_from_python()
 OK
 -- Error occurred in create_reg_key(); filename: D:\3DS Scripts\registerPythonCom.ms; position: 530
 --  Frame:
 --   key_name: "MAX.Application"
 --   key_value_name: ""
 --   key_value_type: #REG_SZ
 --   key_value: "OLE Automation MAX Application"
 --   reg_key: undefined
 --   HKey: HKEY_CLASSES_ROOT
 --   called in anonymous codeblock
 --  Frame:
 --   max_version: "11"
 --   create_reg_key: create_reg_key()
 --   reg_key: undefined
 --   write_sub_key_data: write_sub_key_data()
 -- Type error: HKey requires HKey, got: undefined
 create_python_return_value()
 command_from_python()
 OK

Is there a problem to create reg keys without admin rights???
Where can i find the last scripts from you?


#269

Hey guys,

Just letting you know, I started a new thread to get a little more visibility of it -

http://forums.cgsociety.org/showthread.php?p=6156251#post6156251

But we’ve released our code on a new blur-dev website:

http://blur-dev.googlecode.com

This contains full Python support in 3dsMax, along with a wiki on how to install and run everything. There is no more “python in maxscript” or “python through com” in it - its a direct implementation of python.

Also, for added fun, rollouts and dotNet can be done away with - all of our code supports and is driven by PyQt (http://qt.nokia.com/) which is a very powerful and fast framework.

Enjoy!

Eric Hulser
Tools Developer
Blur Studio


#270

Eric, awesome news, and amazing that you guys share it so freely! thanks.


#271

Hi there,

is there any eta on the publication of the sources ? The reason beeing that this is basically kind of a break even for putting it in our pipeline. As with only binaries Version changes etc could kill a lot of dev time and effort as we can never know when/if recompiles will be there.

On a second note while installing on a different dev machine the problem with the system path variable beeing wiped occured again. I thought it was a different install but it is definately one of the Blur installers. I suspect the QT one as it seemed to hang on “adding to system path” on trying to install again.

Also for deploying it seems kinda bad currently. Can we simply copy over and set the correct env variables to deploy to a lot of machines ?

Kind Regards,
Thorsten


#272

Hi guys,

since I know a lot of you (including me!) would love to have native Python language integrated in 3ds Max, I’d like to share some of our very own stuff we’ve done on this front!

We’ve taken a different approach to Blur’s Python integration, which I have to admit is absolutely fabulous and much more deep and complex than ours, however, Blur’s implementation is very hard to adopt in any production pipeline since it’s completely proprietary, it’s not open source and Blur doesn’t ensure availability for any particular 3ds Max version you might be using.

Our approach, on the other hand, completely leverages on the .NET framework and thus makes our implementation 100% independent on the 3ds Max version or even platform you decide to use! I can run it on Max 9 32bit or Max 2010 64bit at the same time, no need for recompile or anything! Also, when a new IronPython comes out, or if you compile it yourself, just replace the libs and it’ll use that as the scripting engine immediately!

So, here are more technical details as well as a 13 minute features demo video (at the end)!

http://blog.duber.cz/3ds-max/duberpython-features-demonstration

Please, let me know what you think :slight_smile:

I’m considering releasing this library of ours to the public, so, that’s why I’m showing it here.


#273

Hey there,

nice effort! Just wanted to point out that blur did a new version of their integration that seems a lot better then the initial approach, allows for QT and is indeed open source.

http://forums.cgsociety.org/showthread.php?f=98&t=816475

Here’s the thread and you can get the sources at google code
http://blur-dev.googlecode.com/

Might be helpful in your ironpython approach too i guess

Regards,
Thorsten


#274

Thanks, I know about the new Blur approach, however, it’s irrelevant to ours since Blur leverages on the CPython code, but we’re using IronPython, written in C#, leveraging on dotNET. These are two entirely different worlds leading to one place - Python :slight_smile:

As I said, Blur has done an amazing job and their version is much more complex, however, their version still need recompilation each time you install a new version of Max etc… ours doesn’t.

Also, we chose to develop on .NET and its GUI libraries (including WPF) since we don’t need to use other tools that aren’t bound to Microsoft platform. We strictly use Max for all our 3D vfx work, so leveraging on .NET was the best way to go, for us.

As for other tools we use, like Nuke, we run our code written in IronPython, but we load different modules so that the GUI can be written in Qt, but the raw scripting can be done platform independent and thus works in both 3ds Max and Nuke.


#275

Ah, got it. One reason i really dig Py3dsmax + PyQT over .net in native maxscript is that i still find dotNet incredibly slow. Even if it only is on first open per session i find it untolerable and it makes me go nuts even with the builtin dotNet tools. How’s you’re experience with the IronPython approach ? Is it the same or better ?

Regards,
Thorsten


#276

Well, there is a lag at first run, about 2-4s, but then it’s instant, since we then keep IronPython in the memory, so anything else run through our IronPython bridge is instant.

As for GUI. Well, since it’s all based on .NET, the raw Python GUI code is quite fast and I don’t have problems with it. But, you can gain some speed by compiling the GUI into a DLL which you can then reference in your script, which makes it even faster for some super complex GUIs, which is cool. But I’m perfectly happy with the raw Python, scripted, GUI.


#277

Hello,

Anyone got luck making the COM Server works on Windows 7 ?

I registered it with the registerPythonCom.ms, I checked my registry, it seems to me the keys are there and correct, when I try this in a python interpreter :

>>> import win32com.client
>>> mx = win32com.client.Dispatch('Max.Application')

I have that sad message :

Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    mx = win32com.client.Dispatch('Max.Application')
  File "D:\Softwares\Developement\Python26\lib\site-packages\win32com\client\__init__.py", line 95, in Dispatch
    dispatch, userName = dynamic._GetGoodDispatchAndUserName(dispatch,userName,clsctx)
  File "D:\Softwares\Developement\Python26\lib\site-packages\win32com\client\dynamic.py", line 104, in _GetGoodDispatchAndUserName
    return (_GetGoodDispatch(IDispatch, clsctx), userName)
  File "D:\Softwares\Developement\Python26\lib\site-packages\win32com\client\dynamic.py", line 84, in _GetGoodDispatch
    IDispatch = pythoncom.CoCreateInstance(IDispatch, None, clsctx, pythoncom.IID_IDispatch)
com_error: (-2147221164, 'Class not registered', None, None)

Funny thing is that I restarted the python interpreter an reran the same code, without any errors … but now when I try registering a method like this :

>>> mx._FlagAsMethod('ExecuteSIBLLoaderScript')

I get a nasty :

Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    mx._FlagAsMethod('ExecuteSIBLLoaderScript')
  File "D:\Softwares\Developement\Python26\lib\site-packages\win32com\client\dynamic.py", line 427, in _FlagAsMethod
    details = build.MapEntry(self.__AttrToID__(name), (name,))
  File "D:\Softwares\Developement\Python26\lib\site-packages\win32com\client\dynamic.py", line 432, in __AttrToID__
    return self._oleobj_.GetIDsOfNames(0,attr)
com_error: (-2147352570, 'Unknown name.', None, None)

which make sense since there is no reason it would have failed earlier and not now, though I don’t understand the Dispatch method didn’t made errors this time oO

:banghead:


#278

It’s so Good


#279

[QUOTE=loocas][/QUOTE]

I’m a big .net fan so i’m really keen on this approach. Have you thought more about if you’ll release it? :slight_smile:


#280

Was this question aimed at me?

If so, I still haven’t decided on a public release yet. We’ve just ironed out a few tiny kinks in the plugin, so, it seems we’re good on this part, however, I still want to test drive the plugin before a public release.

Currently I’ve been working with an outside studio for the first time to use our Pythoner plugin for their production management system with Python API. So far I’ve ported all the native Python methods over to 3ds Max for direct Max <-> Server Python communication, so, this also seems good.

I’ll let everyone know via this thread once our plugin is ready for the public.

If the question wasn’t aimed at me, then, please, happily ignore this reply. :smiley: