Python Programming Guide

../_images/FE_logo_345_60.png
Fabric Engine version 2.5.0
Copyright (c) 2010-2017 Fabric Software Inc. All rights reserved.

Introduction

Fabric has offered Python bindings for the Core C++ API for some time but new to version 2.2.0 is a PySide-compatible wrapping of the FabricUI user-interface library, allowing users to build complete standalone Fabric-based tools in Python. There is also a higher-level Canvas Python module which wraps much of the FabricUI functionality and makes it accessible in a way that’s easier for building custom Python applications.

The Canvas standalone has been rebuilt in Python using the Canvas module and provides a good example of how another standalone application may be built using Python. The Canvas standalone can be found in FABRIC_DIR/bin/canvas.py.

Additionally, a sample Alembic Viewer application is also shipped with each release and is located FABRIC_DIR/Samples/Python/AlembicViewer/alembic_viewer.py. A short tutorial has been written outlining the steps taken to create the Alembic Viewer sample application. See the Alembic Viewer Tutorial for more information.

The Canvas module and the FabricUI Python bindings are still a work in progress. Over the next few releases we will be working on cleaning up and stabilizing the API as well as providing more detailed documentation. In the meantime we welcome users to begin experimenting with it to build applications, though the API may be changing from release to release as we make improvements to both functionality and ease of use.

Currently we are only providing the bindings for Python 2.7 with Qt 4.8.x and PySide 1.2.4. Users can however visit the FabricUI repository to check out and build the bindings against any version of Python or Qt that’s required. In a future release we will also add FabricUI Python support for supported DCCs.

Canvas Module

Here you can find documentation on the main Canvas module classes and their most relevant methods. Not all classes are documented here and you may still want to look at the Python code itself which can be found under FABRIC_DIR/Python/2.7/FabricEngine/Canvas, however this should give you enough of a starting point to begin building your own Python applications.

CanvasWindow

This module adds the CanvasWindow which encompasses most of the UI required to build a Python application. Users building their own custom apps may want to subclass the CanvasWindow and simply override relevant methods to change behavior as needed.

class FabricEngine.Canvas.CanvasWindow.CanvasWindow(settings, unguarded, noopt)

This window encompasses the entire Canvas application.

defaultFrameIn

int – Default in frame.

defaultFrameOut

int – Default out frame.

autosaveIntervalSecs

int – Interval at which to autosave the current graph.

Parameters:
  • settings (QtCore.QSettings) – Settings object that is used to store and retrieve settings for the application.
  • unguarded (bool) – Whether to create the Fabric client in unguarded mode.
  • noopt (bool) – Whether to create the Fabric client in unoptimized mode.
_init()

Initializes the settings and config for the application.

The autosave directory and file name are established here.

_initDFG()

Initializes the Data Flow Graph.

An evalContext is created to provide contextual information about the evaluation to operators and other objects and systems with Fabric Engine.

A binding to a graph is initialized and is setup so the application can interact with it via the DFGWidget and through other scripted methods within the application.

The UICmdHandler handles the interaction between the UI and the client.

The DFGWidget is the UI that reflects the binding to the graph that is created and changed through the application.

_initDocks()

Initializes all of dock widgets for the application.

The dock widgets host the main widgets for the application and are able to be toggled on and off via the menu items that are created. Some widgets that are hosted in dock widgets are instanced here and some have already been created such as the DFGWidget and TimeLineWidget.

_initGL()

Initializes the Open GL viewport widget.

_initKL(unguarded, noopt)

Initializes the Fabric client.

The core client is what drives the application and what the user interface interacts with to create data types and process the data. The client is required in all Fabric based applications.

Parameters:
  • unguarded (bool) – Sets the client to run in guarded mode or not.
  • noopt (bool) – Set the client to skip KL code optimization
_initLog()

Initializes the DFGLogWidget and Undo view.

_initMenus()

Initializes all menus for the application.

_initTimeLine()

Initializes the TimeLineWidget.

The timeline widget is setup with the class variables for the default in and out frames.

The frameChanged signal is connected to the onFrameChanged method along with the Value Editor’s onFrameChanged method too.

_initTreeView()

Initializes the preset TreeView.

Also connects the DFG Controller’s dirty signal to the onDirty method.

_initValueEditor()

Initializes the value editor.

_initWindow()

Initializes the window attributes, window widgets, actions, and the fps timer.

_reportCallback(source, level, line)

Callback method that fires when the client sends output.

