Finding vertex groups in maya.

So a while ago a friend of mine, Perry Leijten, asked me to help out with seemingly a simple problem for his awesome skinning tools.

*Which you can find here btw: https://gumroad.com/peerke#

The problem being:

“I want to sort my selection of vertices in groups.”

i.e. all neighboring vertices in separate groups.

Simple enough i thought and had a crack at it.

Lots of hair later, 4am, birds chirping and I had a working version… that being immensely slow. After some tinkering and brainstorming we had a version that could do vertex sorting on a 40k vertex mesh in about 1 second.

This got implemented in his skinning tools. Now about 6 months later I revisited the problem and got a speed improvement of about 70%. Sooo I thought it would be nice to make a post about it.

Hopefully the comments in the code speak for themselves.

If not and you have any questions feel free to ask in the comments.

To test it do the following:

1. Create a poly sphere in maya .

2. set it to 200×200 subdivisions

3. run the script

 

Moshi-moshi? Yes C++ speaking … Hi its Python. (ctypes python to c++ )

Because sometimes python is not complex enough ….

Recently I had a task to connect to an existing server to get some data via python so I had two options. Handle all connections myself, communicate with the database in python, cross fingers and hope I would not break anything.

ORRR find a way to call C++ from python and use the existing libraries.

I opted to look into the second solution as it gave me a nice opportunity to research something new. The main thing for me was:

1) Easy to understand. (I am not a hardcore c++ coder)
2) No external dependencies. Just standard python and standard C++.
3) My brain should not explode while trying to get this done !!( Very important and very underestimated requirement)

Seeing as there were only a few beginner resources about this online I thought I’d make a step by step tutorial about it now that I kind of figured it out :). I can’t show how I implemented it with existing code but hopefully the example should make you understand how to do the same.

*side note:
seeing as I’m not a C++ expert I’d like to note that my C++ code might not be perfect but hopefully it will help you understand.

If you want to start learning more on C++ I recommend this resource (most corny website name ever but their basic tutorials on c++ are great):
http://www.gametutorials.com/

Their opening line usually is something like: “Talk to me like I am a 3 year old” which is why I’m finally starting to understand C++ 😛

Tools I used:

Python 2.7.3 x64
Visual Studio 2012 (any other version should do as far as I know)
Python tools for visual studio. (Ptvs)

What we will do:

  1. Create a c++ and pythonproject.
  2. Setup debugging
  3. Add some code that can later be called from python.
  4. Call the c++ dll with the ctypes module in python

 

Stage 1 – setup: (Skip it if you know how to setup a visual studio project for a DLL)
1.1)    Open visual studio.
1.2)    Create a new c++ project. Select Empty Project. (I like starting from a clean project)
1.3)    Give it a name and location and click ok.
createEmptyProject

1.4)    In the Solution Explorer right click on your project and go to “properties”

properties

1.5)    in the Configuration Properties -> General -> Configuration Type set it to “Dynamic Library (.dll)”
1.6)    in the target extension change it to “.dll” instead of “.exe”
*Note that in some tutorials / online resources they refer to this as a .so (shared object / shared library).

settingsDll

Also one thing to recommend.
If you build release and debug the folder locations change. This makes it annoying for python as you have to swap between folder paths.
But you can also just change the build location for the debug and release to be the same folder path.

So change the output directory to:
$(SolutionDir)\dll\

For debug and release.

outputDirDebugoutputDirRelease

1.7)    To be consistent with good coding practices lets make a header and cpp file.

Right click the “Header Files” Folder in the solution Explorer and click
“Add -> new Item”
Select the “header file (.h)” and give it a logical name for example:
RingRingPythonCalling.h
And if you want to be tidy create a proper “headers” folder in your project windows folder. Click ok and now you should have a .h file.

Lets do the same in the Source Files but now for a .cpp file
Please make sure that whatever you called your .h file that you call the .cpp file the same.
This will make it easier to manage our files and code in c++.

HeaderandCpp

1.8)    Creating your python project.

1)    Right mouse button click on your solution and goto
Add -> New Project -> select a Python application.

pythonProject

2)    Give it a name and put it in a logical location.
(preferably in the same folder as your c++ project  )
Mine is:   folderStructure
3)    Now your solution should look something like this.

solutionResult
4)    Now right click the project and click.
Set as StartUp project.

