Skip to content

Commit

Permalink
Expose checkpoint option and save/restore renders
Browse files Browse the repository at this point in the history
- Expose a checkpoint option in cli
- Create a checkpoint after each passes if "--checkpoint" is on
- Restore from a checkpoint if "--checkpoint" is on
- Store and restore checkpoints to/from the given output file
- Store multi pass informations in diagnostic AOVs
- Store only the last samples in depth, normal and uv AOVs
- Handle denoiser when restoring a checkpoint (informations are not
	saved in the same checkpoint file)
- Refactor diagnostic and pixel time AOVs
- Fix passes option paths in cli and studio
- Clean-up tile bbox code snippets
- Minor changes
  • Loading branch information
oktomus committed Aug 1, 2018
1 parent 6828196 commit b145095
Show file tree
Hide file tree
Showing 45 changed files with 2,036 additions and 999 deletions.
5 changes: 5 additions & 0 deletions src/appleseed.cli/commandlinehandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,11 @@ CommandLineHandler::CommandLineHandler()
.set_description("display the output image"));
#endif

parser().add_option_handler(
&m_checkpoint
.add_name("--checkpoint")
.set_description("save a rendering checkpoint on each passes or resume rendering with a previous checkpoint"));

parser().add_option_handler(
&m_send_to_mplay
.add_name("--to-mplay")
Expand Down
1 change: 1 addition & 0 deletions src/appleseed.cli/commandlinehandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class CommandLineHandler
#if defined __APPLE__ || defined _WIN32
foundation::FlagOptionHandler m_display_output;
#endif
foundation::FlagOptionHandler m_checkpoint;
foundation::FlagOptionHandler m_send_to_stdout;
foundation::FlagOptionHandler m_send_to_mplay;
foundation::ValueOptionHandler<int> m_send_to_hrmanpipe;
Expand Down
34 changes: 29 additions & 5 deletions src/appleseed.cli/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ namespace
if (g_cl.m_passes.is_set())
{
params.insert_path(
"generic_frame_renderer.passes",
"passes",
g_cl.m_passes.values()[0]);
}
}
Expand Down Expand Up @@ -336,6 +336,26 @@ namespace
apply_visibility_command_line_options(assembly, show_filter, hide_filter);
}

bool apply_checkpoint_command_line_option(ParamArray& params)
{
if (g_cl.m_checkpoint.is_set())
{
if (!g_cl.m_output.is_set())
{
LOG_ERROR(g_logger, "ouput path must be specified when using checkpoints");
return false;
}

const char* file_path = g_cl.m_output.value().c_str();
LOG_DEBUG(g_logger, "will save checkpoint to %s", file_path);

params.insert_path("generic_frame_renderer.checkpoint", true);
params.insert_path("generic_frame_renderer.checkpoint_path", file_path);
}

return true;
}

void apply_parameter_command_line_options(ParamArray& params)
{
for (size_t i = 0; i < g_cl.m_params.values().size(); ++i)
Expand All @@ -353,7 +373,7 @@ namespace
}
}

void apply_command_line_options(Project& project, ParamArray& params)
bool apply_command_line_options(Project& project, ParamArray& params)
{
// Apply --disable-autosave option.
if (g_cl.m_disable_autosave.is_set())
Expand Down Expand Up @@ -397,8 +417,14 @@ namespace
g_cl.m_hide_object_instances.is_set() ? g_cl.m_hide_object_instances.value() : "(?!)"); // match nothing
}

// Apply --checkpoint option.
if (!apply_checkpoint_command_line_option(params))
return false;

// Apply --parameter options.
apply_parameter_command_line_options(params);

return true;
}

#if defined __APPLE__ || defined _WIN32
Expand Down Expand Up @@ -466,9 +492,7 @@ namespace
params.merge(configuration->get_parameters());

// Apply the command line options.
apply_command_line_options(project, params);

return true;
return apply_command_line_options(project, params);
}

bool is_progressive_render(const ParamArray& params)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,7 @@ namespace
SLOT(slot_changed_image_plane_sampler(const int)));

m_image_plane_sampler_passes = create_integer_input("general.passes", 1, 1000000, 1);
m_image_plane_sampler_passes->setToolTip(m_params_metadata.get_path("generic_frame_renderer.passes.help"));
m_image_plane_sampler_passes->setToolTip(m_params_metadata.get_path("passes.help"));
sublayout->addRow("Passes:", m_image_plane_sampler_passes);
}

