I don’t like 3ds Max, but some times in life you have to work with things you don’t like.
I have recently found a need to send commands to Max from a standalone python app I’m writing. After a few differently worded Google searches it became apparent that Max does not have this, and not only that, there isn’t any real solution. I did find one $5 solution that didn’t promise the source code, something I needed for my project. So I set out to write my own script to open up a command port in Max. This project met my needs at the time, it hasn’t been tested outside of those constraints so it may not work at all for you.
Here’s my little script with all the functions you need to get started.
The listener() function uses the built-in socket library to open a port and listens for data to come through it. You can read more about sockets from this great little thread here (I don’t like puns so its not intended). If you run this function as is it will hang Max (or any application really) until it gets “exit“ as command.
def listener(): max_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) max_socket.bind((HOST, COMMAND_PORT)) command = None while command != "exit": max_socket.listen(5) connection_obj, sender = max_socket.accept() data = connection_obj.recv(1024) if data: command = str(data.decode()) print("Command: ", data.decode()) if command == "exit": break try: # Try to evaluate the command. MaxPlus.Core.EvalMAXScript("%s" % command) except Exception as e: print(e) max_socket.close()
So preferably we want to be able to use Max while the port is open. Use this little function to thread the listener and avoid the application freezing while listening.
def open_max_command_port(): listen_thread = threading.Thread(target=listener) listen_thread.start()
You should note, as far as I know, Python in Max is not a totally thread safe so this project can’t do everything, its more of a proof of concept that I whipped up in an afternoon.
To test this for yourself you just need to write a little Max startup script to load my whole script into memory and run the open_max_command_port() function.