This makes sure that when you press F5 on your keyboard this python file is run. Else it will try to run the C++ file which is not possible as it’s a dll and not an executable 

1.9)    Settings for debugging.

Now in order to be easily able to debug our code in python and c++ at the same time do the following.
1)    Right mouse click on your python project and click properties
2)    Now goto debug and tick”Enable native code debugging”nativeCodeDebug
3)    This now allows the c++ code to be debug able.
4)    Now goto
https://github.com/Microsoft/PTVS/wiki/Symbols-for-Python-mixed-mode-debugging
And download your corresponding pdb files for your python version.
5)    Create a folder called symbols in your python install folder and put the pdb files in there.  pdbFilesFolder

6)    Now goto the menu bar

Tools -> Options
Debugging -> Symbols. .
Click on the folder icon and add the folderpath to the symbols there.
debuggingSymbols

7)    You might also need to click “Load All Symbols” Once for it to work.
8)    Do note that enabling this makes running your python file slower.

So sometimes its recommended to just disable it. Especially once the c++ work is done or you are not making modifications in the c++ file.

Stage 2:

1.0) Creating some example code:
Open your header file by double clicking on it.

Now I wanted to find a use case for this tutorial instead of just doing a hello world.
So the code I have written here would be the basis of doing a c++ matrix or array class but focusing on the communication between c++ and python.

For example. Imagine you are taking skin cluster data from maya and you want to do some special smoothing operations on the skin cluster data.
The data that comes out of maya is usually a list of lists. So per vertex per influence
So on every row you have a vertex. And every column corresponds to every influence.

In python iterating over all these numbers can be quite slow. So if you send the vertex weight information over to c++ and do your math magic there it could be a lot faster.
So keeping this in mind I made this tutorial

In your header file write the following: *note I tried to comment the c++ to the best of my knowledge however I can not guarantee it’s a 100% correct 😀

Now for the cpp file

And last but not least the python file

Now the code should speak for itself and its comments.
As for running it.

Step3: Building the code.

1)    Build the code in Debug or Release

If you press F7 it will build the project into a DLL.
alternatively you can go to Build –> Build solution.
Because a python file doesn’t need to be precompiled visual studio will only compile the DLL.
Scroll down to the Problems and solutions if you run into any problems or errors.

2)    Now press F5.

Seeing as you set the python file to be the startup file it will run the script.
Here are the project files that you can download and test yourself.

PythonCalling

Just running CallingCPP.py if you have python installed should work out of the box. Or you can compile it the dll yourself 🙂

Feel free to post any comments if you run into any problems 

Problems and solutions:

1)    When compiling you get this error:

fatal error C1083: Cannot open include file: ‘RingRingPythonCalling.h’: No such file or directory
a: Check that you wrote the name correctly of the header file.
b: Right mouse button click on your project and go to properties
Goto configuration properties -> c/c++ -> general
At Additional Include directories add the folder where your header file is located.
That should do the trick.

2)    Debugging pops up the “Python Symbols Required” window.

You need to add the python symbols of the correct version.
symRequired

Click download symbols it will take you to this link.
①    https://github.com/Microsoft/PTVS/wiki/Symbols-for-Python-mixed-mode-debugging
②    MAKE SURE YOU GET THE RIGHT VERSION.
③    To find your version do the following:

Run your python executable.
1.    For me that path is “C:\Python27\python.exe”
2.    Then you will see the python window appear with the version in the header. pythonVersion
(note your window will most likely look black)
Now my version is 2.7.3 so make sure you also download the pdb for your corresponding version. Else the “Python Symbols required” dialog will keep popping up.

3)  Python command window pops up and closes instantly.

This sometimes happens with the symbols messing with the python tools for visual studio.
The easiest workaround is to run the script without debugging.
So instead of pressing F5 press Ctrl-F5 untill you fix your bug.

4)  WindowsError: exception: access violation reading 0x000007FE004148D0

There are a million reasons why you could get this error. However the one I ran into the most is:
①    If you get this error the object is most likely being garbage collected by python.
②    So Make sure you store the object in a variable returning from a c++ function. If your c++ function does not need to return anything just give it a int as a return value.
Additionally. I noticed that there is a more severe underlying bug that I could not find the source of.
①    However I did find a solution. (Though very hacky)
②    Just add a Sleep(0.0001) at the end of the function. As seen in the smoothArray function.
③    My guess is python is doing its own memory management after the function is called and moves the objects around. But the function returns to soon so python cant call the function again. This mainly happens in release and not in debug so it’s a nightmare to find.

