Share

Golaem Layout Python API

Golaem Layout is shipped with a Python API module. It is strongly advised to use the API provided by this file to handle Simulation Cache Layout File (.gscl)

Preparing your Environment Variables

The layout API will be reachable if the PYTHONPATH environment variable contains the [Golaem installation directory]/scripts folder

In addition, the PATH environment library must include the [Golaem installation directory]/bin folder : the layout python API requires the glmCrowdIO library to handle licenses

Including Golaem Layout API file in a project

The API needs an app running to be able to manipulate graphs in background, you can insure that by doing:

# Insure that we have an app before calling layout

from glm.Qtpy.Qt import QtWidgets

try:

   app = QtWidgets.QApplication([]) except:

   app = None

Then the Golaem Layout API can be added to a project, by importing the following module:

from glm.layout.layout import *

Finally, a call need to be issued to inform that we are using the layout as a standalone API, before issuing any other layout API call. The call requires the path to the golaem_demo.lic containing directory. This file is used to create a PLE Licenses, thus the licDir path can be ignored if the user is sure to have a valid Lite license, either from Maya Layout or Unreal.

initGolaemStandaloneProduct('C:/Golaem-7.0.3-Maya2018/plug-ins/')

and the following when all layout API calls have been issued

finishGolaemStandaloneProduct()

Using the API to load, modify and save layout files

Load an existing Layout File

It is done by loading a layoutFileHandle from a .gscl file :

layoutFileHandle = openLayoutFile(filePath)

The command takes a string filePath, and returns None on error, or a layoutFileHandle used to modify and save it.

Accessing/Modifying Layout

The cache data can be accessed and modified the following way:

Layout Nodes

listNodeIds(fileHandle) # returns the IDs of all the nodes of a Layout File

Layout Parameters

Layout parameters are parameters generic to the whole file, such as the next available node Id, the root Id of the main graph, the file version, the current file path. 

listLayoutParameters(fileHandle, parameterNameList) # parameterNameList must be an empty list() when calling, which will be fed by the function. Returns False on error

getLayoutParameter(fileHandle, parameterName) # returns None on error or the parameter value

setLayoutParameter(fileHandle, parameterName, parameterValue) # returns False on error

Root ID

Root Id of the main graph, or a group graph if an integer groupNodeId is mentionned, can be get and set via those functions. 

getRootId(fileHandle, groupNodeId=None) # returns -1 on error or the rootId

setRootId(fileHandle, rootId, groupNodeId=None) # returns False on error

Getting Node from ID

getNodeById(fileHandle, nodeID) # returns None on error, or the node instance

Nodes Generic Properties

Some node properties can be set/get by specific functions. All these functions use a node instance, as returned by getNodeById(), or by a creation function createOperator() or createSelector(). On error, getter functions return None while setter functions return False.

Operator and selector shared accessors :

getNodeID(nodeInst) # returns the Node ID

getNodeActive(nodeInst) # returns 1 if enabled, 0 if disabled

getNodeName(nodeInst) # returns the name of the node

getNodePos(nodeInst) # returns an array of [X, Y] value in canvas

setNodeActive(nodeInst, active) # set active to 0 for disabled, or 1 for enabled

setNodeName(nodeInst, name)

setNodePos(nodeInst, pos) # set an array of [X, Y] value in canvas. You can use another node to deduce a position. Default node width in canva is 200 units and separation is an additional 100 units, node height varies depending on type.

Operator only accessors :

getNodeTypeName(nodeInst) # returns the operator type name

getNodeType(nodeInst) # returns the operator numeric type

Selector only accessors :

getNodeEntities(nodeInst) # returns the "entities" string of the selector

setNodeEntities(nodeInst, entities) # sets the "entities" string of the selector

Operator Node Attributes

Operator node attributes depend on the node operator type. Their list can be queried with a function, or the full description of nodes can be found in the [GolaemInstallDir]/scripts/glm/golaem_layoutNodes_definition.json file. Type depends on the attribute, and is always get/set with keyframe and keyValues arrays. Keyframe array can be empty if the attribute is not keyframed. In that occurence, the parameter value will be found in key value between double brackets [[ ]], meaning first value of first (default) frame. For more information about keyFrames and keyValues expected format, see the detailed description of the Simulation Cache Layout File (.gscl)

listNodeAttributes(operatorNode, attributeNameList) # takes an empty attributeNameList list() and feed it, or return False

getNodeAttribute(operatorNode, attributeName, keyFrames, keyValues) # returns None on error

setNodeAttribute(operatorNode, attributeName, keyFrames, keyValues) # returns False on error

setAllNodesAttribute(fileHandle, attributeName, keyFrames, keyValues) # returns False on error

setAllNodesOfTypeAttribute(fileHandle, nodeType, attributeName, keyFrames, keyValues) # returns False on error

Connections

Connections between nodes are requested and handled by those functions. User is responsible to link nodes which are part of the same graph (main graph or a group).

listIncomingConnections(fileHandle, nodeInst, incomingNodeIds) # incomingNodeIds must be an empty list, feed the list or return False

listOutgoingConnections(fileHandle, nodeInst, outgoingNodeIds)  #outgoingNodeIds must be an empty list, feed the list or return False

connect(fileHandle, fromNodeId, toNodeId) # return False on error

disconnect(fileHandle, fromNodeId, toNodeId) # return False on error

Nodes creation

Two methods allow to build new nodes. Nodes can be inserted after other nodes. In that case, a link is automatically done between 'insertAfterNode' and the new node. If the 'insertAfterNode' is root, the "root" is forwarded to the new node. If the new node is the first of a graph (group or main graph), it becomes root automatically. You can refer to the [GolaemInstallDir]/scripts/glm/golaem_layoutNodes_definition.json file for a complete layout nodes definitions.

createSelector(fileHandle, entities, insertAfterNode=None, parentGroupNodeId=None) # returns None on error, or the created selector node instance

listOperators(fileHandle, operatorsList) # feed the operatorsList list() with all the possible operator type names

createOperator(fileHandle, operatorTypeName, insertAfterNode=None, parentGroupNodeId=None) # returns None on error, or the created operator node instance

Nodes deletion

The deletion function takes only a single argument, the node to delete. If the node was the root of its graph, it is the user responsability to set a new root. Deleting a node will also delete all its incoming and outgoing connections.

deleteNode(nodeInstance)

Saving The Layout File

The modified layout can be saved in place, or by specifying a new path. 

saveLayoutFile(fileHandle, newPath = None)

Basic usage sample code

# Insure that we have an app before calling layout (not required if already in a DCC)

from glm.Qtpy.Qt import QtWidgets

try:

   app = QtWidgets.QApplication([]) except:

   app = None

# Load module

from glm.layout.layout import *

filePath = 'N:/asset/layoutFile.gscl'

fileHandle = openLayoutFile(filePath)

if (fileHandle is not None):

   # get current Root Node Id for main graph

   rootId = getRootId(fileHandle)

   # get current Root Node from Id (to be able to link next nodes)

   previousRootNode = getNodeById(fileHandle, rootId)

   # create a selector, linked after root and automatically set as root instead

   translateSelectorNode = createSelector(fileHandle, "*", previousRootNode)

   # create a Translate operator, linked after selector and automatically set as root instead

   translateOperatorNode = createOperator(fileHandle, "Translate", translateSelectorNode)

   # set the translate attribute of the Translate, no keyframe, a single value [10, 0, 0] in the 1st value of the 1st frame

   setNodeAttribute(translateOperatorNode, "translate", [], [[[10, 0, 0]]])

   saveLayoutFile(fileHandle, filePath)

Was this information helpful?