Expand Down
10 changes: 8 additions & 2 deletions src/appleseed/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1411,21 +1411,25 @@ set (renderer_modeling_aov_sources
renderer/modeling/aov/denoiseraov.h
renderer/modeling/aov/depthaov.cpp
renderer/modeling/aov/depthaov.h
renderer/modeling/aov/diagnosticaov.cpp
renderer/modeling/aov/diagnosticaov.h
renderer/modeling/aov/diffuseaov.cpp
renderer/modeling/aov/diffuseaov.h
renderer/modeling/aov/emissionaov.cpp
renderer/modeling/aov/emissionaov.h
renderer/modeling/aov/glossyaov.cpp
renderer/modeling/aov/glossyaov.h
renderer/modeling/aov/iaovfactory.h
renderer/modeling/aov/invalidsamplesaov.cpp
renderer/modeling/aov/invalidsamplesaov.h
renderer/modeling/aov/normalaov.cpp
renderer/modeling/aov/normalaov.h
renderer/modeling/aov/npraovs.cpp
renderer/modeling/aov/npraovs.h
renderer/modeling/aov/pixelsamplecountaov.cpp
renderer/modeling/aov/pixelsamplecountaov.h
renderer/modeling/aov/pixeltimeaov.cpp
renderer/modeling/aov/pixeltimeaov.h
renderer/modeling/aov/pixelvariationaov.cpp
renderer/modeling/aov/pixelvariationaov.h
renderer/modeling/aov/positionaov.cpp
renderer/modeling/aov/positionaov.h
renderer/modeling/aov/uvaov.cpp
Expand Down Expand Up @@ -2004,6 +2008,8 @@ set (renderer_utility_sources
renderer/utility/autodeskmax.h
renderer/utility/bbox.h
renderer/utility/dynamicspectrum.h
renderer/utility/filesystem.h
renderer/utility/filesystem.cpp
renderer/utility/iostreamop.h
renderer/utility/messagecontext.cpp
renderer/utility/messagecontext.h
Expand Down
19 changes: 17 additions & 2 deletions src/appleseed/foundation/image/exrimagefilewriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "foundation/image/icanvas.h"
#include "foundation/image/pixel.h"
#include "foundation/image/tile.h"
#include "foundation/utility/string.h"

// OpenEXR headers.
#include "foundation/platform/_beginexrheaders.h"
Expand All @@ -58,6 +59,7 @@
// Standard headers.
#include <cassert>
#include <cstddef>
#include <string>
#include <vector>

using namespace Iex;
Expand All @@ -68,6 +70,14 @@ using namespace std;
namespace foundation
{

namespace
{
string generate_channel_bin_name(const size_t channel_number)
{
return string("Bin_") + pad_left(to_string(channel_number), '0', 4);
}
}

//
// EXRImageFileWriter class implementation.
//
Expand Down Expand Up @@ -138,7 +148,11 @@ Header build_header(
pixel_type = get_imf_pixel_type(props);
ChannelList channels;
for (size_t c = 0; c < channel_count; ++c)
channels.insert(channel_names[c], Channel(pixel_type));
{
channels.insert(
channel_names == nullptr ? generate_channel_bin_name(c) : channel_names[c],
Channel(pixel_type));
}

header.channels() = channels;

Expand Down Expand Up @@ -179,7 +193,7 @@ void write_tiles(
{
const char* base = tile_base + c * channel_size;
framebuffer.insert(
channel_names[c],
channel_names == nullptr ? generate_channel_bin_name(c) : channel_names[c],
Slice(
pixel_type,
const_cast<char*>(base),
Expand Down Expand Up @@ -279,6 +293,7 @@ void EXRImageFileWriter::write_multipart_exr(const char *filename)
}

delete impl;
impl = nullptr;
}

} // namespace foundation
120 changes: 118 additions & 2 deletions src/appleseed/foundation/image/genericprogressiveimagefilereader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,11 @@ struct GenericProgressiveImageFileReader::Impl
throw ExceptionIOError(OIIO::geterror().c_str());

m_supports_random_access = m_input->supports("random_access") != 0;
read_spec(m_input->spec());
}

const OIIO::ImageSpec& spec = m_input->spec();

void read_spec(const OIIO::ImageSpec& spec)
{
m_is_tiled = spec.tile_width > 0 && spec.tile_height > 0 && spec.tile_depth > 0;

size_t tile_width, tile_height;
Expand Down Expand Up @@ -139,6 +141,7 @@ struct GenericProgressiveImageFileReader::Impl
static_cast<size_t>(spec.nchannels),
pixel_format);
}

};

GenericProgressiveImageFileReader::GenericProgressiveImageFileReader(Logger* logger)
Expand Down Expand Up @@ -326,4 +329,117 @@ Tile* GenericProgressiveImageFileReader::read_tile(
}
}

void GenericProgressiveImageFileReader::read_tile(
const size_t tile_x,
const size_t tile_y,
Tile* output_tile)
{
assert(is_open());
assert(output_tile);
assert(output_tile->get_channel_count() == impl->m_props.m_channel_count);
assert(output_tile->get_pixel_format() == impl->m_props.m_pixel_format);

if (impl->m_is_tiled)
{
//
// Tiled image.
//
// In appleseed, for images whose width or height are not multiples
// of the tile's width or height, border tiles are actually smaller.
// In OpenImageIO, border tiles have the same size as other tiles,
// and the image's pixel data window defines which pixels of those
// tiles actually belong to the image.
//
// Since in appleseed we don't propagate pixel data windows through
// the whole image pipeline, we make sure here to return tiles of
// the correct dimensions, at some expenses.
//

const size_t origin_x = tile_x * impl->m_props.m_tile_width;
const size_t origin_y = tile_y * impl->m_props.m_tile_height;
const size_t tile_width = min(impl->m_props.m_tile_width, impl->m_props.m_canvas_width - origin_x);
const size_t tile_height = min(impl->m_props.m_tile_height, impl->m_props.m_canvas_height - origin_y);

// The tile fits perfectly into the canvas.
if (tile_width == impl->m_props.m_tile_width && tile_height == impl->m_props.m_tile_height)
{
assert(output_tile->get_width() == impl->m_props.m_tile_width);
assert(output_tile->get_height() == impl->m_props.m_tile_height);

if (!impl->m_input->read_tile(
static_cast<int>(origin_x),
static_cast<int>(origin_y),
0, // z
impl->m_input->spec().format,
output_tile->get_storage()))
throw ExceptionIOError(impl->m_input->geterror().c_str());
}
else
{
assert(output_tile->get_width() == tile_width);
assert(output_tile->get_height() == tile_height);

unique_ptr<Tile> source_tile(
new Tile(
impl->m_props.m_tile_width,
impl->m_props.m_tile_height,
impl->m_props.m_channel_count,
impl->m_props.m_pixel_format));

if (!impl->m_input->read_tile(
static_cast<int>(origin_x),
static_cast<int>(origin_y),
0, // z
impl->m_input->spec().format,
source_tile->get_storage()))
throw ExceptionIOError(impl->m_input->geterror().c_str());

for (size_t y = 0; y < tile_height; ++y)
{
memcpy(
output_tile->pixel(0, y),
source_tile->pixel(0, y),
tile_width * impl->m_props.m_pixel_size);
}
}
}
else
{
//
// Scanline image.
//

assert(output_tile->get_width() == impl->m_props.m_canvas_width);
assert(output_tile->get_height() == impl->m_props.m_canvas_height);

if (!impl->m_supports_random_access)
{
close();
impl->open();
}

if (!impl->m_input->read_image(
impl->m_input->spec().format,
output_tile->get_storage()))
throw ExceptionIOError(impl->m_input->geterror().c_str());
}
}

bool GenericProgressiveImageFileReader::choose_subimage(const size_t subimage) const
{
OIIO::ImageSpec spec;
const bool success = impl->m_input->seek_subimage(subimage, 0, spec);

if (success)
impl->read_spec(spec);

return success;
}

const char* GenericProgressiveImageFileReader::get_filename() const
{
assert(is_open());
return impl->m_filename.c_str();
}

} // namespace foundation
11 changes: 11 additions & 0 deletions src/appleseed/foundation/image/genericprogressiveimagefilereader.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,17 @@ class APPLESEED_DLLSYMBOL GenericProgressiveImageFileReader
const size_t tile_x,
const size_t tile_y) override;