Threading in maya.

So a while back I wanted to create a background thread that checks the user selection at any given point. Now I know I could have done this with a script job but I wanted more flexibility so started looking into threading.

Now threading in maya is somewhat a nightmare as threads are not safe so if a thread crashes so does maya.

But I think I’ve come up with a “somewhat” stable version of threading. I am kind of cheating the function to run on the main thread. This way most Pymel functions will still work correctly without erroring out.

Now be careful though: It can still be unstable especially when using print statements.

The problem is that if one thread gets delayed and the other one starts that there is a slim chance that two or more threads try to do the same operation in maya at the same time. So for example they will both try to move object.vtx[1] to different positions or print to the script editor at the same time it will result in a crash as maya does not know what to do with the situation.

The class here calls the provided function every 1 second. unless specified otherwise. The timer will never be faster than the function takes. so if the function takes 3 seconds to complete then the interval will be 3 seconds even though you might set it to 0.001

It also supports string and mel functions.

Here is the code:

The evalDeferred is the most important part of this class. Without it there is a very high chance that maya will crash as it will most likely try to do two or more operations at the same time.

To see this in action with a funky little example copy this code into a file named:
threadedFunctions.py
into your scripts directory. i.e. C:\Users\<username>\Documents\maya\<maya version>\scripts

Now in maya create a poly plane of 100 units wide and high. (make sure you leave the name as default i.e.: “pPlane1”)
and give it 10 subdivisions in each direction.

and run this code:

Now if you are lucky maya dint crash and you will see a flag like motion without the timeline advancing.

VERY IMPORTANT NOTE!!!. if you want to stop the thread run the following code.

DO NOT REDEFINE THE “flagThread” variable as that will lose your chance to kill the thread.

I hope this is of some use to someone. I guess you could even make a simple game with this in maya haha :D.

 

 

 

 

MEL Autocompletion for Sublime and MayaSublime

Justin Israel made an awesome extension for the Sublime Text editor called MayaSublime.
https://github.com/justinfx/MayaSublime

But I noticed there is no auto completion file for the MEL syntax so I decided to generate one.

This contains all MEL commands that I can find. Half of these are generated by the help of the Maya help command:
help -list “*”

The rest is generated by parsing all the MEL scripts and taking all “global procs” in the Maya installation scripts folder.

Hope this is of some help to people still having to manage legacy MEL scripts ^^.

I also added the script that I wrote to generate this which might be useful if you are working in a different version of Maya than this file is generated from. (Maya 2014)

Feel free use edit and or modify these files in any way you see fit.

The zip file contains the MEL.sublime-completions and the Python file used to generate this file.

SublimeAutoComplete  < CLICK HERE >

(links dont show up properly yet XD)

Copy the MEL.sublime-completions here:

C:\Users\<userName>\AppData\Roaming\Sublime Text 3\Packages\MayaSublime

If you want to generate this file do the following steps:

1) Copy the SublimeMelAutocompletion.py into your scripts folder.

2) C:\Users\<UserName>\Documents\maya\<Maya Version>\scripts

3) Load up maya.

4) open the script editor

5) type:

Flags:

mayaOnly = This will export only maya commands and scripts that are in the install folder ( C:\Program Files\Autodesk\<mayaVersion>\scripts)

Setting this to False will look in all possible scripts paths defined in the environment variable called: MAYA_SCRIPT_PATH

apiOnly = only generate the commands that are listed in the maya command reference.

filePath = The file path the document will be exported to. i.e. C:\MEL.sublime-completions

If you leave the filePath argument out of it then it will export to the default sublimeText3 mayaSublime folder if it exists:

C:\Users\<userName>\AppData\Roaming\Sublime Text 3\Packages\MayaSublime

It will try to detect your user name automatically.

 

 

Maya’s “pasted_” is history and maya root namespace.

PASTED_

In maya the copy paste feature can be really useful. The major downside however is that every node that gets pasted gets a nice:

