Execute code in Maya from VSCode

When I started programming in Maya I was using the default code editor and let me tell you it’s very barebones. Useful when you know what you’re doing but not very user-friendly. After a while, I got introduced to Charcoal Editor 2 that had way more features, code completion, quick help access to documentation, etc. It does its work extremely well but still had its limitations. The most bothersome one was that on the free version you can only have 2 tabs open at the same time. 

So I set up on a quest to try to get VSCode to work with Maya. At first, there were two main plugins that kinda worked but they were very buggy and sometimes required the restart of Maya or VSCode to start working again. These plugins connected to Maya through the use of a Mel command that created a port and received code to be run. So after a looong and a deep rabbit hole, I got something working.

#######################################################################
# Sends the file to maya to be executed, also adds the whole folder into
# the environment before executing and removes it after
#
# Requires this mel command to be run in maya first in a userSetup.mel file
# commandPort -n "localhost:7001" -stp "python";
#
#######################################################################
import os
import sys
import socket

HOST = 'localhost'  # the local host
PORT = 7001         # The same port as used by the server

file = sys.argv[1]

folder_dir = os.path.abspath(os.path.dirname(file))
script_dir = sys.argv[1]

# Code to send test script to maya
code = (
    "print(r'# Running {} #')\n".format(file)
    + "import sys\n"
    + "current_directory = r'{}'\n".format(folder_dir)
    + "file = r'{}'\n".format(script_dir)
    + "if current_directory not in sys.path:\n"
    + "\tsys.path.insert(0,current_directory)\n"
    + "try:\n"
    + "\texec(open(file).read(), globals())\n"
    + "\tprint('# Successfully Ended #')\n"
    + "except:\n"
    + "\tprint('# Error while running #')\n"
    + "\tprint(sys.exc_info()[1])\n"
    + "del(sys.path[0])\n"
)

# Create a socket and connect
# TODO: Check if connection failed
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((HOST, PORT))

# Send the command to maya
client.sendall(code.encode())

# Receive erros
# TODO: This should be in a while just in case msg is longer than 4096
# '\n\x00' is the message terminator

data = client.recv(4096)
print("\nError: %s" % data.decode())

client.close()

For this to work there’s a bit of setup required.

First add the line:

commandPort -n "localhost:7001" -stp "python";

to the userSetup.mel file in the users Maya scripts folder. (usually user/Documents/maya/20xx/scripts/)

Second, in VSCode we need to setup a workspace folder so we can create a task. To setup a workspace is as easy as just telling VSCode tp open the folder which contains the python files we want to work on.

More on VSCode Workspaces here.

Last, a task can be created to send the currently open file to maya. Pressing Ctrl+Shift+B, then selecting

and then copying the following lines, make sure to change the path to the location of the above script!

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "Send to Maya",
            "type": "shell",
            "command": "python ///path to above script.py/// ${file}",
            "problemMatcher": [],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ]
}

After that you should be able to press Ctrl+Shift+B again and with Maya open it will send the contents of your opened script to the Maya terminal

Some things to note is that when there’s an error in execution, it will be displayed on the Maya terminal

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s