Skip to content

Commit

Permalink
Testing film portable text format serialization
Browse files Browse the repository at this point in the history
  • Loading branch information
Dade916 committed Mar 23, 2021
1 parent 95fe88b commit 0a04862
Show file tree
Hide file tree
Showing 42 changed files with 289 additions and 143 deletions.
16 changes: 10 additions & 6 deletions include/luxcore/luxcore.h
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,8 @@ CPP_EXPORT class CPP_API Film {
OUTPUT_AVG_SHADING_NORMAL,
OUTPUT_NOISE,
OUTPUT_USER_IMPORTANCE,
OUTPUT_CAUSTIC
OUTPUT_CAUSTIC,
OUTPUT_SERIALIZED_TEXT_FILM
} FilmOutputType;

/*!
Expand Down Expand Up @@ -312,11 +313,13 @@ CPP_EXPORT class CPP_API Film {

/*!
* \brief Loads a stand alone Film (i.e. not connected to a rendering session)
* from a file.
* from a binary or portable text format file.
*
* \param fileName is the name of the file with the serialized film to read.
* \param fileName is the name of the file with the serialized binary format film to read.
* \param useBinFormat if to use binary or portable text format file.
*/
static Film *Create(const std::string &fileName);
static Film *Create(const std::string &fileName, const bool useBinFormat = true);

/*!
* \brief Create a stand alone Film (i.e. not connected to a rendering session)
* from the properties.
Expand Down Expand Up @@ -410,11 +413,12 @@ CPP_EXPORT class CPP_API Film {
virtual void SaveOutput(const std::string &fileName, const FilmOutputType type, const luxrays::Properties &props) const = 0;

/*!
* \brief Serializes a Film in a file.
* \brief Serializes a binary or portable text format Film in a file.
*
* \param fileName is the name of the file where to serialize the film.
* \param useBinFormat if to use binary or portable text format file.
*/
virtual void SaveFilm(const std::string &fileName) const = 0;
virtual void SaveFilm(const std::string &fileName, const bool useBinFormat = true) const = 0;

