IronPython in Maya

Hey loocas,

Good to see you here. If your tool appears to be an external process, you can use the SetParent method using Pinvoke. Here is the signature for it.

Light

[QUOTE=loocas;1300]Perfect! It was super simple to implement actually!
[/QUOTE]

Right on! If it’s not too NDA, can you post a version of your script with the changes? I’d like to start compiling stuff like this and putting together a python .net / maya tutorial, i think that’d be a really cool project. Glad i could help!:D:

[QUOTE=Light;1333]Hey loocas,

Good to see you here. If your tool appears to be an external process, you can use the SetParent method using Pinvoke. Here is the signature for it.

Light[/QUOTE]

  • Heya, Light, man! :slight_smile: Howdy? It’s good to see you here as well! :wink:

  • As for the provided link, I have no idea currently how to implement any of the mentioned methods in my forms :frowning: I got as far as identifying maya’s Handles and PIDs, but I couldn’t make any use of that in my Forms creation as they require an Owner, which is yet another Form (type), but how the hell do I specify that this current PID or Hanlde “owns” the Form I’m about to call?!

  • Thanks again, mate! :wink: As for the scripts, no, they’re not under any NDA :smiley: I’m just trying to learn some more advanced concepts of .NET and try to use it when creating more complex, richer, user interfaces. As for the Maya .NET tutorial, count me in! I’d also like to publish some of my findings and experiences. So far, .NET seems to be a little bit of an overkill for what I need (Forms, ListViews, TreeViews, some buttons etc…) :slight_smile: but a solid one.

The script I’m talking about isn’t anything fantastic, but it’s served well. The main purpose is to pass it a path to a folder with point caches (nothing fancy, really) which’ll then take the names of selected shapes and apply a PC2 or MDD deformer (depending on the script instance) to all of them. This was my first script in Maya and Python actually. It used to use a classic Maya’s form with a textbox for pasting in the path string, and a button for assigning the stuff :slight_smile:

So I thought I’d revamp the script a bit to learn something new as well as make it more usable and easier to use for the newcomers :wink: Since there are two flavours of the script (one that creates PC2 deformers and the other for MDD deformers) I created a module with a class defining the whole UI which I ten instantiate in the actual script file and overload some of the class’s properties to facilitate the script’s purpose. It’s simple, but it works.

The threading comes in handy when you need to interact with Maya, as when I tried to run the Form through .ShowDialog() method, which creates a modal form, you can’t access the creator of the Form.

I’ve attached the scripts to this message, note that I’ve used absolute paths to the UI of Maya (is there a way to get the path through MEL functions?) and I’ve put the PCsGUI in Maya’s Python/lib/site-packages/loocas/ folder. You can then place the scripts in your shelves for easier access.

(EDIT: please, re-download the attachment)

As for embedding the Forms in Maya’s thread, the above mentioned method seems not to be the way. I’m not 100% sure if it’s possible to do through Python directly, but I think it’s more logical doing this through .NET itself by assigning the Form a Handle or any other value for that matter, and call the form with the Owner property.

The function that Light has posted, might as well be a solution, but unfortunately for me, I wasn’t able to get it running :frowning:

So, right now, I don’t have any way of making more complex tools that require user interaction while at the same time objects/scene/nodes interaction inside Maya.

I bought a book on PyQt so I’ll probably end up using that, but that’d be a pitty as .NET is readily available on all our Windows machines by default, while Qt would need a massive deployment from my side in the studio, which might be a problem.

A little bit of my findings. Using the threading method from within Python with Maya is highly unstable and more likely to produce errors in context with ShowDialog() method, especially when calling back Maya’s commands, like a simple cmds.ls(sl=True) produces an error saying “sl must be passed a boolean argument”.

When using the Maya.util’s executeInMainThreadWithResult method, this also doesn’t work as expected and returns even more weird error message: “Error reading data element number 1: 1.0”

When I run the Form outside Python’s threading, everything works just fine.

This really makes a lot of trouble for making some nice gui with .NET and Python.

One possible workaround I’ve found (well, it’s not a workaround by definition actually :smiley: ) is to not use threading from within Python, but instead of calling the Form as a modal Form (which has to be done in order to keep it alive in the separate thread), just call it with the Show() method instead.

Or, better yet, with threading, instead of showing the form with regular Show() or ShowDialog() methods, it’s better to use System.Windows.Form.Application.Run(YourForm) .NET’s method. This seems to be working quite well with threading through Python, however, I haven’t tested it thoroughly yet, so, there might be other obstacles, but so far, this seems to be the best way.

