Cython and Maya

172 views
Skip to first unread message

Gabriel

unread,
Aug 2, 2019, 2:45:50 PM8/2/19
to Python Programming for Autodesk Maya
Hey guys, how are you doing?

I'm trying compile some scripts with Cython and Maya and I've some doubts. How can I declare the OpenMaya types on cpdef?

My setup script is this:

from setuptools import setup, Extension
from Cython.Build import cythonize
import os


def _script_path(module_name):
    return os.path.join(os.path.dirname(__file__), "src", module_name).replace("//", "/")


setup(
    name="vzUtils",
    ext_modules=cythonize(
        Extension("vzUtils",
                  language="c++",
                  sources=[_script_path("vzUtils.pyx")],
                  include_dirs=[
                      "C:/Program Files/Autodesk/Maya2019/Python/Lib/site-packages",
                      "C:/Program Files/Autodesk/Maya2019/include",
                      os.path.join(os.path.dirname(__file__), "src").replace("//", "/")
                  ],
                  libraries=[
                      "Foundation",
                      "OpenMaya",
                      "OpenMayaUI",
                      "OpenMayaAnim",
                      "OpenMayaFX",
                      "OpenMayaRender",
                      "Image"
                  ],
                  library_dirs=[
                      "C:/Program Files/Autodesk/Maya2019/lib",
                      "C:/Program Files/Autodesk/Maya2019/Python/DLLs"
                  ])
    )
)


And my script test is this:

# distiutils: Language=c++

from maya import OpenMaya


cpdef list_nodes_connections(node, list node_list):
    if node.isNull():
        return

    node_plugs = OpenMaya.MPlugArray()
    fn = OpenMaya.MFnDependencyNode(node)

    if fn.typeName() in ["mesh", "polyCurve"]:
        return

    fn.getConnections(node_plugs)
    cdef int i = 0
    cdef int k = 0
    for i in range(node_plugs.length()):
        plugs_connected = OpenMaya.MPlugArray()
        node_plugs[i].connectedTo(plugs_connected, True, False)
        for k in range(plugs_connected.length()):
            list_nodes_connections(plugs_connected[k].node(), node_list)

    if fn.name() not in node_list:
        node_list.append(fn.name())

I compile this script successfully but the Maya doesn't import them. Maya said is not possible to import the DLL...

I tried to declare the Maya's type and resulted in a compilation error. Cython said that MObject is unknown type:

cpdef list_nodes_connections(MObject nodes, list node_list):

Have you any idea to fix these errors? How the best practice to use Cython and Maya? Must I recompile for each Maya's version linking like C++ plug-ins?

Regards,
Gabriel Valderramos

Justin Israel

unread,
Aug 2, 2019, 5:16:52 PM8/2/19
to python_in...@googlegroups.com
I can comment on the Cython stuff since I have plenty of projects using it, but not so much on Windows compiling. But you would need to compile it for each major (and sometimes major.minor) release of Maya. 

You have a bit of a mixed situation here with the concepts of what Cython can do, what you expect, and what you are actually doing. Yes you could be using the Maya C++ types like MObject, but you are currently doing everything through the python bindings. This means you are not gaining much at all from Cython besides statically typing your loop variables. All the calls and list access is still python. Try this: Use the cython command line tool to run your pyx file through the "annotate" flag. It will produce an HTML file of your source that is highlighted with yellow. The darker the yellow, the more python your code is doing. You want as much white as possible to indicate C usage. I'm guessing most of your code will be yellow besides the lines that declare the int variables. This also means that currently you don't need to be linking against Maya's C++ libraries since you aren't even using any of its headers and symbols. 

So, in order to get much benefit out of this whole process, you would need to drop the use of the Maya Python imports for the critical performance sections of your code and declare the parts of the C++ api that you need to access. I'm answering via mobile so I cant offer examples. But you need to create a pxd file which includes the correct Maya headers and declares cppclass items and the methods and fields that you need to expose to Cython. This example should help:

You could try statically typing more of your variables before they get used in the loop, and see how far that gets you when you keep checking the annotated HTML. But I don't know if it will be a huge gain to make it worth it, without really using C++ types. 



Regards,
Gabriel Valderramos

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/dc8e094c-b78a-4077-b7e1-1d9af18f5ae7%40googlegroups.com.

Justin Israel

unread,
Aug 2, 2019, 6:20:47 PM8/2/19
to python_in...@googlegroups.com
Slight correction. Recompiling for different Maya versions depends on whether they have changed compiler versions, Python major.minor version, and whether you end up really linking against Maya's C++ libraries. 
Reply all
Reply to author
Forward
0 new messages