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
|
settings := sj.Settings.AdditionalProperties
|
||||||
|
|
||||||
// Tasks should have been created to render the frames: 1-3, 4-6, 7-9, 10, video-encoding, and cleanup
|
// Tasks should have been created to render the frames: 1-3, 4-6, 7-9, 10, and video-encoding
|
||||||
assert.Len(t, aj.Tasks, 6)
|
assert.Len(t, aj.Tasks, 5)
|
||||||
t0 := aj.Tasks[0]
|
t0 := aj.Tasks[0]
|
||||||
expectCliArgs := []interface{}{ // They are strings, but Goja doesn't know that and will produce an []interface{}.
|
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-format", settings["format"].(string),
|
||||||
"--render-frame", "1..3",
|
"--render-frame", "1..3",
|
||||||
}
|
}
|
||||||
@ -116,8 +116,8 @@ func TestSimpleBlenderRenderHappy(t *testing.T) {
|
|||||||
assert.Equal(t, "frames-to-video", tVideo.Commands[0].Name)
|
assert.Equal(t, "frames-to-video", tVideo.Commands[0].Name)
|
||||||
assert.EqualValues(t, AuthoredCommandParameters{
|
assert.EqualValues(t, AuthoredCommandParameters{
|
||||||
"exe": "ffmpeg",
|
"exe": "ffmpeg",
|
||||||
"inputGlob": "/render/sprites/farm_output/promo/square_ellie/square_ellie.lighting_light_breakdown2__intermediate-2006-01-02_090405/*.png",
|
"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__intermediate-2006-01-02_090405/scene123-1-10.mp4",
|
"outputFile": "/render/sprites/farm_output/promo/square_ellie/square_ellie.lighting_light_breakdown2/scene123-1-10.mp4",
|
||||||
"fps": int64(24),
|
"fps": int64(24),
|
||||||
"args": expectedFramesToVideoArgs,
|
"args": expectedFramesToVideoArgs,
|
||||||
}, tVideo.Commands[0].Parameters)
|
}, tVideo.Commands[0].Parameters)
|
||||||
@ -173,12 +173,12 @@ func TestSimpleBlenderRenderWindowsPaths(t *testing.T) {
|
|||||||
|
|
||||||
settings := sj.Settings.AdditionalProperties
|
settings := sj.Settings.AdditionalProperties
|
||||||
|
|
||||||
// Tasks should have been created to render the frames: 1-3, 4-6, 7-9, 10, video-encoding, and cleanup
|
// Tasks should have been created to render the frames: 1-3, 4-6, 7-9, 10, and video-encoding
|
||||||
assert.Len(t, aj.Tasks, 6)
|
assert.Len(t, aj.Tasks, 5)
|
||||||
t0 := aj.Tasks[0]
|
t0 := aj.Tasks[0]
|
||||||
expectCliArgs := []interface{}{ // They are strings, but Goja doesn't know that and will produce an []interface{}.
|
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.
|
// 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-format", settings["format"].(string),
|
||||||
"--render-frame", "1..3",
|
"--render-frame", "1..3",
|
||||||
}
|
}
|
||||||
@ -201,8 +201,8 @@ func TestSimpleBlenderRenderWindowsPaths(t *testing.T) {
|
|||||||
assert.Equal(t, "frames-to-video", tVideo.Commands[0].Name)
|
assert.Equal(t, "frames-to-video", tVideo.Commands[0].Name)
|
||||||
assert.EqualValues(t, AuthoredCommandParameters{
|
assert.EqualValues(t, AuthoredCommandParameters{
|
||||||
"exe": "ffmpeg",
|
"exe": "ffmpeg",
|
||||||
"inputGlob": "R:/sprites/farm_output/promo/square_ellie/square_ellie.lighting_light_breakdown2__intermediate-2006-01-02_090405/*.png",
|
"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__intermediate-2006-01-02_090405/scene123-1-10.mp4",
|
"outputFile": "R:/sprites/farm_output/promo/square_ellie/square_ellie.lighting_light_breakdown2/scene123-1-10.mp4",
|
||||||
"fps": int64(24),
|
"fps": int64(24),
|
||||||
"args": expectedFramesToVideoArgs,
|
"args": expectedFramesToVideoArgs,
|
||||||
}, tVideo.Commands[0].Parameters)
|
}, tVideo.Commands[0].Parameters)
|
||||||
@ -232,11 +232,11 @@ func TestSimpleBlenderRenderOutputPathFieldReplacement(t *testing.T) {
|
|||||||
// The job compiler should have replaced the {timestamp} and {ext} fields.
|
// 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"])
|
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
|
// Tasks should have been created to render the frames: 1-3, 4-6, 7-9, 10, and video-encoding
|
||||||
assert.Len(t, aj.Tasks, 6)
|
require.Len(t, aj.Tasks, 5)
|
||||||
t0 := aj.Tasks[0]
|
t0 := aj.Tasks[0]
|
||||||
expectCliArgs := []interface{}{ // They are strings, but Goja doesn't know that and will produce an []interface{}.
|
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-format", sj.Settings.AdditionalProperties["format"].(string),
|
||||||
"--render-frame", "1..3",
|
"--render-frame", "1..3",
|
||||||
}
|
}
|
||||||
@ -251,8 +251,8 @@ func TestSimpleBlenderRenderOutputPathFieldReplacement(t *testing.T) {
|
|||||||
tVideo := aj.Tasks[4] // This should be a video encoding task
|
tVideo := aj.Tasks[4] // This should be a video encoding task
|
||||||
assert.EqualValues(t, AuthoredCommandParameters{
|
assert.EqualValues(t, AuthoredCommandParameters{
|
||||||
"exe": "ffmpeg",
|
"exe": "ffmpeg",
|
||||||
"inputGlob": "/root/2006-01-02_090405/jobname__intermediate-2006-01-02_090405/*.png",
|
"inputGlob": "/root/2006-01-02_090405/jobname/*.png",
|
||||||
"outputFile": "/root/2006-01-02_090405/jobname__intermediate-2006-01-02_090405/scene123-1-10.mp4",
|
"outputFile": "/root/2006-01-02_090405/jobname/scene123-1-10.mp4",
|
||||||
"fps": int64(24),
|
"fps": int64(24),
|
||||||
"args": expectedFramesToVideoArgs,
|
"args": expectedFramesToVideoArgs,
|
||||||
}, tVideo.Commands[0].Parameters)
|
}, tVideo.Commands[0].Parameters)
|
||||||
|
@ -45,23 +45,22 @@ function compileJob(job) {
|
|||||||
print("Blender Render job submitted");
|
print("Blender Render job submitted");
|
||||||
print("job: ", job);
|
print("job: ", job);
|
||||||
|
|
||||||
if (videoFormats.indexOf(job.settings.format) >= 0) {
|
const settings = job.settings;
|
||||||
throw `This job type only renders images, and not "${job.settings.format}"`;
|
if (videoFormats.indexOf(settings.format) >= 0) {
|
||||||
|
throw `This job type only renders images, and not "${settings.format}"`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const renderOutput = renderOutputPath(job);
|
const renderOutput = renderOutputPath(job);
|
||||||
job.settings.render_output_path = renderOutput;
|
|
||||||
|
|
||||||
const finalDir = path.dirname(renderOutput);
|
// Make sure that when the job is investigated later, it shows the
|
||||||
const renderDir = intermediatePath(job, finalDir);
|
// 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 renderTasks = authorRenderTasks(settings, renderDir, renderOutput);
|
||||||
const videoTask = authorCreateVideoTask(settings, renderDir);
|
const videoTask = authorCreateVideoTask(settings, renderDir);
|
||||||
const cleanupTask = authorCleanupTask(finalDir, renderDir);
|
|
||||||
|
|
||||||
for (const rt of renderTasks) {
|
for (const rt of renderTasks) {
|
||||||
cleanupTask.addDependency(rt);
|
|
||||||
job.addTask(rt);
|
job.addTask(rt);
|
||||||
}
|
}
|
||||||
if (videoTask) {
|
if (videoTask) {
|
||||||
@ -69,10 +68,8 @@ function compileJob(job) {
|
|||||||
for (const rt of renderTasks) {
|
for (const rt of renderTasks) {
|
||||||
videoTask.addDependency(rt);
|
videoTask.addDependency(rt);
|
||||||
}
|
}
|
||||||
cleanupTask.addDependency(videoTask);
|
|
||||||
job.addTask(videoTask);
|
job.addTask(videoTask);
|
||||||
}
|
}
|
||||||
job.addTask(cleanupTask);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do field replacement on the render output path.
|
// 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) {
|
function authorRenderTasks(settings, renderDir, renderOutput) {
|
||||||
print("authorRenderTasks(", renderDir, renderOutput, ")");
|
print("authorRenderTasks(", renderDir, renderOutput, ")");
|
||||||
let renderTasks = [];
|
let renderTasks = [];
|
||||||
@ -156,13 +146,3 @@ function authorCreateVideoTask(settings, renderDir) {
|
|||||||
print(`Creating output video for ${settings.format}`);
|
print(`Creating output video for ${settings.format}`);
|
||||||
return task;
|
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…
x
Reference in New Issue
Block a user