PASTED_ prefix attached to it. Resulting in a horribly messy scene that no one ever cares to clean up… until you have to revisit the scene and have to dive into the world of pasted_ nodes trying to find the correct shader etc.

Now there is a really easy fix for it:

In your maya instalation directory there is a file called cutCopyPaste.mel (of course thanks autodesk … )

in that is a function called pasteScene()

replace that function with the following code:

This will merge all the pasted nodes directly into the scene (root namespace ) without adding any prefix or suffix. (Only when the node all ready exists in the same depth it will add a number to the end).

Root Namespace

Whenever I loaded in a referenced scene maya would create a namespace (either with an normal namespace or it would prefix the nodes with the filename and an underscore). However Autodesk has finally been nice enough to open the functionality in the UI to load a scene into the root namespace (making sure the referenced scene does not get any weird naming or namespace. Making it easier to work with)

When going to File > Create reference

The trick is not to disable namespaces on load but enabling them and selecting the : ( root )  namespace and set the following option:

Merge into selected namespace and rename …

Mel and Python do go hand in hand at times.

Seeing as some developers still work with mel and a lot of legacy scripts within companies are still written and maintained in mel its sometimes useful to call python functions in mel when having to extend those old legacy scripts. now most people know you can do a:

inside of mel.

But I recently found a mel wrapper function that does this for you!!! And not only that it also adds the proper from module import function path as well!

So this is actually quite usefull so i thought i’d share it here:

for example. Let say you have the following python script that connects two attributes.

Save this to a file and store it somewhere in the maya scripts paths.

(i.e. my s\Documents\maya\2014-x64 )

Now import the script:

This will run the script and as I added a print it will output the actual code it evaluates:

and now you can go to mel and do:

*note i added the “rehash” to make sure the mel scripts are refreshed.

 

If you want to get more information about this wrapper function run the following lines inside of a python tab in maya:

Or take a look here:

http://download.autodesk.com/global/docs/maya2014/en_us/index.html?url=files/GUID-8A96A8DB-FD6F-434F-A878-288DD84E99C7.htm,topicNumber=d30e727627

 

What an artist doesnt see he cant break! “node.intermediateObject.set(1)”

While working on one of our pipelines I had to find a way to prevent artist touching certain object. But I still needed access to them in code and be able to modify and delete them.

So I tried locking the objects and hiding them from the scene. But the problem was that they still existed in the outliner. So artists would sometimes clean the objects up or move them around.
Heck one of the artists even accidentally figured out how to unlock the objects and delete it. (dont ask me how).

So I needed to come up with a way to prevent this from happening:

 

Now I found out there is one thing that scares an artist more than spiders do to a little girl and that is traversing through the hyper graph. (and showing all non dag objects in the outliner :P)

So if you mark an object as an intermediateObject then it will no longer show up in the outliner nor will it be visible in the scene.
The only way to still see it is by traversing in the hypergraph or knowing where you left it :D. Or doing a in Edit Deformers.

So next time if you dont want an artist to accedentally select, modify, delete an object do a:

*note as soon as you connect the intermediate object the transform will disappear.

 

Printing and clearing output window.

Recently I started to work on some maya startup scripts and wanted to print out some info in Maya’s Output Window.

So I thought a simple

Would do the trick. However it doesnt.

Turns out maya stores the stdout connection of the Output Window in the private __stdout__.

So in order to print to the output window use:

Now after a few lines of testing I wanted to clear out the Output Window which turns out to be quite hacky.

So after some searching I found that someone uploaded a useful script that does exactly this:

http://www.creativecrash.com/maya/script/clear-output-window

It does look very intrusive into the windows file system so I guess using this for linux or mac is out of the question.

 

 

 

Save out vertex colors from Houdini.

Someone asked me how to export vertex colors from Houdini.

So I gave it a quick go to see how rusty my houdini had become and turns out it was horrifically rusty.

Anyway without further ado … here   is the script and otl.

Mind that the otl is made in the learning edition.

 

 

Python reload all. Well … kind of

Do you also hate adding a

while developing a new tool.
If yes then here is the solution:

This removes all initilised modules from the memory. Even the ones that are loaded using the

method.

This means python will have to reload all modules. So put those few lines at the top of your project and you dont have to worry about reloading your modules while you are developing them. 😀

(Yes i know hacky as hell, but then again thats why we are tech artists :D)