From 6841a99a908dce780c2801e6ab914d8dd22d13f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Thu, 1 Aug 2024 14:45:46 +0200 Subject: [PATCH] Simple Blender Render: include scene name in job settings Include the current scene name in a hidden setting of the Simple Blender Render, and pass that as CLI argument to Blender. This ensures that the correct scene is rendered when working directly on shared storage (as that does not have a copy of the blend file per job). The job setting `"scene"` is still optional. If it's missing or empty, the `--scene ` CLI arg will simply not be passed to Blender. --- CHANGELOG.md | 1 + .../job_compilers/job_compilers_test.go | 35 +++++++++++++++++++ .../scripts/simple_blender_render.js | 12 +++++-- 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c40bb13..a9106145 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ bugs in actually-released versions. - Security updates of some deendencies: - [GO-2024-2937: Parsing a corrupt or malicious image with invalid color indices can cause a panic](https://pkg.go.dev/vuln/GO-2024-2937) - Web interface: list the job's worker tag in the job details. +- Ensure the submitted scene is rendered in a multi-scene blend file. ## 3.5 - released 2024-04-16 diff --git a/internal/manager/job_compilers/job_compilers_test.go b/internal/manager/job_compilers/job_compilers_test.go index 430d8dbd..dae5f8e1 100644 --- a/internal/manager/job_compilers/job_compilers_test.go +++ b/internal/manager/job_compilers/job_compilers_test.go @@ -139,6 +139,41 @@ func TestSimpleBlenderRenderHappy(t *testing.T) { assert.Equal(t, expectDeps, tVideo.Dependencies) } +func TestSimpleBlenderRenderWithScene(t *testing.T) { + c := mockedClock(t) + + s, err := Load(c) + require.NoError(t, err) + + // Compiling a job should be really fast. + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond) + defer cancel() + + sj := exampleSubmittedJob() + sj.Settings.AdditionalProperties["scene"] = "Test Scene" + aj, err := s.Compile(ctx, sj) + require.NoError(t, err) + require.NotNil(t, aj) + + t0 := aj.Tasks[0] + expectCliArgs := []interface{}{ // They are strings, but Goja doesn't know that and will produce an []interface{}. + "--scene", "Test Scene", + "--render-output", "/render/sprites/farm_output/promo/square_ellie/square_ellie.lighting_light_breakdown2/######", + "--render-format", "PNG", + "--render-frame", "1..3", + } + assert.Equal(t, "render-1-3", t0.Name) + assert.Equal(t, 1, len(t0.Commands)) + assert.Equal(t, "blender-render", t0.Commands[0].Name) + assert.EqualValues(t, AuthoredCommandParameters{ + "exe": "{blender}", + "exeArgs": "{blenderArgs}", + "blendfile": "/render/sf/jobs/scene123.blend", + "args": expectCliArgs, + "argsBefore": make([]interface{}, 0), + }, t0.Commands[0].Parameters) +} + func TestJobWithoutTag(t *testing.T) { c := mockedClock(t) diff --git a/internal/manager/job_compilers/scripts/simple_blender_render.js b/internal/manager/job_compilers/scripts/simple_blender_render.js index 3c6f4123..5d9c2fb2 100644 --- a/internal/manager/job_compilers/scripts/simple_blender_render.js +++ b/internal/manager/job_compilers/scripts/simple_blender_render.js @@ -32,6 +32,8 @@ const JOB_TYPE = { description: "File extension used when rendering images" }, { key: "has_previews", type: "bool", required: false, eval: "C.scene.render.image_settings.use_preview", visible: "hidden", description: "Whether Blender will render preview images."}, + { key: "scene", type: "string", required: true, eval: "C.scene.name", visible: "web", + description: "Name of the scene to render."}, ] }; @@ -100,6 +102,12 @@ function authorRenderTasks(settings, renderDir, renderOutput) { print("authorRenderTasks(", renderDir, renderOutput, ")"); let renderTasks = []; let chunks = frameChunker(settings.frames, settings.chunk_size); + + let baseArgs = []; + if (settings.scene) { + baseArgs = baseArgs.concat(["--scene", settings.scene]); + } + for (let chunk of chunks) { const task = author.Task(`render-${chunk}`, "blender"); const command = author.Command("blender-render", { @@ -107,11 +115,11 @@ function authorRenderTasks(settings, renderDir, renderOutput) { exeArgs: "{blenderArgs}", argsBefore: [], blendfile: settings.blendfile, - args: [ + args: baseArgs.concat([ "--render-output", path.join(renderDir, path.basename(renderOutput)), "--render-format", settings.format, "--render-frame", chunk.replaceAll("-", ".."), // Convert to Blender frame range notation. - ] + ]) }); task.addCommand(command); renderTasks.push(task);