Skip to content

Instantly share code, notes, and snippets.

@mottosso
Last active March 14, 2021 20:17
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mottosso/ee34d1f1819efb7251abf08ae3532346 to your computer and use it in GitHub Desktop.
Save mottosso/ee34d1f1819efb7251abf08ae3532346 to your computer and use it in GitHub Desktop.
Parallel Evaluation in Maya 2018+

An example of parallel evaluation in Maya 2018+

Scenes

  1. Independent hierarchies, with parent constraint

Usage

Files prefixed scene* generate nodes suitable for parallelism, profile* contain ways to measure performance. Each snippet of code is meant to be copy/pasted into the Script Editor and run.

  1. Run a scene
  2. Run a profile

Output

evaluation=off: 107.23 ms
evaluation=parallel: 103.81 ms
"""Incrementing time via `cmds.currentTime`, keeping track of time
Example:
evaluation=off: 107.23 ms
evaluation=parallel: 103.81 ms
"""
import timeit
from maya import cmds
def test(name):
def run():
cmds.refresh(suspend=True)
for i in range(start, end):
cmds.currentTime(i, update=False)
cmds.refresh(suspend=False)
times = timeit.repeat(run, number=1, repeat=3)
best = min(times)
print("%s: %.2f ms" % (name, best * 1000))
import timeit
# Profile "mode"
cmds.evaluationManager(mode="off")
test("evaluation=off")
cmds.evaluationManager(mode="parallel")
test("evaluation=parallel")
"""Run Maya for X amount of time in each evaluation mode, keeping track of how many frames it drew
This includes viewport refresh, higher numbers are better.
Example:
evaluation=off: 128 frames
evaluation=parallel: 146 frames
"""
from maya import cmds
from PySide2 import QtCore
# Setup
cmds.playbackOptions(min=1)
cmds.playbackOptions(max=10 ** 5)
cmds.playbackOptions(maxPlaybackSpeed=0)
cmds.playbackOptions(playbackSpeed=0)
# Parameters
duration = 1000 # Run for this long
def test(name, setup):
def onDone():
cmds.play(state=False)
results.append("%s: %d frames" % (name, cmds.currentTime(query=True)))
# Run next
try:
tests.pop(0)()
except IndexError:
onFinished()
def onFinished():
print("")
for result in results:
print(result)
# Run for 1 second
cmds.currentTime(1)
setup()
cmds.play()
QtCore.QTimer.singleShot(duration, onDone)
results = list()
tests = [
lambda: test("evaluation=off", setup=lambda: cmds.evaluationManager(mode="off")),
lambda: test("evaluation=parallel", setup=lambda: cmds.evaluationManager(mode="parallel"))
]
tests.pop(0)()
import random
from maya import cmds
# WARNING: This will wipe your current scene
cmds.file(new=True, force=True)
branches = 4 # Number of independent hierarchies
depth = 100 # Number of children per branch
# Create Scene
for branch in range(branches):
root = cmds.createNode("transform", name="root%d" % (branch + 1))
parent = root
for i in range(depth):
parent = cmds.createNode("transform", parent=parent)
cube, _ = cmds.polyCube(name="cube%d" % branch)
cmds.parentConstraint(parent, cube)
key = lambda frame, value: cmds.setKeyframe(
root,
attribute="translateY",
value=value,
time=[frame],
inTangentType="linear",
outTangentType="linear",
)
# Force evaluation on every frame
key(1, 0), key((10 ** 3) // 2, random.random() * 10), key(10 ** 5, 0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment