diff --git a/openVulkanoCpp/Scene/MeshWriter.cpp b/openVulkanoCpp/Scene/MeshWriter.cpp index 28a7277..d8466bf 100644 --- a/openVulkanoCpp/Scene/MeshWriter.cpp +++ b/openVulkanoCpp/Scene/MeshWriter.cpp @@ -24,8 +24,8 @@ namespace OpenVulkano::Scene if (!file.is_open()) throw std::runtime_error("Failed to open file '" + filePath + "' for writing!"); - auto [objContents, mtlContents] = GetObjContents(geometry, ""); - file << objContents; + std::stringstream dummy; + WriteObjContents(geometry, "", file, dummy); file.close(); } @@ -34,8 +34,7 @@ namespace OpenVulkano::Scene std::ofstream file(filePath); if (!file.is_open()) throw std::runtime_error("Failed to open file '" + filePath + "' for writing!"); - std::string scene = GetUsdContents(geometry); - file << scene << "\n"; + WriteUsdContents(file, geometry); file.close(); } @@ -43,13 +42,14 @@ namespace OpenVulkano::Scene { OpenVulkano::ArchiveWriter zipWriter(zipPath.c_str()); - auto [objContents, mtlContents] = GetObjContents(geometry, texturePath); + std::stringstream objContents, mtlContents; + WriteObjContents(geometry, texturePath, objContents, mtlContents); - auto objDesc = OpenVulkano::FileDescription::MakeDescriptionForFile("model.obj", objContents.size()); - zipWriter.AddFile(objDesc, objContents.data()); + auto objDesc = OpenVulkano::FileDescription::MakeDescriptionForFile("model.obj", objContents.str().size()); + zipWriter.AddFile(objDesc, objContents.str().data()); - auto mtlDesc = OpenVulkano::FileDescription::MakeDescriptionForFile("material.mtl", mtlContents.size()); - zipWriter.AddFile(mtlDesc, mtlContents.data()); + auto mtlDesc = OpenVulkano::FileDescription::MakeDescriptionForFile("material.mtl", mtlContents.str().size()); + zipWriter.AddFile(mtlDesc, mtlContents.str().data()); if (!texturePath.empty() && std::filesystem::exists(texturePath)) { @@ -63,9 +63,10 @@ namespace OpenVulkano::Scene { OpenVulkano::ZipWriter zipWriter(usdzPath); - std::string usd = GetUsdContents(geometry, texturePath); - auto usdDesc = OpenVulkano::FileDescription::MakeDescriptionForFile("geometry.usda", usd.size()); - zipWriter.AddFile(usdDesc, usd.data()); + std::stringstream usdFile; + WriteUsdContents(usdFile, geometry); + auto usdDesc = OpenVulkano::FileDescription::MakeDescriptionForFile("geometry.usda", usdFile.str().size()); + zipWriter.AddFile(usdDesc, usdFile.str().data()); if (!texturePath.empty() && std::filesystem::exists(texturePath)) { @@ -73,7 +74,5 @@ namespace OpenVulkano::Scene auto texDesc = OpenVulkano::FileDescription::MakeDescriptionForFile("texture.png", textureFile.Size()); zipWriter.AddFile(texDesc, textureFile.Data()); } - - zipWriter.Close(); } } \ No newline at end of file diff --git a/openVulkanoCpp/Scene/ObjEncoder.hpp b/openVulkanoCpp/Scene/ObjEncoder.hpp index 8bd6311..6323288 100644 --- a/openVulkanoCpp/Scene/ObjEncoder.hpp +++ b/openVulkanoCpp/Scene/ObjEncoder.hpp @@ -14,30 +14,22 @@ namespace OpenVulkano::Scene { - // Returns [objContents, mtlContents] - std::pair GetObjContents(Geometry* geometry, const std::string& texturePath) + void WriteObjContents(Geometry* geometry, const std::string& texturePath, std::ostream& objContent, std::ostream& mtlContent) { - std::pair result; - bool useTexture = texturePath.size() != 0; - std::stringstream objContent; objContent << "# OBJ file generated by OpenVulkanoCpp\n"; if (useTexture) { - std::stringstream mtlContent; - std::string materialName = "Material0"; - mtlContent << "newmtl " << materialName << R"( + mtlContent << R"(newmtl Material0 Ka 1.000 1.000 1.000 Kd 1.000 1.000 1.000 Ks 0.000 0.000 0.000 map_Ka texture.png map_Kd texture.png )"; - objContent << "mtllib material.mtl\nusemtl " << materialName << "\n"; - - result.second = mtlContent.str(); + objContent << "mtllib material.mtl\nusemtl Material0\n"; } for (int i = 0; i < geometry->vertexCount; ++i) @@ -62,9 +54,5 @@ map_Kd texture.png uint32_t i2 = geometry->GetIndex(i + 2) + 1; objContent << fmt::format("f {0}/{0}/{0} {1}/{1}/{1} {2}/{2}/{2}\n", i0, i1, i2); } - - result.first = objContent.str(); - - return result; } } \ No newline at end of file diff --git a/openVulkanoCpp/Scene/UsdEncoder.hpp b/openVulkanoCpp/Scene/UsdEncoder.hpp index 429ceed..de1235f 100644 --- a/openVulkanoCpp/Scene/UsdEncoder.hpp +++ b/openVulkanoCpp/Scene/UsdEncoder.hpp @@ -11,56 +11,9 @@ namespace OpenVulkano::Scene { - std::string GetUsdContents(OpenVulkano::Scene::Geometry* geometry, const std::string texturePath = "") + void WriteUsdContents(std::ostream& output, OpenVulkano::Scene::Geometry* geometry) { - std::ostringstream result; - std::ostringstream points, normals, indices, texCoords, faceCounts; - points << std::fixed << std::setprecision(6); - normals << std::fixed << std::setprecision(6); - - for (size_t i = 0; i < geometry->vertexCount; ++i) - { - const auto& v = geometry->vertices[i]; - points << "(" << v.position.x << ", " << v.position.y << ", " << v.position.z << ")"; - normals << "(" << v.normal.x << ", " << v.normal.y << ", " << v.normal.z << ")"; - if (i < geometry->vertexCount - 1) - { - points << ", "; - normals << ", "; - } - } - - for (size_t i = 0; i < geometry->indexCount; ++i) - { - indices << geometry->GetIndex(i); - if (i < geometry->indexCount - 1) - { - indices << ", "; - } - if ((i + 1) % 3 == 0) - { - faceCounts << "3"; - if (i < geometry->indexCount - 1) - { - faceCounts << ", "; - } - } - } - - texCoords << std::fixed << std::setprecision(6); - - for (size_t i = 0; i < geometry->indexCount; ++i) - { - const size_t vertexIndex = geometry->GetIndex(i); - const auto& v = geometry->vertices[vertexIndex]; - texCoords << "(" << v.textureCoordinates.x << ", " << v.textureCoordinates.y << ")"; - if (i < geometry->indexCount - 1) - { - texCoords << ", "; - } - } - - result << R"(#usda 1.0 + output << R"(#usda 1.0 ( defaultPrim = "root" doc = "Exported from OpenVulkano" @@ -91,19 +44,79 @@ def Xform "root" ( { uniform bool doubleSided = 1 float3[] extent = [(-0.5, -0.5, 0), (0.5, 0.5, 0)] - int[] faceVertexCounts = [)" - << faceCounts.str() << R"(] - int[] faceVertexIndices = [)" - << indices.str() << R"(] + int[] faceVertexCounts = [)"; + + for (size_t i = 0; i < geometry->indexCount; ++i) + { + if ((i + 1) % 3 == 0) + { + output << "3"; + if (i < geometry->indexCount - 1) + { + output << ", "; + } + } + } + + output << R"(] + int[] faceVertexIndices = [)"; + + for (size_t i = 0; i < geometry->indexCount; ++i) + { + output << geometry->GetIndex(i); + if (i < geometry->indexCount - 1) + { + output << ", "; + } + } + + output << R"(] rel material:binding = - normal3f[] normals = [)" - << normals.str() << R"(] ( + normal3f[] normals = [)"; + + output << std::fixed << std::setprecision(6); + for (size_t i = 0; i < geometry->vertexCount; ++i) + { + const auto& v = geometry->vertices[i]; + output << "(" << v.normal.x << ", " << v.normal.y << ", " << v.normal.z << ")"; + if (i < geometry->vertexCount - 1) + { + output << ", "; + } + } + + output << R"(] ( interpolation = "faceVarying" ) - point3f[] points = [)" - << points.str() << R"(] - texCoord2f[] primvars:st = [)" - << texCoords.str() << R"(] ( + point3f[] points = [)"; + + for (size_t i = 0; i < geometry->vertexCount; ++i) + { + const auto& v = geometry->vertices[i]; + output << "(" << v.position.x << ", " << v.position.y << ", " << v.position.z << ")"; + if (i < geometry->vertexCount - 1) + { + output << ", "; + } + } + + output << R"(] + texCoord2f[] primvars:st = [)"; + + output << std::fixed << std::setprecision(6); + + for (size_t i = 0; i < geometry->indexCount; ++i) + { + const size_t vertexIndex = geometry->GetIndex(i); + const auto& v = geometry->vertices[vertexIndex]; + output << "(" << v.textureCoordinates.x << ", " << v.textureCoordinates.y << ")"; + if (i < geometry->indexCount - 1) + { + output << ", "; + } + } + + output << R"(] ( interpolation = "faceVarying" ) uniform token subdivisionScheme = "none" @@ -153,6 +166,5 @@ def Xform "root" ( } } )"; - return result.str(); } } \ No newline at end of file diff --git a/tests/IO/Archive/ZipWriterTest.cpp b/tests/IO/Archive/ZipWriterTest.cpp index fffa270..6b70d21 100644 --- a/tests/IO/Archive/ZipWriterTest.cpp +++ b/tests/IO/Archive/ZipWriterTest.cpp @@ -19,8 +19,9 @@ using namespace OpenVulkano; TEST_CASE("Empty zip file", "[ZipWriter]") { const auto emptyZipPath = AppFolders::GetAppTempDir() / "empty.zip"; - ZipWriter writer(emptyZipPath); - writer.Close(); + { + ZipWriter writer(emptyZipPath); + } auto mem = Utils::ReadFile(emptyZipPath); const int expectSize = 22; Array expect = {0x50, 0x4b, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; @@ -34,15 +35,17 @@ TEST_CASE("Empty zip file", "[ZipWriter]") TEST_CASE("Zip with one file(AAA.txt that has 'AAA')", "[ZipWriter]") { const auto oneFileZipPath = AppFolders::GetAppTempDir() / "one_file.zip"; - ZipWriter writer(oneFileZipPath); + + { + ZipWriter writer(oneFileZipPath); - FileDescription desc = FileDescription::MakeDescriptionForFile("AAA.txt", 3); - desc.modTime = {}; - desc.createTime = {}; - char buffer[] = {'A', 'A', 'A'}; + FileDescription desc = FileDescription::MakeDescriptionForFile("AAA.txt", 3); + desc.modTime = {}; + desc.createTime = {}; + char buffer[] = {'A', 'A', 'A'}; - writer.AddFile(desc, buffer); - writer.Close(); + writer.AddFile(desc, buffer); + } auto mem = Utils::ReadFile(oneFileZipPath); @@ -67,21 +70,22 @@ TEST_CASE("Zip with one file(AAA.txt that has 'AAA')", "[ZipWriter]") TEST_CASE("Zip with two files(AAA.txt that has 'AAA', BBB.bin that has 'BBB')", "[ZipWriter]") { const auto twoFilesZipPath = AppFolders::GetAppTempDir() / "two_files.zip"; - ZipWriter writer(twoFilesZipPath); + { + ZipWriter writer(twoFilesZipPath); - FileDescription aaa = FileDescription::MakeDescriptionForFile("AAA.txt", 3); - aaa.modTime = {}; - aaa.createTime = {}; - char aaaBuffer[] = {'A', 'A', 'A'}; + FileDescription aaa = FileDescription::MakeDescriptionForFile("AAA.txt", 3); + aaa.modTime = {}; + aaa.createTime = {}; + char aaaBuffer[] = {'A', 'A', 'A'}; - FileDescription bbb = FileDescription::MakeDescriptionForFile("BBB.bin", 3); - bbb.modTime = {}; - bbb.createTime = {}; - char bbbBuffer[] = {'B', 'B', 'B'}; + FileDescription bbb = FileDescription::MakeDescriptionForFile("BBB.bin", 3); + bbb.modTime = {}; + bbb.createTime = {}; + char bbbBuffer[] = {'B', 'B', 'B'}; - writer.AddFile(aaa, aaaBuffer); - writer.AddFile(bbb, bbbBuffer); - writer.Close(); + writer.AddFile(aaa, aaaBuffer); + writer.AddFile(bbb, bbbBuffer); + } auto mem = Utils::ReadFile(twoFilesZipPath);