Fast(est?) get attr for each frame.

*update. Found another method. still open maya with mdg time is faster. But this is not half bad.

T.L.D.R

the “om_plug_as_double_mdg_set_time” function is the fastest I could find.
be careful with currentTime eval=False and cmds.keyframe. Scroll down for the script.

Explanation:

Soooo I had to export a bunch of data (10k+ maya files) for some dataset.
Which forced me to find a fast way to export attrbutes per frame.
(And it also had to work in mayapy)

And I dint want to have to dive into a c++ plugin or anything.

So I compared a bunch of different ways that i know to getAttr and updating the maya time.

Problems:
1. Dont use cmds.currentTime(frameNr, eval=False) !!
This results in the attribute dg not being evaluated. sooooo its useless.

2. cmds.keyframe(attr, query=True, eval=True)
This only evaluates the active anim layer’s keyframe data.
And changing the active anim layer in mayapy is a nightmare soooo… yeah don’t use it. Also it only works if there are keyframes set. So a channel with a constraint will not return any value.

So for testing i made a simple sphere and 2 additive anim layers with some animation in them.

 

Timings with a sphere:

Shortest duration for each function tested 100 times:

 

Timing with a heavier scene with skinning and constraints.

Timing becomes more clear this way.

Code should mostly speak for itself.
If you have any questions just ask.

 

 

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 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

 

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)

A different way of printing, its the comma that makes it easy.

When I start debugging I usually fill up my entire code with prints to get some info out of it.
Now I used to write something like this

or

However I started to get annoyed by it as I would forget converting ints to str etc.

So I started writing it like this:

This first of all saves a lot of time typing, because of the comma, but also python will not try to combine the data and will just print whatever is provided without adding a new line in between.