Report sources:
Core.ReportSource.System Core.ReportSource.User
Report levels:
Core.ReportLevel.Error Core.ReportLevel.Warning Core.ReportLevel.Info Core.ReportLevel.Debug
Parameters:
  • source (int) – Source of the report call.
  • level (int) – Level of the report.
  • line (int) – Text of the output.
_statusCallback(target, data)

Status callback used for KL code to communicate status messages back to the client.

Parameters:
  • target (str) – Target of the callback.
  • data – Data to be sent to the target.
autosave()

Saves the scene when the auto-save timer triggers.

checkUnsavedChanges()

Checks for any unsaved changes in the graph.

If there are changes that haven’t been saved the user is prompted with a dialog asking them if the graph should be saved.

closeEvent(event)

Standard close event method called when the Window is closed.

Settings for the application are stored and the window widget is closed. The super class’s closeEvent is then fired and the Fabric client is closed.

Parameters:event (QtCore.QEvent) – Event that has been triggered.
enableShortCutsAndUndoRedo(enabled)

Enables or disables shortcuts.

enabled (bool): Whether or not to enable the shortcuts.

execNewGraph(skip_save=False)

Callback Executed when a key or menu command has requested a new graph.

This simply executes the corresponding script command.

Parameters:skip_save (bool) – Whether to skip the check for unsaved changes.
loadGraph(filePath)

Method to load a graph from disk.

Files are typically *.canvas files.

Parameters:filePath (str) – Path to the graph to load.
onAdditionalMenuActionsRequested(name, menu, prefix)

Callback for when a request to add additional menu actions is called.

Parameters:
  • name (str) – Name of the menu.
  • menu (QMenu) – Menu item to add to.
  • prefix (str) – Whether to add the prefixed menu items or not.
onDirty()

Method called when the graph is dirtied.

onFileNameChanged(fileName)

Callback for when the file name has changed.

This method updates the window title to reflect the new file path.

onFrameChanged(frame)

Method called when the user has changed frames.

The frame change call pushes the new frame into the binding ports which map to the timeline.

Parameters:frame (float) – The new frame the user has changed to.
onGraphSet(graph)

Callback when the graph is set.

Parameters:graph – The graph that is being set as current.
onImportGraphAsNode()

Callback for when users wish to import a graph as a node from the UI.

A file dialog is opened and users can select the file to import. The last directory the user saved or opened a graph from is used.

onLoadGraph()

Callback for when users wish to load a graph from the UI.

A file dialog is opened and users can select the file to load. The last directory the user saved or opened a graph from is used.

onNewGraph(skip_save=False)

Callback Executed when a call to create a new graph has been made.

This method deallocates the previous binding and creates a new one. It also resets the undo stack, clears inline drawing, and sets the timeline.

Parameters:skip_save (bool) – Whether to skip the check for unsaved changes.
onNodeEditRequested(node)

Method that is called when a request to edit the specified node has been emitted.

onPortManipulationRequested(portName)

Method to trigger value changes that are requested by manipulators in the viewport.

Parameters:portName (str) – Name of the port that is being driven.
onSaveGraph()

Method called when the graph is saved.

onSaveGraphAs()

Method called when the graph is to be saved under a different file name.

onUrlDropped(url, bypassUnsavedChanges, importAsNode, pos)

Callback when an item (.canvas file) is dropped on the graphview.

Parameters:
  • url – The path of the graph to load or import.
  • bypassUnsavedChanges – It the graph is loaded (importAsNode == False), check if the graph needs to be saved
  • importAsNode – If true, import the file as a node, load it as the current graph otherwise.
  • pos – The drop position.
performSave(binding, filePath)

Writes the current graph to disk.

Parameters:
  • binding – The graph binding to save to disk.
  • filePath (str) – The file path to which the binding is saved.
saveGraph(saveAs)

Wraps the performSave method.

Opens a dialog for user to save the file if the lastFileName attribute is not set or if the saveas argument is True. Otherwise it overwrites the file which was opened.

Parameters:saveAs (bool) – Whether to save the graph to a different file path.
setBlockCompilations(blockCompilations)

Sets the graph to block compilations.

Parameters:blockCompilations (bool) – Whether to block compilations or not.
updateFPS()

Method for updating the FPS label in the status bar.

ScriptEditor

