Skip to content
Snippets Groups Projects
Commit 146eaa0f authored by Sybren A. Stüvel's avatar Sybren A. Stüvel
Browse files

Worker: implemented MergeExrCommand

parent 57b7bb9e
Branches
Tags
No related merge requests found
*.pyc *.pyc
*.bak *.bak
*.blend[1-9]
/temp/ /temp/
/docs/site/ /docs/site/
......
No preview for this file type
...@@ -15,6 +15,26 @@ from . import worker ...@@ -15,6 +15,26 @@ from . import worker
# Timeout of subprocess.stdout.readline() call. # Timeout of subprocess.stdout.readline() call.
SUBPROC_READLINE_TIMEOUT = 3600 # seconds SUBPROC_READLINE_TIMEOUT = 3600 # seconds
MERGE_EXR_PYTHON = """\
import bpy
scene = bpy.context.scene
nodes = scene.node_tree.nodes
image1 = bpy.data.images.load("%(input1)s")
image2 = bpy.data.images.load("%(input2)s")
nodes["image1"].image = image1
nodes["image2"].image = image2
nodes["weight1"].outputs[0].default_value = %(weight1)i
nodes["weight2"].outputs[0].default_value = %(weight2)i
nodes["output"].base_path = "%(tmpdir)s"
scene.render.resolution_x, scene.render.resolution_y = image1.size
scene.render.tile_x, scene.render.tile_y = image1.size
scene.render.filepath = "%(tmpdir)s/preview.jpg"
bpy.ops.render.render(write_still=True)
"""
command_handlers = {} command_handlers = {}
...@@ -201,7 +221,7 @@ class AbstractCommand(metaclass=abc.ABCMeta): ...@@ -201,7 +221,7 @@ class AbstractCommand(metaclass=abc.ABCMeta):
return None return None
def _setting(self, settings: dict, key: str, is_required: bool, valtype=str) -> ( def _setting(self, settings: dict, key: str, is_required: bool, valtype: typing.Type = str) -> (
typing.Any, typing.Optional[str]): typing.Any, typing.Optional[str]):
"""Parses a setting, returns either (value, None) or (None, errormsg)""" """Parses a setting, returns either (value, None) or (None, errormsg)"""
...@@ -561,18 +581,36 @@ class MergeExrCommand(AbstractSubprocessCommand): ...@@ -561,18 +581,36 @@ class MergeExrCommand(AbstractSubprocessCommand):
return 'blender_cmd %r does not exist' % cmd[0] return 'blender_cmd %r does not exist' % cmd[0]
settings['blender_cmd'] = cmd settings['blender_cmd'] = cmd
_, err = self._setting(settings, 'input1', True, str) input1, err = self._setting(settings, 'input1', True, str)
if err: return err
if '"' in input1:
return 'Double quotes are not allowed in filenames: %r' % input1
if not Path(input1).exists():
return 'Input 1 %r does not exist' % input1
input2, err = self._setting(settings, 'input2', True, str)
if err: return err if err: return err
_, err = self._setting(settings, 'input2', True, str) if '"' in input2:
return 'Double quotes are not allowed in filenames: %r' % input2
if not Path(input2).exists():
return 'Input 2 %r does not exist' % input2
output, err = self._setting(settings, 'output', True, str)
if err: return err if err: return err
if '"' in output:
return 'Double quotes are not allowed in filenames: %r' % output
_, err = self._setting(settings, 'weight1', True, int) _, err = self._setting(settings, 'weight1', True, int)
if err: return err if err: return err
_, err = self._setting(settings, 'weight2', True, int) _, err = self._setting(settings, 'weight2', True, int)
if err: return err if err: return err
async def execute(self, settings: dict): async def execute(self, settings: dict):
import shlex from pathlib import Path
await self.subprocess(shlex.split(settings['cmd'])) import shutil
import tempfile
blendpath = Path(__file__).with_name('merge-exr.blend')
cmd = settings['blender_cmd'][:] cmd = settings['blender_cmd'][:]
cmd += [ cmd += [
...@@ -580,11 +618,26 @@ class MergeExrCommand(AbstractSubprocessCommand): ...@@ -580,11 +618,26 @@ class MergeExrCommand(AbstractSubprocessCommand):
'--enable-autoexec', '--enable-autoexec',
'-noaudio', '-noaudio',
'--background', '--background',
str(blendpath),
] ]
# TODO: set up node properties and render settings. # set up node properties and render settings.
output = Path(settings['output'])
output.mkdir(parents=True, exist_ok=True)
await self.worker.register_task_update(activity='Starting Blender') with tempfile.TemporaryDirectory(dir=str(output)) as tmpdir:
await self.subprocess(cmd) tmppath = Path(tmpdir)
assert tmppath.exists()
settings['tmpdir'] = tmpdir
cmd += [
'--python-expr', MERGE_EXR_PYTHON % settings
]
await self.worker.register_task_update(activity='Starting Blender to merge EXR files')
await self.subprocess(cmd)
# move output files into the correct spot.
shutil.move(str(tmppath / 'merged0001.exr'), str(output))
shutil.move(str(tmppath / 'preview.jpg'), str(output.with_suffix('.jpg')))
# TODO: move output files into the correct spot.
File added
File added
...@@ -10,3 +10,19 @@ class AbstractWorkerTest(unittest.TestCase): ...@@ -10,3 +10,19 @@ class AbstractWorkerTest(unittest.TestCase):
level=logging.DEBUG, level=logging.DEBUG,
format='%(asctime)-15s %(levelname)8s %(name)s %(message)s', format='%(asctime)-15s %(levelname)8s %(name)s %(message)s',
) )
def find_blender_cmd(self):
import os
import platform
if platform.system() == 'Windows':
blender = 'blender.exe'
else:
blender = 'blender'
for path in os.getenv('PATH').split(os.path.pathsep):
full_path = path + os.sep + blender
if os.path.exists(full_path):
return full_path
self.fail('Unable to find "blender" executable on $PATH')
from pathlib import Path
from test_runner import AbstractCommandTest
class MergeExrCommandTest(AbstractCommandTest):
def setUp(self):
super().setUp()
from flamenco_worker.runner import MergeExrCommand
import tempfile
self.tmpdir = tempfile.TemporaryDirectory()
self.mypath = Path(__file__).parent
self.cmd = MergeExrCommand(
worker=self.fworker,
task_id='12345',
command_idx=0,
)
def tearDown(self):
super().tearDown()
del self.tmpdir
def test_happy_flow(self):
output = Path(self.tmpdir.name) / 'merged.exr'
settings = {
'blender_cmd': self.find_blender_cmd(),
'input1': str(self.mypath / 'Corn field-1k.exr'),
'input2': str(self.mypath / 'Deventer-1k.exr'),
'weight1': 20,
'weight2': 100,
'output': str(output)
}
task = self.cmd.run(settings)
ok = self.loop.run_until_complete(task)
self.assertTrue(ok)
# Assuming that if the files exist, the merge was ok.
self.assertTrue(output.exists())
self.assertTrue(output.with_suffix('.jpg').exists())
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment