From 8929f443521bc113dd2f4ec3959a3d2e08f8d31b Mon Sep 17 00:00:00 2001 From: "Arthur Brainville (Ybalrid)" Date: Fri, 5 Jul 2019 23:36:33 +0200 Subject: [PATCH 1/7] Start experimental serializer --- tiny_obj_loader.h | 107 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 104 insertions(+), 3 deletions(-) diff --git a/tiny_obj_loader.h b/tiny_obj_loader.h index 62815c82..79e34690 100644 --- a/tiny_obj_loader.h +++ b/tiny_obj_loader.h @@ -546,6 +546,108 @@ class ObjReader { std::string error_; }; +// TODO move the inline implementation of this to the define below to speed up +// build times +class ObjWriter { + ObjWriter() {} + + /// Construct a writer from a reader + ObjWriter(const ObjReader &other) { + attrib_ = other.GetAttrib(); + shapes_ = other.GetShapes(); + materials_ = other.GetMaterials(); + warning_.clear(); + error_.clear(); + } + + bool SaveToString(std::string &obj_text, std::string &mlt_text) { + // Write the Obj text + std::stringstream obj_text_stream(obj_text); + obj_text_stream << "#File created by experimental tiny_obj serializer\n"; + const auto vertex_count = attrib_.vertices.size() / 3; + for (size_t v = 0; v < vertex_count; v++) { + obj_text_stream << "v "; + obj_text_stream << attrib_.vertices[3 * v + 0] << " "; + obj_text_stream << attrib_.vertices[3 * v + 1] << " "; + obj_text_stream << attrib_.vertices[3 * v + 2] << "\n"; + } + + for (size_t v = 0; v < vertex_count; v++) { + obj_text_stream << "vt "; + obj_text_stream << attrib_.texcoords[2 * v + 0] << " "; + obj_text_stream << attrib_.texcoords[2 * v + 1] << " "; + obj_text_stream << attrib_.texcoord_ws[v] << "\n"; + } + + for (size_t v = 0; v < vertex_count; v++) { + obj_text_stream << "vn "; + obj_text_stream << attrib_.normals[3 * v + 0] << " "; + obj_text_stream << attrib_.normals[3 * v + 1] << " "; + obj_text_stream << attrib_.normals[3 * v + 2] << "\n"; + } + + // faces + for (int s = 0; s < shapes_.size(); ++s) { + const auto &shape = shapes_[s]; + size_t index_offset = 0; + const auto face_count = shape.mesh.num_face_vertices.size(); + for (size_t f = 0; f < face_count; f++) { + obj_text_stream << "f "; + const auto face_vertex_count = shape.mesh.num_face_vertices[f]; + + for (size_t v = 0; v < face_vertex_count; ++v) { + index_t index = shape.mesh.indices[index_offset + v]; + obj_text_stream << index.vertex_index << "/" << index.texcoord_index + << "/" << index.normal_index << " "; + } + obj_text_stream << "\b\n"; + index_offset += face_vertex_count; + } + } + + // TODO write material + } + + bool SaveTofile(const std::string &file_path) { + std::string obj_path, mlt_path; + obj_path = mlt_path = file_path; + obj_path += ".obj"; + mlt_path += ".mlt"; + + std::string obj_text, mlt_text; + + if (!SaveToString(obj_text, mlt_text)) { + return false; + } + + std::ofstream obj_output = std::ofstream(obj_path); + std::ofstream mlt_output = std::ofstream(mlt_path); + + if (!(obj_output && mlt_output)) { + error_ = "Could not open output files " + obj_path + " " + mlt_path; + return false; + } + } + + /// + /// Warning message(may be filled after `save`) + /// + const std::string &Warning() const { return warning_; } + + /// + /// Error message(filled when `save` failed) + /// + const std::string &Error() const { return error_; } + + attrib_t attrib_; + std::vector shapes_; + std::vector materials_; + + private: + std::string warning_; + std::string error_; +}; + /// ==>>========= Legacy v1 API ============================================= /// Loads .obj from a file. @@ -616,11 +718,10 @@ bool ParseTextureNameAndOption(std::string *texname, texture_option_t *texopt, #include #include #include -#include -#include - #include +#include #include +#include namespace tinyobj { From c5f8d5ceacf75e10ad53966fe0e65d6e18353369 Mon Sep 17 00:00:00 2001 From: "Arthur Brainville (Ybalrid)" Date: Sat, 6 Jul 2019 01:30:43 +0200 Subject: [PATCH 2/7] Actually write the output file --- tiny_obj_loader.h | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/tiny_obj_loader.h b/tiny_obj_loader.h index 79e34690..28e2208c 100644 --- a/tiny_obj_loader.h +++ b/tiny_obj_loader.h @@ -549,6 +549,7 @@ class ObjReader { // TODO move the inline implementation of this to the define below to speed up // build times class ObjWriter { + public: ObjWriter() {} /// Construct a writer from a reader @@ -562,7 +563,7 @@ class ObjWriter { bool SaveToString(std::string &obj_text, std::string &mlt_text) { // Write the Obj text - std::stringstream obj_text_stream(obj_text); + std::stringstream obj_text_stream; obj_text_stream << "#File created by experimental tiny_obj serializer\n"; const auto vertex_count = attrib_.vertices.size() / 3; for (size_t v = 0; v < vertex_count; v++) { @@ -575,8 +576,8 @@ class ObjWriter { for (size_t v = 0; v < vertex_count; v++) { obj_text_stream << "vt "; obj_text_stream << attrib_.texcoords[2 * v + 0] << " "; - obj_text_stream << attrib_.texcoords[2 * v + 1] << " "; - obj_text_stream << attrib_.texcoord_ws[v] << "\n"; + obj_text_stream << attrib_.texcoords[2 * v + 1] << "\n"; + // obj_text_stream << attrib_.texcoord_ws[v] << "\n"; } for (size_t v = 0; v < vertex_count; v++) { @@ -589,23 +590,27 @@ class ObjWriter { // faces for (int s = 0; s < shapes_.size(); ++s) { const auto &shape = shapes_[s]; - size_t index_offset = 0; const auto face_count = shape.mesh.num_face_vertices.size(); + + size_t index_offset = 0; for (size_t f = 0; f < face_count; f++) { obj_text_stream << "f "; const auto face_vertex_count = shape.mesh.num_face_vertices[f]; - for (size_t v = 0; v < face_vertex_count; ++v) { index_t index = shape.mesh.indices[index_offset + v]; obj_text_stream << index.vertex_index << "/" << index.texcoord_index << "/" << index.normal_index << " "; } - obj_text_stream << "\b\n"; + obj_text_stream << "\n"; index_offset += face_vertex_count; } } + obj_text = obj_text_stream.str(); + // TODO write material + + return true; } bool SaveTofile(const std::string &file_path) { @@ -627,6 +632,11 @@ class ObjWriter { error_ = "Could not open output files " + obj_path + " " + mlt_path; return false; } + + obj_output << obj_text; + mlt_output << mlt_text; + + return true; } /// From 2fd137b98882a77b4de2d7925999796532c2a5f0 Mon Sep 17 00:00:00 2001 From: "Arthur Brainville (Ybalrid)" Date: Sun, 7 Jul 2019 16:06:52 +0200 Subject: [PATCH 3/7] Move serialzier implementation to the the "_IMPLEMENTATION" macro --- tiny_obj_loader.h | 184 ++++++++++++++++++++++++---------------------- 1 file changed, 97 insertions(+), 87 deletions(-) diff --git a/tiny_obj_loader.h b/tiny_obj_loader.h index 28e2208c..3d8df7ba 100644 --- a/tiny_obj_loader.h +++ b/tiny_obj_loader.h @@ -546,108 +546,26 @@ class ObjReader { std::string error_; }; -// TODO move the inline implementation of this to the define below to speed up -// build times class ObjWriter { public: ObjWriter() {} /// Construct a writer from a reader - ObjWriter(const ObjReader &other) { - attrib_ = other.GetAttrib(); - shapes_ = other.GetShapes(); - materials_ = other.GetMaterials(); - warning_.clear(); - error_.clear(); - } - - bool SaveToString(std::string &obj_text, std::string &mlt_text) { - // Write the Obj text - std::stringstream obj_text_stream; - obj_text_stream << "#File created by experimental tiny_obj serializer\n"; - const auto vertex_count = attrib_.vertices.size() / 3; - for (size_t v = 0; v < vertex_count; v++) { - obj_text_stream << "v "; - obj_text_stream << attrib_.vertices[3 * v + 0] << " "; - obj_text_stream << attrib_.vertices[3 * v + 1] << " "; - obj_text_stream << attrib_.vertices[3 * v + 2] << "\n"; - } - - for (size_t v = 0; v < vertex_count; v++) { - obj_text_stream << "vt "; - obj_text_stream << attrib_.texcoords[2 * v + 0] << " "; - obj_text_stream << attrib_.texcoords[2 * v + 1] << "\n"; - // obj_text_stream << attrib_.texcoord_ws[v] << "\n"; - } - - for (size_t v = 0; v < vertex_count; v++) { - obj_text_stream << "vn "; - obj_text_stream << attrib_.normals[3 * v + 0] << " "; - obj_text_stream << attrib_.normals[3 * v + 1] << " "; - obj_text_stream << attrib_.normals[3 * v + 2] << "\n"; - } - - // faces - for (int s = 0; s < shapes_.size(); ++s) { - const auto &shape = shapes_[s]; - const auto face_count = shape.mesh.num_face_vertices.size(); - - size_t index_offset = 0; - for (size_t f = 0; f < face_count; f++) { - obj_text_stream << "f "; - const auto face_vertex_count = shape.mesh.num_face_vertices[f]; - for (size_t v = 0; v < face_vertex_count; ++v) { - index_t index = shape.mesh.indices[index_offset + v]; - obj_text_stream << index.vertex_index << "/" << index.texcoord_index - << "/" << index.normal_index << " "; - } - obj_text_stream << "\n"; - index_offset += face_vertex_count; - } - } - - obj_text = obj_text_stream.str(); - - // TODO write material - - return true; - } - - bool SaveTofile(const std::string &file_path) { - std::string obj_path, mlt_path; - obj_path = mlt_path = file_path; - obj_path += ".obj"; - mlt_path += ".mlt"; - - std::string obj_text, mlt_text; - - if (!SaveToString(obj_text, mlt_text)) { - return false; - } - - std::ofstream obj_output = std::ofstream(obj_path); - std::ofstream mlt_output = std::ofstream(mlt_path); - - if (!(obj_output && mlt_output)) { - error_ = "Could not open output files " + obj_path + " " + mlt_path; - return false; - } + ObjWriter(const ObjReader &other); - obj_output << obj_text; - mlt_output << mlt_text; + bool SaveToString(std::string &obj_text, std::string &mlt_text); - return true; - } + bool SaveTofile(const std::string &file_path); /// /// Warning message(may be filled after `save`) /// - const std::string &Warning() const { return warning_; } + const std::string &Warning() const; /// /// Error message(filled when `save` failed) /// - const std::string &Error() const { return error_; } + const std::string &error() const; attrib_t attrib_; std::vector shapes_; @@ -729,8 +647,10 @@ bool ParseTextureNameAndOption(std::string *texname, texture_option_t *texopt, #include #include #include +#include #include #include +#include #include namespace tinyobj { @@ -2171,6 +2091,96 @@ bool MaterialStreamReader::operator()(const std::string &matId, return true; } +ObjWriter::ObjWriter(const ObjReader &other) { + attrib_ = other.GetAttrib(); + shapes_ = other.GetShapes(); + materials_ = other.GetMaterials(); + warning_.clear(); + error_.clear(); +} + +bool ObjWriter::SaveToString(std::string &obj_text, std::string &mlt_text) { + // Write the Obj text + std::stringstream obj_text_stream; + obj_text_stream << "#File created by experimental tiny_obj serializer\n"; + const auto vertex_count = attrib_.vertices.size() / 3; + for (size_t v = 0; v < vertex_count; v++) { + obj_text_stream << "v "; + obj_text_stream << attrib_.vertices[3 * v + 0] << " "; + obj_text_stream << attrib_.vertices[3 * v + 1] << " "; + obj_text_stream << attrib_.vertices[3 * v + 2] << "\n"; + } + + for (size_t v = 0; v < vertex_count; v++) { + obj_text_stream << "vt "; + obj_text_stream << attrib_.texcoords[2 * v + 0] << " "; + obj_text_stream << attrib_.texcoords[2 * v + 1] << "\n"; + // obj_text_stream << attrib_.texcoord_ws[v] << "\n"; + } + + for (size_t v = 0; v < vertex_count; v++) { + obj_text_stream << "vn "; + obj_text_stream << attrib_.normals[3 * v + 0] << " "; + obj_text_stream << attrib_.normals[3 * v + 1] << " "; + obj_text_stream << attrib_.normals[3 * v + 2] << "\n"; + } + + // faces + for (int s = 0; s < shapes_.size(); ++s) { + const auto &shape = shapes_[s]; + const auto face_count = shape.mesh.num_face_vertices.size(); + + size_t index_offset = 0; + for (size_t f = 0; f < face_count; f++) { + obj_text_stream << "f "; + const auto face_vertex_count = shape.mesh.num_face_vertices[f]; + for (size_t v = 0; v < face_vertex_count; ++v) { + index_t index = shape.mesh.indices[index_offset + v]; + obj_text_stream << index.vertex_index << "/" << index.texcoord_index + << "/" << index.normal_index << " "; + } + obj_text_stream << "\n"; + index_offset += face_vertex_count; + } + } + + obj_text = obj_text_stream.str(); + + // TODO write material + + return true; +} + +bool ObjWriter::SaveTofile(const std::string &file_path) { + std::string obj_path, mlt_path; + obj_path = mlt_path = file_path; + obj_path += ".obj"; + mlt_path += ".mlt"; + + std::string obj_text, mlt_text; + + if (!SaveToString(obj_text, mlt_text)) { + return false; + } + + std::ofstream obj_output = std::ofstream(obj_path); + std::ofstream mlt_output = std::ofstream(mlt_path); + + if (!(obj_output && mlt_output)) { + error_ = "Could not open output files " + obj_path + " " + mlt_path; + return false; + } + + obj_output << obj_text; + mlt_output << mlt_text; + + return true; +} + +const std::string &ObjWriter::Warning() const { return warning_; } + +const std::string &ObjWriter::error() const { return error_; } + bool LoadObj(attrib_t *attrib, std::vector *shapes, std::vector *materials, std::string *warn, std::string *err, const char *filename, const char *mtl_basedir, From 7f1677d1e8e110bbccd58ae7354180d93c927402 Mon Sep 17 00:00:00 2001 From: "Arthur Brainville (Ybalrid)" Date: Sun, 7 Jul 2019 16:15:29 +0200 Subject: [PATCH 4/7] Try to not use C++11 features --- tiny_obj_loader.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tiny_obj_loader.h b/tiny_obj_loader.h index 3d8df7ba..a381ba15 100644 --- a/tiny_obj_loader.h +++ b/tiny_obj_loader.h @@ -2103,7 +2103,7 @@ bool ObjWriter::SaveToString(std::string &obj_text, std::string &mlt_text) { // Write the Obj text std::stringstream obj_text_stream; obj_text_stream << "#File created by experimental tiny_obj serializer\n"; - const auto vertex_count = attrib_.vertices.size() / 3; + const size_t vertex_count = attrib_.vertices.size() / 3; for (size_t v = 0; v < vertex_count; v++) { obj_text_stream << "v "; obj_text_stream << attrib_.vertices[3 * v + 0] << " "; @@ -2127,13 +2127,13 @@ bool ObjWriter::SaveToString(std::string &obj_text, std::string &mlt_text) { // faces for (int s = 0; s < shapes_.size(); ++s) { - const auto &shape = shapes_[s]; - const auto face_count = shape.mesh.num_face_vertices.size(); + const shape_t &shape = shapes_[s]; + const unsigned char face_count = shape.mesh.num_face_vertices.size(); size_t index_offset = 0; for (size_t f = 0; f < face_count; f++) { obj_text_stream << "f "; - const auto face_vertex_count = shape.mesh.num_face_vertices[f]; + const unsigned char face_vertex_count = shape.mesh.num_face_vertices[f]; for (size_t v = 0; v < face_vertex_count; ++v) { index_t index = shape.mesh.indices[index_offset + v]; obj_text_stream << index.vertex_index << "/" << index.texcoord_index @@ -2163,8 +2163,8 @@ bool ObjWriter::SaveTofile(const std::string &file_path) { return false; } - std::ofstream obj_output = std::ofstream(obj_path); - std::ofstream mlt_output = std::ofstream(mlt_path); + std::ofstream obj_output = std::ofstream(obj_path.c_str()); + std::ofstream mlt_output = std::ofstream(mlt_path.c_str()); if (!(obj_output && mlt_output)) { error_ = "Could not open output files " + obj_path + " " + mlt_path; From 4ccd84f2b53eafd6f73a69c0a5d9c60b13a4b765 Mon Sep 17 00:00:00 2001 From: "Arthur Brainville (Ybalrid)" Date: Sun, 7 Jul 2019 16:20:06 +0200 Subject: [PATCH 5/7] Don't initialize/copy std::ofstream objects --- tiny_obj_loader.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tiny_obj_loader.h b/tiny_obj_loader.h index a381ba15..3596c3b9 100644 --- a/tiny_obj_loader.h +++ b/tiny_obj_loader.h @@ -2163,11 +2163,11 @@ bool ObjWriter::SaveTofile(const std::string &file_path) { return false; } - std::ofstream obj_output = std::ofstream(obj_path.c_str()); - std::ofstream mlt_output = std::ofstream(mlt_path.c_str()); + std::ofstream obj_output(obj_path.c_str()); + std::ofstream mlt_output(mlt_path.c_str()); if (!(obj_output && mlt_output)) { - error_ = "Could not open output files " + obj_path + " " + mlt_path; + error_ = "Could not open output files " + obj_path + " and/or " + mlt_path; return false; } From 42a3382ba9abd94e3fe9a7f6f38e4e9ac61e9866 Mon Sep 17 00:00:00 2001 From: "Arthur Brainville (Ybalrid)" Date: Sun, 7 Jul 2019 16:29:35 +0200 Subject: [PATCH 6/7] add some documentation comments here --- tiny_obj_loader.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tiny_obj_loader.h b/tiny_obj_loader.h index 3596c3b9..ce37ce46 100644 --- a/tiny_obj_loader.h +++ b/tiny_obj_loader.h @@ -553,8 +553,12 @@ class ObjWriter { /// Construct a writer from a reader ObjWriter(const ObjReader &other); + ///\brief Save the content of this obj asset to a pair of strings representing + /// the OBJ and MLT file contents bool SaveToString(std::string &obj_text, std::string &mlt_text); + /// Save the content to the file path + /// \param file_path The path where to save the file WITHOUT EXTENSION bool SaveTofile(const std::string &file_path); /// From 4ee81827fc1a590eb34bab9ce9c8059cb0c2d47d Mon Sep 17 00:00:00 2001 From: "Arthur Brainville (Ybalrid)" Date: Mon, 8 Jul 2019 01:24:14 +0200 Subject: [PATCH 7/7] Fix a clang warning --- tiny_obj_loader.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tiny_obj_loader.h b/tiny_obj_loader.h index ce37ce46..9d3c8739 100644 --- a/tiny_obj_loader.h +++ b/tiny_obj_loader.h @@ -2130,16 +2130,17 @@ bool ObjWriter::SaveToString(std::string &obj_text, std::string &mlt_text) { } // faces - for (int s = 0; s < shapes_.size(); ++s) { + for (size_t s = 0; s < shapes_.size(); ++s) { const shape_t &shape = shapes_[s]; - const unsigned char face_count = shape.mesh.num_face_vertices.size(); + const unsigned char face_count = + static_cast(shape.mesh.num_face_vertices.size()); size_t index_offset = 0; for (size_t f = 0; f < face_count; f++) { obj_text_stream << "f "; const unsigned char face_vertex_count = shape.mesh.num_face_vertices[f]; for (size_t v = 0; v < face_vertex_count; ++v) { - index_t index = shape.mesh.indices[index_offset + v]; + const index_t index = shape.mesh.indices[index_offset + v]; obj_text_stream << index.vertex_index << "/" << index.texcoord_index << "/" << index.normal_index << " "; } @@ -2151,6 +2152,7 @@ bool ObjWriter::SaveToString(std::string &obj_text, std::string &mlt_text) { obj_text = obj_text_stream.str(); // TODO write material + (void)mlt_text; return true; }