/*!
* \brief Returns the total sample count.
Expand Down
4 changes: 2 additions & 2 deletions include/luxcore/luxcoreimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class RenderSessionImpl;

class FilmImpl : public Film {
public:
FilmImpl(const std::string &fileName);
FilmImpl(const std::string &fileName, const bool useBinFormat = true);
FilmImpl(const luxrays::Properties &props,
const bool hasPixelNormalizedChannel,
const bool hasScreenNormalizedChannel);
Expand All @@ -59,7 +59,7 @@ class FilmImpl : public Film {

void SaveOutputs() const;
void SaveOutput(const std::string &fileName, const FilmOutputType type, const luxrays::Properties &props) const;
void SaveFilm(const std::string &fileName) const;
void SaveFilm(const std::string &fileName, const bool useBinFormat = true) const;

double GetTotalSampleCount() const;

Expand Down
18 changes: 12 additions & 6 deletions include/luxrays/utils/serializationutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,25 @@

#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>

#include "luxrays/luxrays.h"

namespace luxrays {

typedef boost::archive::binary_oarchive LuxOutputArchive;
typedef boost::archive::binary_iarchive LuxInputArchive;
typedef boost::archive::binary_oarchive LuxOutputBinArchive;
typedef boost::archive::binary_iarchive LuxInputBinArchive;
typedef boost::archive::text_oarchive LuxOutputTextArchive;
typedef boost::archive::text_iarchive LuxInputTextArchive;

template <class T>
class SerializationOutputFile {
public:
SerializationOutputFile(const std::string &fileName);
virtual ~SerializationOutputFile();

LuxOutputArchive &GetArchive();
T &GetArchive();

bool IsGood();
std::streampos GetPosition();
Expand All @@ -67,22 +72,23 @@ class SerializationOutputFile {
private:
boost::filesystem::ofstream outFile;
boost::iostreams::filtering_ostream outStream;
LuxOutputArchive *outArchive;
T *outArchive;
};

template <class T>
class SerializationInputFile {
public:
SerializationInputFile(const std::string &fileName);
virtual ~SerializationInputFile();

LuxInputArchive &GetArchive();
T &GetArchive();

bool IsGood();

private:
boost::filesystem::ifstream inFile;
boost::iostreams::filtering_istream inStream;
LuxInputArchive *inArchive;
T *inArchive;
};

}
Expand Down
4 changes: 2 additions & 2 deletions include/slg/film/film.h
Original file line number Diff line number Diff line change
Expand Up @@ -450,8 +450,8 @@ class Film {
luxrays::HardwareDeviceKernel *mergeRADIANCE_PER_SCREEN_NORMALIZEDKernel;
luxrays::HardwareDeviceKernel *mergeFinalizeKernel;

static Film *LoadSerialized(const std::string &fileName);
static void SaveSerialized(const std::string &fileName, const Film *film);
static Film *LoadSerialized(const std::string &fileName, const bool useBinFormat);
static void SaveSerialized(const std::string &fileName, const bool useBinFormat, const Film *film);

static bool GetFilmSize(const luxrays::Properties &cfg,
u_int *filmFullWidth, u_int *filmFullHeight,
Expand Down
2 changes: 1 addition & 1 deletion include/slg/film/filmoutputs.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class FilmOutputs {
RADIANCE_GROUP, UV, RAYCOUNT, BY_MATERIAL_ID, IRRADIANCE,
OBJECT_ID, OBJECT_ID_MASK, BY_OBJECT_ID, SAMPLECOUNT,
CONVERGENCE, SERIALIZED_FILM, MATERIAL_ID_COLOR, ALBEDO, AVG_SHADING_NORMAL,
NOISE, USER_IMPORTANCE, CAUSTIC,
NOISE, USER_IMPORTANCE, CAUSTIC, SERIALIZED_TEXT_FILM,
FILMOUTPUT_TYPE_COUNT
} FilmOutputType;

Expand Down
2 changes: 1 addition & 1 deletion include/slg/rendersession.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class RenderSession {
void Resume();

void SaveFilmOutputs();
void SaveFilm(const std::string &fileName);
void SaveFilm(const std::string &fileName, const bool useBinFormat);
void SaveResumeFile(const std::string &fileName);

void CheckPeriodicSave(const bool force = false);
Expand Down
1 change: 1 addition & 0 deletions release-notes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* BIDIRCPU can now use PhotonGI caustic cache to render SDS paths
* Optimized the parsing of mesh light sources and it is now about 3x faster
* Introduced (partial) multi-thread support in pre-processing of Light sources
* Added the support for portable text film file format

### Fixed Bugs

Expand Down
6 changes: 4 additions & 2 deletions samples/luxcoreui/uimenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -338,8 +338,10 @@ void LuxCoreApp::MenuFilm() {
ImGui::Separator();
if (session && ImGui::MenuItem("Save outputs"))
session->GetFilm().SaveOutputs();
if (session && ImGui::MenuItem("Save film"))
session->GetFilm().SaveFilm("film.flm");
if (session && ImGui::MenuItem("Save binary film"))
session->GetFilm().SaveFilm("film.flm", true);
if (session && ImGui::MenuItem("Save portable (text) film"))
session->GetFilm().SaveFilm("film.pflm", false);
}

//------------------------------------------------------------------------------
Expand Down
4 changes: 2 additions & 2 deletions src/luxcore/luxcore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,10 +262,10 @@ vector<string> luxcore::GetFileNameResolverPaths() {
// Film
//------------------------------------------------------------------------------

Film *Film::Create(const std::string &fileName) {
Film *Film::Create(const std::string &fileName, const bool useBinFormat) {
API_BEGIN("{}", ToArgString(fileName));

Film *result = new luxcore::detail::FilmImpl(fileName);
Film *result = new luxcore::detail::FilmImpl(fileName, useBinFormat);

API_RETURN("{}", (void *)result);

Expand Down
18 changes: 9 additions & 9 deletions src/luxcore/luxcoreimpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ using namespace luxcore::detail;
// FilmImpl
//------------------------------------------------------------------------------

FilmImpl::FilmImpl(const std::string &fileName) : renderSession(NULL) {
standAloneFilm = slg::Film::LoadSerialized(fileName);
FilmImpl::FilmImpl(const std::string &fileName, const bool useBinFormat) : renderSession(NULL) {
standAloneFilm = slg::Film::LoadSerialized(fileName, useBinFormat);
}

FilmImpl::FilmImpl(const luxrays::Properties &props, const bool hasPixelNormalizedChannel,
Expand Down Expand Up @@ -207,13 +207,13 @@ void FilmImpl::SaveOutput(const std::string &fileName, const FilmOutputType type
API_END();
}

void FilmImpl::SaveFilm(const string &fileName) const {
void FilmImpl::SaveFilm(const string &fileName, const bool useBinFormat) const {
API_BEGIN("{}", ToArgString(fileName));

if (renderSession)
renderSession->renderSession->SaveFilm(fileName);
else
slg::Film::SaveSerialized(fileName, standAloneFilm);
if (renderSession) {
renderSession->renderSession->SaveFilm(fileName, useBinFormat);
} else
slg::Film::SaveSerialized(fileName, useBinFormat, standAloneFilm);

API_END();
}
Expand Down Expand Up @@ -1226,7 +1226,7 @@ RenderConfigImpl::RenderConfigImpl(const std::string &fileName) {

RenderConfigImpl::RenderConfigImpl(const std::string &fileName, RenderStateImpl **startState,
FilmImpl **startFilm) {
SerializationInputFile sif(fileName);
SerializationInputFile<LuxInputBinArchive> sif(fileName);

// Read the render configuration and the scene
sif.GetArchive() >> renderConfig;
Expand Down Expand Up @@ -1431,7 +1431,7 @@ RenderSessionImpl::RenderSessionImpl(const RenderConfigImpl *config, const std::
renderConfig(config) {
film = new FilmImpl(*this);

unique_ptr<slg::Film> startFilm(slg::Film::LoadSerialized(startFilmFileName));
unique_ptr<slg::Film> startFilm(slg::Film::LoadSerialized(startFilmFileName, true));
unique_ptr<slg::RenderState> startState(slg::RenderState::LoadSerialized(startStateFileName));

renderSession = new slg::RenderSession(config->renderConfig,
Expand Down
2 changes: 2 additions & 0 deletions src/luxcore/pyluxcore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1915,9 +1915,11 @@ BOOST_PYTHON_MODULE(pyluxcore) {
.value("NOISE", Film::OUTPUT_NOISE)
.value("USER_IMPORTANCE", Film::OUTPUT_USER_IMPORTANCE)
.value("CAUSTIC", Film::OUTPUT_CAUSTIC)
.value("SERIALIZED_TEXT_FILM", Film::OUTPUT_SERIALIZED_TEXT_FILM)
;

class_<luxcore::detail::FilmImpl>("Film", init<string>())
.def(init<string, bool>())
.def(init<luxrays::Properties, bool, bool>())
.def("GetWidth", &luxcore::detail::FilmImpl::GetWidth)
.def("GetHeight", &luxcore::detail::FilmImpl::GetHeight)
Expand Down
4 changes: 2 additions & 2 deletions src/luxrays/core/exttrianglemesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ ExtTriangleMesh *ExtTriangleMesh::Merge(const vector<const ExtTriangleMesh *> &m
// file of BOOST_CLASS_EXPORT_IMPLEMENT()

ExtTriangleMesh *ExtTriangleMesh::LoadSerialized(const string &fileName) {
SerializationInputFile sif(fileName);
SerializationInputFile<LuxInputBinArchive> sif(fileName);

ExtTriangleMesh *mesh;
sif.GetArchive() >> mesh;
Expand All @@ -523,7 +523,7 @@ ExtTriangleMesh *ExtTriangleMesh::LoadSerialized(const string &fileName) {
}

void ExtTriangleMesh::SaveSerialized(const string &fileName) const {
SerializationOutputFile sof(fileName);
SerializationOutputFile<LuxOutputBinArchive> sof(fileName);

const ExtTriangleMesh *mesh = this;
sof.GetArchive() << mesh;
Expand Down
47 changes: 35 additions & 12 deletions src/luxrays/utils/serializationutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,14 @@ using namespace luxrays;
// SerializationOuputFile
//------------------------------------------------------------------------------

SerializationOutputFile::SerializationOutputFile(const std::string &fileName) :
template <class T>
SerializationOutputFile<T>::SerializationOutputFile(const std::string &fileName) :
outArchive(NULL) {
outFile.exceptions(boost::filesystem::ofstream::failbit |
boost::filesystem::ofstream::badbit |
boost::filesystem::ofstream::eofbit);
// Force to use C locale
outFile.imbue(cLocale);

// The use of boost::filesystem::path is required for UNICODE support: fileName
// is supposed to be UTF-8 encoded.
Expand All @@ -41,34 +44,40 @@ SerializationOutputFile::SerializationOutputFile(const std::string &fileName) :
outStream.push(outFile);

// Use portable archive
outArchive = new LuxOutputArchive(outStream);
outArchive = new T(outStream);
}

SerializationOutputFile::~SerializationOutputFile() {
template <class T>
SerializationOutputFile<T>::~SerializationOutputFile() {
delete outArchive;
}

LuxOutputArchive &SerializationOutputFile::GetArchive() {
template <class T>
T &SerializationOutputFile<T>::GetArchive() {
return *outArchive;
}

bool SerializationOutputFile::IsGood() {
template <class T>
bool SerializationOutputFile<T>::IsGood() {
return outStream.good();
}

void SerializationOutputFile::Flush() {
template <class T>
void SerializationOutputFile<T>::Flush() {
outStream.flush();
}

std::streampos SerializationOutputFile::GetPosition() {
template <class T>
std::streampos SerializationOutputFile<T>::GetPosition() {
return outFile.tellp();
}

//------------------------------------------------------------------------------
// SerializationInputFile
//------------------------------------------------------------------------------

SerializationInputFile::SerializationInputFile(const std::string &fileName) :
template <class T>
SerializationInputFile<T>::SerializationInputFile(const std::string &fileName) :
inArchive(NULL) {
inFile.exceptions(boost::filesystem::ifstream::failbit |
boost::filesystem::ifstream::badbit |
Expand All @@ -84,18 +93,32 @@ SerializationInputFile::SerializationInputFile(const std::string &fileName) :
inStream.push(inFile);

// Use portable archive
inArchive = new LuxInputArchive(inStream);
inArchive = new T(inStream);

}

SerializationInputFile::~SerializationInputFile() {
template <class T>
SerializationInputFile<T>::~SerializationInputFile() {
delete inArchive;
}

LuxInputArchive &SerializationInputFile::GetArchive() {
template <class T>
T &SerializationInputFile<T>::GetArchive() {
return *inArchive;
}

bool SerializationInputFile::IsGood() {
template <class T>
bool SerializationInputFile<T>::IsGood() {
return inStream.good();
}

//------------------------------------------------------------------------------
// Explicit instantiations
//------------------------------------------------------------------------------

namespace luxrays {
template class SerializationOutputFile<LuxOutputBinArchive>;
template class SerializationInputFile<LuxInputBinArchive>;
template class SerializationOutputFile<LuxOutputTextArchive>;
template class SerializationInputFile<LuxInputTextArchive>;
}
11 changes: 7 additions & 4 deletions src/pyluxcoretools/pyluxcoretools/pyluxcoremerge/cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,11 @@ def LoadFilm(filmFileName, hasPixelNormalizedChannel, hasScreenNormalizedChannel
props = pyluxcore.Properties(filmFileName)
return pyluxcore.Film(props, hasPixelNormalizedChannel, hasScreenNormalizedChannel)
elif (fileExt == ".flm"):
# It is a stand alone film
return pyluxcore.Film(filmFileName)
# It is a stand alone film (binary format)
return pyluxcore.Film(filmFileName, True)
elif (fileExt == ".pflm"):
# It is a stand alone film (portable text format)
return pyluxcore.Film(filmFileName, False)
elif (fileExt == ".rsm"):
# It is a resume rendering file
(config, startState, startFilm) = pyluxcore.RenderConfig.LoadResumeFile(filmFileName)
Expand All @@ -55,7 +58,7 @@ def LuxCoreMerge(argv):
filmParser = argparse.ArgumentParser(description="Film Options", add_help=False)
# Film options
filmParser.add_argument("fileFilm",
help=".cfg, .flm or .rsm files with a film")
help=".cfg, .pflm, .flm or .rsm files with a film")
filmParser.add_argument("-p", "--pixel-normalized-channel", action = "store_true", default=False,
help = "The film will have CHANNEL_RADIANCE_PER_PIXEL_NORMALIZED (required by all render engines)")
filmParser.add_argument("-s", "--screen-normalized-channel", action = "store_true", default=False,
Expand Down Expand Up @@ -100,7 +103,7 @@ def LuxCoreMerge(argv):
aovOutput = generalArgs.aov_output[1]

# Split the arguments based of film files
filmsArgv = list(argsutils.ArgvSplitter(filmArgv, [".cfg", ".flm", ".rsm"]))
filmsArgv = list(argsutils.ArgvSplitter(filmArgv, [".cfg", ".pflm", ".flm", ".rsm"]))
if not filmsArgv:
generalParser.print_help()
filmParser.print_help()
Expand Down
Loading

0 comments on commit 0a04862

Please sign in to comment.