The ScriptEditor is where Python code may be written and executed in the context of the current Canvas scene. All Canvas commands that are executed through the UI (e.g. creating a node, moving one, editing a port, etc.) will also show up in the ScriptEditor as Python code so that users can see exactly what Canvas is doing, and to assist in reproducing issues that were initially triggered through the UI.

UICmdHandler

The UICmdHandler is responsible for executing DFG commands sent from other parts of the UI (for example from the Canvas DFGWidget).

Each Canvas integration has its own UICmdHandler (for example Maya, or Softimage) and this is the implementation for Python. The UICmdHandler turns each command into a pure Python command and then sends it to the ScriptEditor for execution. This allows logging all commands run by the Canvas standalone as simple Python commands which can later be used to recreate behaviors that were originally generated using the UI.

class FabricEngine.Canvas.UICmdHandler.UICmdHandler(client, scriptEditor)
dfgDoAddBackDrop(binding, execPath, exec_, title, pos)
dfgDoAddBlock(binding, execPath, exec_, desiredName, pos)
dfgDoAddBlockPort(binding, execPath, exec_, blockName, desiredPortName, portType, typeSpec, pathToConnect, connectType, extDep, metaData)
dfgDoAddFunc(binding, execPath, exec_, title, initialCode, pos)
dfgDoAddGet(binding, execPath, exec_, desiredNodeName, varPath, pos)
dfgDoAddGraph(binding, execPath, exec_, title, pos)
dfgDoAddInstBlockPort(binding, execPath, exec_, instName, blockName, desiredPortName, typeSpec, pathToConnect, extDep, metaData)
dfgDoAddInstPort(binding, execPath, exec_, instName, desiredPortName, portType, typeSpec, pathToConnect, connectType, extDep, metaData)
dfgDoAddPort(binding, execPath, exec_, desiredPortName, portType, typeSpec, portToConnect, extDep, metaData)
dfgDoAddSet(binding, execPath, exec_, desiredNodeName, varPath, pos)
dfgDoAddVar(binding, execPath, exec_, desiredNodeName, dataType, extDep, pos)
dfgDoConnect(binding, execPath, exec_, srcPorts, dstPorts)
dfgDoCreatePreset(binding, execPath, exec_, nodeName, presetDirPath, presetName, updateOrigPreset)
dfgDoDisconnect(binding, execPath, exec_, srcPorts, dstPorts)
dfgDoDismissLoadDiags(binding, indices)
dfgDoEditNode(binding, execPath, exec_, oldNodeName, desiredNewNodeName, nodeMetadata, execMetadata)
dfgDoEditPort(binding, execPath, exec_, oldPortName, desiredNewPortName, portType, typeSpec, extDep, metaData)
dfgDoExplodeNode(binding, execPath, exec_, nodeName)
dfgDoImplodeNodes(binding, execPath, exec_, nodeNames, desiredNodeName)
dfgDoImportNodeFromJSON(binding, execPath, exec_, nodeName, graphPath, pos)
dfgDoInstPreset(binding, execPath, exec_, presetPath, pos)
dfgDoMoveNodes(binding, execPath, exec_, nodeNames, newTopLeftPoss)
dfgDoPaste(binding, execPath, exec_, json, cursorPos)
dfgDoRemoveNodes(binding, execPath, exec_, nodeNames)
dfgDoRemovePort(binding, execPath, exec_, portNames)
dfgDoRenamePort(binding, execPath, exec_, portPath, desiredNewPortName)
dfgDoReorderPorts(binding, execPath, exec_, itemPath, indices)
dfgDoResizeBackDrop(binding, execPath, exec_, backDropNodeName, newTopLeftPos, newSize)
dfgDoSetArgValue(binding, argName, value)
dfgDoSetCode(binding, execPath, exec_, code)
dfgDoSetExtDeps(binding, execPath, exec_, extDeps)
dfgDoSetNodeComment(binding, execPath, exec_, nodeName, comment)
dfgDoSetPortDefaultValue(binding, execPath, exec_, portPath, value)
dfgDoSetRefVarPath(binding, execPath, exec_, refName, varPath)
dfgDoSplitFromPreset(binding, execPath, exec_)
static encodeBool(x)
static encodeFloat(x)
static encodeInt(x)
static encodeInts(xs)
encodePortType(portType)
static encodePosXs(poss)
static encodePosYs(poss)
static encodeString(string)
static encodeStringChars(string)
static encodeStrings(strings)
evalCmdWithArgs(cmd, encodedArgs)

BindingWrapper

