Houdini 16.5 Python Scripting

Scripting Houdini from web pages

HTML pages viewed in the embedded browser can use a special JavaScript object to interact with Houdini.

On this page

Note

The method for calling Python from Javascript code changed in Houdini 16 due to Houdini switching to the Qt5 UI library. Scripts written to use the window.Python object will need to be rewritten to initialize the bridge and use the asynchronous callback style for expressions.

Overview

When you view a page in the embedded browser, the JavaScript on that page can use the window.Python JavaScript object to execute Python code and interact with Houdini. This only works in the embedded browser.

This lets you set up HTML interfaces that can read information from and change the Houdini scene.

For example:

// Javascript

if (window.Python) {
    // Run a Python statement that saves the current scene
    Python.runStatements("__import__('hou').hipFile.save()");
}

if (window.Python) {
    // Run a Python expression and get the result as a string
    var nodePath = Python.runStringExpression("__import('hou')__.node('/obj/geo1').path()");
}

Initializing

Before running Python code from JavaScript some initialization is required in the web page.

  1. Load the qwebchannel.js file in your web page, for example:

    <head>
        <script language="javascript" src="/path/to/qwebchannel.js"></script>
    </head>
    

    You can get a copy of qwebchannel.js from $HFS/houdini/python2.7libs/bookish/static/js and install it in your web server.

  2. When the page is loaded, create the web channel communication object in JavaScript:

    window.onload = function() {
        if (!qt || !qt.webChannelTransport) {
            // The web channel transport does not exist so we must not
            // be running in the embedded browser.
            return;
        }
    
        new QWebChannel(qt.webChannelTransport, function(channel) {
            // Assign the Python bridge to the window object 
            // to make it globally available.
            window.Python = channel.objects.Python;
    
            // (Optional) Make Python calls during page load here...
            window.Python.runStatements("print 'Hello World.'");
        });
    }
    

How to

Unlike the Qt4 version, calls to the Javascript bridge in Qt5 are asynchronous: they return immediately instead of waiting until the Python code runs. To get the result of a Python expression, you need to register a callback function.

Run Python statements

if (window.Python) {
    window.Python.runStatements("__import__('hou').setFrame(5)");
}

The Javascript call will return immediately and Python will do the work asynchronously. You can register a callback to do something when the Python finishes:

window.Python.runStatements(
    "__import__('hou').setFrame(5)",
    function() {
        alert("Frame is set!");
    }
);

Run a Python expression that returns a string

To get the result of the expression, you must pass a callback function. The bridge will call the function with the result when the Python code is finished.

if (window.Python) {
    window.Python.runStringExpression(
        "__import__('hou').node('/obj/geo1').path()",
        function(result) {
            alert("Path=" + result);
        }
    )
}

Run a Python expression that returns an integer

if (window.Python) {
    window.Python.runIntExpression(
        "__import__('hou').intFrame()",
        function(result) {
            alert("Integer Frame=" + result);
        }
    )
}

Run a Python expression that returns a floating point number

if (window.Python) {
    window.Python.runFloatExpression(
        "__import__('hou').time()",
        function(result) {
            alert("Time=" + result);
        }
    )
}

Tips and tricks

  • See the Python language definition for the difference between executing statements and evaluating and expression. The main differences are that with statements, you can have more than one statement, they can include control flow (for example, if, for), and they don’t return a value.

  • hou is not automatically available in the executed Python code. You need to import it as part of the code.

  • There is essentially no error handling. If an exception occurs on the Python side, the Javascript functions simply return the empty string or zero (depending on the method).

Running Python code from JavaScript in the old Qt4 browser (deprecated)

This section is for informational purposes only.

  • In a Qt4 build, you don’t need to initialize the Javascript bridge. The Qt4 embedded browser automatically creates the window.Python object.

  • In the Qt4 bridge, calls return synchronously, instead of using callbacks.

window.Python.runStatements(String)null

Executes the given string as one or more Python statements. You can separate statements with newlines or the ; character.

window.Python.runStringExpression(String)String

Evaluates the given string as a Python expression and returns the result as a JavaScript string.

window.Python.runIntExpression(string)Number

Evaluates the given string as a Python expression and returns the result as a whole number (JavaScript has no distinction between ints and floats).

window.Python.runFloatExpression(string)Number

Evaluates the given string as a Python expression and returns the result as a possibly fractional number (JavaScript has no distinction between ints and floats).

Python Scripting

Getting started

Next steps

Guru level

Reference

  • hou

    Module containing all the sub-modules, classes, and functions to access Houdini.

  • Alembic extension functions

    Utility functions for extracting information from Alembic files.