Skip to content

Commit

Permalink
Add frame range to Blender command in CueSubmit (#1337)
Browse files Browse the repository at this point in the history
* Add frame range to Blender render command

Extracted from layerRange value in layerData

Import regex module

* Fix linting issue

Line too long

* Add variables for frame range tokens

* Update Blender command with tokens for
animation frame range

* Remove unused import

* Add suffix to frame start/end variables

* Update comment

Update comment explaining render frame range Blender command

* Add unit tests

For single frame and multi frame Blender renders

* Add missing services line to blender unit test layer data
  • Loading branch information
n-jay authored and carlosfelgarcia committed May 22, 2024
1 parent 97f265b commit fd7e7bf
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 4 deletions.
5 changes: 3 additions & 2 deletions cuesubmit/cuesubmit/Constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
Some values can be overridden by custom config, see Config.py."""


from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
Expand All @@ -38,6 +37,8 @@
NUKE_RENDER_CMD = config.get('NUKE_RENDER_CMD', 'nuke')
BLENDER_RENDER_CMD = config.get('BLENDER_RENDER_CMD', 'blender')
FRAME_TOKEN = config.get('FRAME_TOKEN', '#IFRAME#')
FRAME_START_TOKEN = config.get('FRAME_START', '#FRAME_START#')
FRAME_END_TOKEN = config.get('FRAME_END', '#FRAME_END#')

# Tokens are replaced by cuebot during dispatch with their computed value.
# see: cuebot/src/main/java/com/imageworks/spcue/dispatcher/DispatchSupportService.java
Expand All @@ -55,7 +56,7 @@
BLENDER_FORMATS = ['', 'AVIJPEG', 'AVIRAW', 'BMP', 'CINEON', 'DPX', 'EXR', 'HDR', 'IRIS', 'IRIZ',
'JP2', 'JPEG', 'MPEG', 'MULTILAYER', 'PNG', 'RAWTGA', 'TGA', 'TIFF']
BLENDER_OUTPUT_OPTIONS_URL = \
'https://docs.blender.org/manual/en/latest/advanced/command_line/arguments.html#render-options'
'https://docs.blender.org/manual/en/latest/advanced/command_line/arguments.html#render-options'

DIR_PATH = os.path.dirname(__file__)

Expand Down
11 changes: 9 additions & 2 deletions cuesubmit/cuesubmit/Submission.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ def buildBlenderCmd(layerData):
blenderFile = layerData.cmd.get('blenderFile')
outputPath = layerData.cmd.get('outputPath')
outputFormat = layerData.cmd.get('outputFormat')
frameRange = layerData.layerRange
if not blenderFile:
raise ValueError('No Blender file provided. Cannot submit job.')

Expand All @@ -72,8 +73,14 @@ def buildBlenderCmd(layerData):
renderCommand += ' -o {}'.format(outputPath)
if outputFormat:
renderCommand += ' -F {}'.format(outputFormat)
# The render frame must come after the scene and output
renderCommand += ' -f {frameToken}'.format(frameToken=Constants.FRAME_TOKEN)
if frameRange:
# Render frames from start to end (inclusive) via '-a' command argument
renderCommand += (' -s {startFrame} -e {endFrame} -a'
.format(startFrame=Constants.FRAME_START_TOKEN,
endFrame=Constants.FRAME_END_TOKEN))
else:
# The render frame must come after the scene and output
renderCommand += ' -f {frameToken}'.format(frameToken=Constants.FRAME_TOKEN)
return renderCommand


Expand Down
70 changes: 70 additions & 0 deletions cuesubmit/tests/Submission_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,27 @@
'services': ['nuke'],
}

BLENDER_MULTI_LAYER_DATA = {
'name': 'arbitraryBlenderLayer_name',
'layerType': cuesubmit.JobTypes.JobTypes.BLENDER,
'cmd': {'outputPath': '/path/to/output',
'blenderFile': '/path/to/scene.blend',
'outputFormat': 'PNG'},
'layerRange': '3-9',
'cores': '2',
'services': ['blender']
}

BLENDER_SINGLE_LAYER_DATA = {
'name': 'arbitraryBlenderLayer_name',
'layerType': cuesubmit.JobTypes.JobTypes.BLENDER,
'cmd': {'outputPath': '/path/to/output',
'blenderFile': '/path/to/scene.blend',
'outputFormat': 'PNG'},
'cores': '2',
'services': ['blender']
}

SHELL_LAYER_DATA = {
'name': 'arbitraryShellLayer_name',
'layerType': cuesubmit.JobTypes.JobTypes.SHELL,
Expand Down Expand Up @@ -109,6 +130,55 @@ def testSubmitNukeJob(self, launchMock):
self.assertEqual(NUKE_LAYER_DATA['layerRange'], layer.get_frame_range())
self.assertEqual('nuke', layer.get_service())

def testSubmitSingleFrameBlenderJob(self, launchMock):
cuesubmit.Submission.submitJob({
'name': 'arbitrary-blender-job',
'shot': 'arbitrary-shot-name',
'show': 'arbitrary-show-name',
'username': 'arbitrary-user',
'layers': [cuesubmit.Layer.LayerData.buildFactory(**BLENDER_SINGLE_LAYER_DATA)],
})

ol = launchMock.call_args[0][0]
self.assertEqual(1, len(ol.get_layers()))
layer = ol.get_layer(BLENDER_SINGLE_LAYER_DATA['name'])
self.assertEqual(BLENDER_SINGLE_LAYER_DATA['name'], layer.get_name())
self.assertEqual(
[
'blender', '-b', '-noaudio', BLENDER_SINGLE_LAYER_DATA['cmd']['blenderFile'],
'-o', BLENDER_SINGLE_LAYER_DATA['cmd']['outputPath'],
'-F', BLENDER_SINGLE_LAYER_DATA['cmd']['outputFormat'],
'-f', '#IFRAME#'
],
layer.get_arg('command')
)
self.assertEqual('blender', layer.get_service())

def testSubmitMultiFrameBlenderJob(self, launchMock):
cuesubmit.Submission.submitJob({
'name': 'arbitrary-blender-job',
'shot': 'arbitrary-shot-name',
'show': 'arbitrary-show-name',
'username': 'arbitrary-user',
'layers': [cuesubmit.Layer.LayerData.buildFactory(**BLENDER_MULTI_LAYER_DATA)],
})

ol = launchMock.call_args[0][0]
self.assertEqual(1, len(ol.get_layers()))
layer = ol.get_layer(BLENDER_MULTI_LAYER_DATA['name'])
self.assertEqual(BLENDER_MULTI_LAYER_DATA['name'], layer.get_name())
self.assertEqual(
[
'blender', '-b', '-noaudio', BLENDER_MULTI_LAYER_DATA['cmd']['blenderFile'],
'-o', BLENDER_MULTI_LAYER_DATA['cmd']['outputPath'],
'-F', BLENDER_MULTI_LAYER_DATA['cmd']['outputFormat'],
'-s', '#FRAME_START#', '-e', '#FRAME_END#', '-a'
],
layer.get_arg('command')
)
self.assertEqual(BLENDER_MULTI_LAYER_DATA['layerRange'], layer.get_frame_range())
self.assertEqual('blender', layer.get_service())

def testSubmitMayaAndShellJob(self, launchMock):
cuesubmit.Submission.submitJob({
'name': 'arbitrary-maya-shell-job',
Expand Down

0 comments on commit fd7e7bf

Please sign in to comment.