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:
parent
f065cda830
commit
0afde53209
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user