diff --git a/12_MeshLoaders/main.cpp b/12_MeshLoaders/main.cpp index 3a4d8b13b..b876dd7ec 100644 --- a/12_MeshLoaders/main.cpp +++ b/12_MeshLoaders/main.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2018-2020 - DevSH Graphics Programming Sp. z O.O. // This file is part of the "Nabla Engine". // For conditions of distribution and use, see copyright notice in nabla.h +#include "../3rdparty/argparse/include/argparse/argparse.hpp" #include "common.hpp" #include "../3rdparty/portable-file-dialogs/portable-file-dialogs.h" @@ -29,6 +30,24 @@ class MeshLoadersApp final : public MonoWindowApplication, public BuiltinResourc if (!device_base_t::onAppInitialized(smart_refctd_ptr(system))) return false; + // parse args + argparse::ArgumentParser parser("12_meshloaders"); + parser.add_argument("--savemesh") + .help("Save the displayed mesh on program termination to the file with specified name. Takes filename without extension as an argument") + .flag(); + + try + { + parser.parse_args({ argv.data(), argv.data() + argv.size() }); + } + catch (const std::exception& e) + { + return logFail(e.what()); + } + + if (parser["--savemesh"] == true) + m_saveMeshOnExit = true; + m_semaphore = m_device->createSemaphore(m_realFrameIx); if (!m_semaphore) return logFail("Failed to Create a Semaphore!"); @@ -176,6 +195,32 @@ class MeshLoadersApp final : public MonoWindowApplication, public BuiltinResourc return retval; } + inline bool onAppTerminated() override + { + if (m_saveMeshOnExit) + { + // make save path + static const auto prefix = std::filesystem::absolute("saved/"); + + if (!std::filesystem::exists(prefix)) + m_system->createDirectory(prefix); + + auto savePath = (prefix / path(m_modelPath).filename()).generic_string(); + + m_logger->log("Saving mesh to %S", ILogger::ELL_INFO, savePath.c_str()); + // TODO (Yas): learn how to get out the geometry from renderer and transform it into IAsset + + auto& asset = m_currentBundle.getContents()[0]; + IAssetWriter::SAssetWriteParams params{ asset.get() }; + m_assetMgr->writeAsset(savePath, params); + } + + if (!device_base_t::onAppTerminated()) + return false; + + return true; + } + protected: const video::IGPURenderpass::SCreationParams::SSubpassDependency* getDefaultSubpassDependencies() const override { @@ -249,16 +294,16 @@ class MeshLoadersApp final : public MonoWindowApplication, public BuiltinResourc //! load the geometry IAssetLoader::SAssetLoadParams params = {}; params.logger = m_logger.get(); - auto bundle = m_assetMgr->getAsset(m_modelPath,params); - if (bundle.getContents().empty()) + m_currentBundle = m_assetMgr->getAsset(m_modelPath,params); + if (m_currentBundle.getContents().empty()) return false; // core::vector> geometries; - switch (bundle.getAssetType()) + switch (m_currentBundle.getAssetType()) { case IAsset::E_TYPE::ET_GEOMETRY: - for (const auto& item : bundle.getContents()) + for (const auto& item : m_currentBundle.getContents()) if (auto polyGeo=IAsset::castDown(item); polyGeo) geometries.push_back(polyGeo); break; @@ -416,6 +461,11 @@ class MeshLoadersApp final : public MonoWindowApplication, public BuiltinResourc Camera camera = Camera(core::vectorSIMDf(0, 0, 0), core::vectorSIMDf(0, 0, 0), core::matrix4SIMD()); // mutables std::string m_modelPath; + + SAssetBundle m_currentBundle; + + std::string m_saveFileName; // NOTE: no extension + bool m_saveMeshOnExit; }; NBL_MAIN_FUNC(MeshLoadersApp) \ No newline at end of file