Hey loocas,

Yeah it’s easy. Just copy the C# signature into your code:

[DllImport(“user32.dll”)]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

and use the SetParent method by passing your form handle as the first argument, and the main Maya window handle as the second argument.

You can get the handle of your WinForms handle using the Handle property.

For Maya, either use some of the available method in Maya API (I don’t know if there are any for this) or you have to use several Win32 methods to do this.

Cheers,
Light

Thanks, but it seems that I’ll need a little bit more help than that :smiley:

The code doesn’t work “as is” neither in MEL nor in Python, unfortunately, so I’m pretty much stuck where I was before :frowning:

How do I import a DLL assembly actually? In MAXScript this is easy as .NET is integrated, but PythonNet? No idea (I went through the documentation of course).

[QUOTE=Light;1365]Hey loocas,

Yeah it’s easy. Just copy the C# signature into your code:

[DllImport(“user32.dll”)]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

and use the SetParent method by passing your form handle as the first argument, and the main Maya window handle as the second argument.

You can get the handle of your WinForms handle using the Handle property.

For Maya, either use some of the available method in Maya API (I don’t know if there are any for this) or you have to use several Win32 methods to do this.

Cheers,
Light[/QUOTE]

Yeah I haven’t tried that in Python .Net, but top of my head, what you could do is to compile the C# code as a separate assembly (DLL), which you can then import into Python .Net.

OR

Just write the same code in Python .Net. Should be very similar.

Would that work?

Light

Here is some code that I posted a couple of posts back, but the callback code down the bottom is causing Maya to crash, any ideas guys?

import maya.cmds as cmds
import clr
from System.Reflection import Assembly
import sys 

Assembly.LoadFile("C:\\Program Files\\Autodesk\\Maya2008\\bin\\DotNetTest.dll")

global dotNetWindow

dotNetWindow = clr.DotNetTest.Form1()
dotNetWindow.Show()

def myCallback(sender, args):
    print 'Button: ', sender.Text

dotNetWindow.button1.Click += myCallback

Hope that helps.

Hi there, DrBob,

I’ve tried to run your code in Maya, but the Assemly.LoadFile method throws me an error:

Traceback (most recent call last):

File “<maya console>”, line 1, in ?

BadImageFormatException: The module was expected to contain an assembly manifest. (Exception from HRESULT: 0x80131018)

at System.Reflection.Assembly.nLoadFile(String path, Evidence evidence)

at System.Reflection.Assembly.LoadFile(String path)

Any idea why that might be? Cheers,

It may sound silly, but is DotNetTest.dll a .NET dll?

On msdn it says, that this exception is thrown when the file image of an executable program is invalid. For example, this exception is thrown when unmanaged code is passed to Load for loading.

Light

Was it addressed to me, Light? If so, i didn’t try to load that DLL, but instead Windows’ own user32.dll

@ Light. Yeah it’s a .net dll, it will load in maya no probs and I can call functions from python in the dll.
It crashes when I try to add a callback to python “dotNetWindow.button1.Click += myCallback”.

Maybe there is an issue with my pc setup.

~B)

Hey loocas,

Yeah I asked Robert. Sorry if it wasn’t clear.

It’s most probably caused by the .NET dll. Make sure there is nothing in the code that would cause some strange behaviour.

I got the same thing with Max and found out that I was using a rather old win32 call using Pinvoke, which crashed Max as soon as the event was fired.

You got it when the event fires, right? If not, then it might be your constructor or any initializing code you might use.

Cheers,
Light

Hmmm… it seems that the user32.dll isn’t an “assembly” :frowning: which means I have no idea how to load it up in my code and use its functions to obtain the HWND of a running process. MAN! I knew I didn’t want to be a programmer! :smiley:

An assembly is the term used in the managed world for compiled libraries (DLL).

So you should not directly load it but use the proper Pinvoke syntax, which will let you to call unmanaged functions from that dll.

I found this link that seems to show how to do the same.

Come on now, you will be fine (:

Cheers,
Light

Yep, got that working, thanks a lot, man! :wink:

I’ll see what I can do with that :smiley: if anything.

[QUOTE=Light;1412]An assembly is the term used in the managed world for compiled libraries (DLL).

So you should not directly load it but use the proper Pinvoke syntax, which will let you to call unmanaged functions from that dll.

I found this link that seems to show how to do the same.

Come on now, you will be fine (:

Cheers,
Light[/QUOTE]