The BindingWrapper wraps a Core DFGBinding in order to provide a simple API for the DFG UI commands. Commands sent from the UICmdHandler are executed in the ScriptEditor and the ScriptEditor uses the BindingWrapper to actually invoke each command.

There is a 1-to-1 mapping of the methods provided by the UICmdHandler (which receives commands from the UI) and the BindingWrapper (which invokes the commands in the Fabric Core). The BindingWrapper also takes care of adding all commands to a QUndoStack so that undo/redo functionality is properly maintained.

class FabricEngine.Canvas.BindingWrapper.BindingWrapper(client, binding, qUndoStack)
addBackDrop(execPath, title, posX, posY)
addBlock(execPath, desiredName, posX, posY)
addBlockPort(execPath, blockName, desiredPortName, portType, typeSpec, pathToConnect, connectType, extDep, metaData)
addFunc(execPath, title, initialCode, posX, posY)
addGet(execPath, desiredNodeName, varPath, posX, posY)
addGraph(execPath, title, posX, posY)
addInstBlockPort(execPath, instName, blockName, desiredPortName, typeSpec, pathToConnect, extDep, metaData)
addInstPort(execPath, instName, desiredPortName, portType, typeSpec, pathToConnect, connectType, extDep, metaData)
addPort(execPath, desiredPortName, portType, typeSpec, pathToConnect, extDep, metaData)
addSet(execPath, desiredNodeName, varPath, posX, posY)
addVar(execPath, desiredNodeName, dataType, extDep, posX, posY)
connect(execPath, packedSrcPorts, packedDstPorts)
createPreset(execPath, nodeName, presetDirPath, presetName, updateOrigPreset)
decodePortType(portType)
disconnect(execPath, packedSrcPorts, packedDstPorts)
dismissLoadDiags(packedIndices)
editNode(execPath, oldNodeName, desiredNewNodeName, nodeMetadata, execMetadata)
editPort(execPath, oldPortName, desiredNewPortName, portType, typeSpec, extDep, metaData)
explodeNode(execPath, nodeName)
implodeNodes(execPath, packedNodeNames, desiredNodeName)
importNodeFromJSON(execPath, nodeName, filePath, posX, posY)
instPreset(execPath, presetPath, posX, posY)
moveNodes(execPath, packedNodeNames, packedNewTopLeftPosXs, packedNewTopLeftPosYs)
paste(execPath, json, cursorPosX, cursorPosY)
redo()
removeNodes(execPath, packedNodeNames)
removePort(execPath, packedPortNames)
renamePort(execPath, portPath, desiredNewPortName)
reorderPorts(execPath, itemPath, packedIndices)
resizeBackDrop(execPath, backDropNodeName, newTopLeftPosX, newTopLeftPosY, newSizeW, newSizeH)
setArgValue(argName, typeName, valueJSON)
setCode(execPath, code)
setExtDeps(execPath, packedExtDeps)
setNodeComment(execPath, nodeName, comment)
setPortDefaultValue(execPath, portPath, typeName, valueJSON)
setRefVarPath(execPath, refName, varPath)
splitFromPreset(execPath, nodeName)
static splitInts(packedIndices)
static splitNames(names)
static splitPoss(posXs, posYs)
undo()
FabricEngine.Canvas.BindingWrapper.InvokeCmd(cmd, qUndoStack)
class FabricEngine.Canvas.BindingWrapper.UndoCmd(cmd)
redo()
undo()

LogWidget

The LogWidget receives and saves logging output from the ScriptEditor.

RTValEncoderDecoder

The RTValEncoderDecoder is responsible for encoding and decoding RTVals to and from strings. This is used by the ScriptEditor to allow sending plain Python commands to the Core that include the contents of RTVals and is also used by the Fabric Core for persistence to allow saving the contents of a scene to JSON.

FabricParser

The FabricParser handles parsing command line options for the Canvas standalone.

FabricEngine.Canvas.FabricParser.CheckExtension(choices)

Argparse action to check a file extension at loading.

Parameters:choices (Dictionary) – List of allowed extensions {‘ext1, ext2, ...’}.
class FabricEngine.Canvas.FabricParser.FabricParser(prog=None, usage=None, description=None, epilog=None, version=None, parents=[], formatter_class=<class 'argparse.HelpFormatter'>, prefix_chars='-', fromfile_prefix_chars=None, argument_default=None, conflict_handler='error', add_help=True)

Specialize the argparse.ArgumentParser class. If an error occurs when parsing the arguments, the available options will be diplayed before exiting.