// Read an image tile. Outputs the content in the given tile.
void read_tile(
const size_t tile_x,
const size_t tile_y,
Tile* output_tile);

bool choose_subimage(const size_t subimage) const;

// Return the path to the opened file.
const char* get_filename() const;

private:
struct Impl;
Impl* impl;
Expand Down
1 change: 1 addition & 0 deletions src/appleseed/foundation/image/image.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@


//
// This source file is part of appleseed.
// Visit https://appleseedhq.net/ for additional information and resources.
Expand Down
4 changes: 3 additions & 1 deletion src/appleseed/renderer/api/aov.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,15 @@
#include "renderer/modeling/aov/aovfactoryregistrar.h"
#include "renderer/modeling/aov/aovtraits.h"
#include "renderer/modeling/aov/depthaov.h"
#include "renderer/modeling/aov/diagnosticaov.h"
#include "renderer/modeling/aov/diffuseaov.h"
#include "renderer/modeling/aov/emissionaov.h"
#include "renderer/modeling/aov/glossyaov.h"
#include "renderer/modeling/aov/iaovfactory.h"
#include "renderer/modeling/aov/invalidsamplesaov.h"
#include "renderer/modeling/aov/normalaov.h"
#include "renderer/modeling/aov/pixelsamplecountaov.h"
#include "renderer/modeling/aov/pixeltimeaov.h"
#include "renderer/modeling/aov/pixelvariationaov.h"
#include "renderer/modeling/aov/positionaov.h"
#include "renderer/modeling/aov/uvaov.h"

Expand Down
Loading

0 comments on commit b145095

Please sign in to comment.