Simple Blender Render: no longer render to intermediate directory

Simple Blender Render now no longer renders to an intermediate directory.
This not only simplifies the script, but it also opens the door for
selective re-running of individual tasks.

In the old situation, where the intermediate directory was renamed to
the desired name in the last task, rerunning tasks would fail because the
directory they expect to exist no longer exists. This is now resolved.
This commit is contained in:
Sybren A. Stüvel 2022-08-31 17:08:01 +02:00
parent f065cda830
commit 0afde53209
2 changed files with 22 additions and 42 deletions

@ -89,11 +89,11 @@ func TestSimpleBlenderRenderHappy(t *testing.T) {
settings := sj.Settings.AdditionalProperties
// Tasks should have been created to render the frames: 1-3, 4-6, 7-9, 10, video-encoding, and cleanup
assert.Len(t, aj.Tasks, 6)
// Tasks should have been created to render the frames: 1-3, 4-6, 7-9, 10, and video-encoding
assert.Len(t, aj.Tasks, 5)
t0 := aj.Tasks[0]
expectCliArgs := []interface{}{ // They are strings, but Goja doesn't know that and will produce an []interface{}.
"--render-output", "/render/sprites/farm_output/promo/square_ellie/square_ellie.lighting_light_breakdown2__intermediate-2006-01-02_090405/######",
"--render-output", "/render/sprites/farm_output/promo/square_ellie/square_ellie.lighting_light_breakdown2/######",
"--render-format", settings["format"].(string),
"--render-frame", "1..3",
}
@ -116,8 +116,8 @@ func TestSimpleBlenderRenderHappy(t *testing.T) {
assert.Equal(t, "frames-to-video", tVideo.Commands[0].Name)
assert.EqualValues(t, AuthoredCommandParameters{
"exe": "ffmpeg",
"inputGlob": "/render/sprites/farm_output/promo/square_ellie/square_ellie.lighting_light_breakdown2__intermediate-2006-01-02_090405/*.png",
"outputFile": "/render/sprites/farm_output/promo/square_ellie/square_ellie.lighting_light_breakdown2__intermediate-2006-01-02_090405/scene123-1-10.mp4",
"inputGlob": "/render/sprites/farm_output/promo/square_ellie/square_ellie.lighting_light_breakdown2/*.png",
"outputFile": "/render/sprites/farm_output/promo/square_ellie/square_ellie.lighting_light_breakdown2/scene123-1-10.mp4",
"fps": int64(24),
"args": expectedFramesToVideoArgs,
}, tVideo.Commands[0].Parameters)
@ -173,12 +173,12 @@ func TestSimpleBlenderRenderWindowsPaths(t *testing.T) {
settings := sj.Settings.AdditionalProperties
// Tasks should have been created to render the frames: 1-3, 4-6, 7-9, 10, video-encoding, and cleanup
assert.Len(t, aj.Tasks, 6)
// Tasks should have been created to render the frames: 1-3, 4-6, 7-9, 10, and video-encoding
assert.Len(t, aj.Tasks, 5)
t0 := aj.Tasks[0]
expectCliArgs := []interface{}{ // They are strings, but Goja doesn't know that and will produce an []interface{}.
// The render output is constructed by the job compiler, and thus transforms to forward slashes.
"--render-output", "R:/sprites/farm_output/promo/square_ellie/square_ellie.lighting_light_breakdown2__intermediate-2006-01-02_090405/######",
"--render-output", "R:/sprites/farm_output/promo/square_ellie/square_ellie.lighting_light_breakdown2/######",
"--render-format", settings["format"].(string),
"--render-frame", "1..3",
}
@ -201,8 +201,8 @@ func TestSimpleBlenderRenderWindowsPaths(t *testing.T) {
assert.Equal(t, "frames-to-video", tVideo.Commands[0].Name)
assert.EqualValues(t, AuthoredCommandParameters{
"exe": "ffmpeg",
"inputGlob": "R:/sprites/farm_output/promo/square_ellie/square_ellie.lighting_light_breakdown2__intermediate-2006-01-02_090405/*.png",
"outputFile": "R:/sprites/farm_output/promo/square_ellie/square_ellie.lighting_light_breakdown2__intermediate-2006-01-02_090405/scene123-1-10.mp4",
"inputGlob": "R:/sprites/farm_output/promo/square_ellie/square_ellie.lighting_light_breakdown2/*.png",
"outputFile": "R:/sprites/farm_output/promo/square_ellie/square_ellie.lighting_light_breakdown2/scene123-1-10.mp4",
"fps": int64(24),
"args": expectedFramesToVideoArgs,
}, tVideo.Commands[0].Parameters)
@ -232,11 +232,11 @@ func TestSimpleBlenderRenderOutputPathFieldReplacement(t *testing.T) {
// The job compiler should have replaced the {timestamp} and {ext} fields.
assert.Equal(t, "/root/2006-01-02_090405/jobname/######", aj.Settings["render_output_path"])
// Tasks should have been created to render the frames: 1-3, 4-6, 7-9, 10, video-encoding, and cleanup
assert.Len(t, aj.Tasks, 6)
// Tasks should have been created to render the frames: 1-3, 4-6, 7-9, 10, and video-encoding
require.Len(t, aj.Tasks, 5)
t0 := aj.Tasks[0]
expectCliArgs := []interface{}{ // They are strings, but Goja doesn't know that and will produce an []interface{}.
"--render-output", "/root/2006-01-02_090405/jobname__intermediate-2006-01-02_090405/######",
"--render-output", "/root/2006-01-02_090405/jobname/######",
"--render-format", sj.Settings.AdditionalProperties["format"].(string),
"--render-frame", "1..3",
}
@ -251,8 +251,8 @@ func TestSimpleBlenderRenderOutputPathFieldReplacement(t *testing.T) {
tVideo := aj.Tasks[4] // This should be a video encoding task
assert.EqualValues(t, AuthoredCommandParameters{
"exe": "ffmpeg",
"inputGlob": "/root/2006-01-02_090405/jobname__intermediate-2006-01-02_090405/*.png",
"outputFile": "/root/2006-01-02_090405/jobname__intermediate-2006-01-02_090405/scene123-1-10.mp4",
"inputGlob": "/root/2006-01-02_090405/jobname/*.png",
"outputFile": "/root/2006-01-02_090405/jobname/scene123-1-10.mp4",
"fps": int64(24),
"args": expectedFramesToVideoArgs,
}, tVideo.Commands[0].Parameters)

@ -45,23 +45,22 @@ function compileJob(job) {
print("Blender Render job submitted");
print("job: ", job);
if (videoFormats.indexOf(job.settings.format) >= 0) {
throw `This job type only renders images, and not "${job.settings.format}"`;
const settings = job.settings;
if (videoFormats.indexOf(settings.format) >= 0) {
throw `This job type only renders images, and not "${settings.format}"`;
}
const renderOutput = renderOutputPath(job);
job.settings.render_output_path = renderOutput;
const finalDir = path.dirname(renderOutput);
const renderDir = intermediatePath(job, finalDir);
// Make sure that when the job is investigated later, it shows the
// actually-used render output:
settings.render_output_path = renderOutput;
const settings = job.settings;
const renderDir = path.dirname(renderOutput);
const renderTasks = authorRenderTasks(settings, renderDir, renderOutput);
const videoTask = authorCreateVideoTask(settings, renderDir);
const cleanupTask = authorCleanupTask(finalDir, renderDir);
for (const rt of renderTasks) {
cleanupTask.addDependency(rt);
job.addTask(rt);
}
if (videoTask) {
@ -69,10 +68,8 @@ function compileJob(job) {
for (const rt of renderTasks) {
videoTask.addDependency(rt);
}
cleanupTask.addDependency(videoTask);
job.addTask(videoTask);
}
job.addTask(cleanupTask);
}
// Do field replacement on the render output path.
@ -91,13 +88,6 @@ function renderOutputPath(job) {
});
}
// Determine the intermediate render output path.
function intermediatePath(job, finalDir) {
const basename = path.basename(finalDir);
const name = `${basename}__intermediate-${formatTimestampLocal(job.created)}`;
return path.join(path.dirname(finalDir), name);
}
function authorRenderTasks(settings, renderDir, renderOutput) {
print("authorRenderTasks(", renderDir, renderOutput, ")");
let renderTasks = [];
@ -156,13 +146,3 @@ function authorCreateVideoTask(settings, renderDir) {
print(`Creating output video for ${settings.format}`);
return task;
}
function authorCleanupTask(finalDir, renderDir) {
const task = author.Task("move-to-final", "file-management");
const command = author.Command("move-directory", {
src: renderDir,
dest: finalDir,
});
task.addCommand(command);
return task;
}