Skip to content

--savemesh argument in example 12 #207

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
5 changes: 4 additions & 1 deletion 12_MeshLoaders/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,7 @@ endif()
# TODO; Arek I removed `NBL_EXECUTABLE_PROJECT_CREATION_PCH_TARGET` from the last parameter here, doesn't this macro have 4 arguments anyway !?
nbl_create_executable_project("" "" "${NBL_INCLUDE_SERACH_DIRECTORIES}" "${NBL_LIBRARIES}")
# TODO: Arek temporarily disabled cause I haven't figured out how to make this target yet
# LINK_BUILTIN_RESOURCES_TO_TARGET(${EXECUTABLE_NAME} nblExamplesGeometrySpirvBRD)
# LINK_BUILTIN_RESOURCES_TO_TARGET(${EXECUTABLE_NAME} nblExamplesGeometrySpirvBRD)

add_dependencies(${EXECUTABLE_NAME} argparse)
target_include_directories(${EXECUTABLE_NAME} PUBLIC $<TARGET_PROPERTY:argparse,INTERFACE_INCLUDE_DIRECTORIES>)
92 changes: 88 additions & 4 deletions 12_MeshLoaders/main.cpp
Original file line number Diff line number Diff line change
@@ -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 "argparse/argparse.hpp"
#include "common.hpp"

#include "../3rdparty/portable-file-dialogs/portable-file-dialogs.h"
Expand Down Expand Up @@ -29,6 +30,41 @@ 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 mesh on exit or reload")
.flag();

parser.add_argument("--savepath")
.nargs(1)
.help("Specify the file to which the mesh will be saved");

try
{
parser.parse_args({ argv.data(), argv.data() + argv.size() });
}
catch (const std::exception& e)
{
return logFail(e.what());
}

if (parser["--savemesh"] == true)
m_saveGeomOnExit = true;

if (parser.present("--savepath"))
{
auto tmp = path(parser.get<std::string>("--savepath"));

if (tmp.empty() || !tmp.has_filename())
return logFail("Invalid path has been specified in --savepath argument");

if (!std::filesystem::exists(tmp.parent_path()))
return logFail("Path specified in --savepath argument doesn't exist");

m_geomSavePath.emplace(std::move(tmp));
}

m_semaphore = m_device->createSemaphore(m_realFrameIx);
if (!m_semaphore)
return logFail("Failed to Create a Semaphore!");
Expand Down Expand Up @@ -176,6 +212,17 @@ class MeshLoadersApp final : public MonoWindowApplication, public BuiltinResourc
return retval;
}

inline bool onAppTerminated() override
{
if (m_saveGeomOnExit && m_currentGeom)
writeGeometry();

if (!device_base_t::onAppTerminated())
return false;

return true;
}

protected:
const video::IGPURenderpass::SCreationParams::SSubpassDependency* getDefaultSubpassDependencies() const override
{
Expand Down Expand Up @@ -222,6 +269,8 @@ class MeshLoadersApp final : public MonoWindowApplication, public BuiltinResourc

bool reloadModel()
{
m_currentGeom = nullptr;

if (m_nonInteractiveTest) // TODO: maybe also take from argv and argc
m_modelPath = (sharedInputCWD/"ply/Spanner-ply.ply").string();
else
Expand All @@ -241,6 +290,9 @@ class MeshLoadersApp final : public MonoWindowApplication, public BuiltinResourc
m_modelPath = file.result()[0];
}

if (m_saveGeomOnExit && m_currentGeom)
writeGeometry();

// free up
m_renderer->m_instances.clear();
m_renderer->clearGeometries({.semaphore=m_semaphore.get(),.value=m_realFrameIx});
Expand All @@ -249,16 +301,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())
auto asset = m_assetMgr->getAsset(m_modelPath,params);
if (asset.getContents().empty())
return false;

//
core::vector<smart_refctd_ptr<const ICPUPolygonGeometry>> geometries;
switch (bundle.getAssetType())
switch (asset.getAssetType())
{
case IAsset::E_TYPE::ET_GEOMETRY:
for (const auto& item : bundle.getContents())
for (const auto& item : asset.getContents())
if (auto polyGeo=IAsset::castDown<ICPUPolygonGeometry>(item); polyGeo)
geometries.push_back(polyGeo);
break;
Expand All @@ -269,6 +321,8 @@ class MeshLoadersApp final : public MonoWindowApplication, public BuiltinResourc
if (geometries.empty())
return false;

m_currentGeom = geometries[0];

using aabb_t = hlsl::shapes::AABB<3,double>;
auto printAABB = [&](const aabb_t& aabb, const char* extraMsg="")->void
{
Expand Down Expand Up @@ -401,6 +455,31 @@ class MeshLoadersApp final : public MonoWindowApplication, public BuiltinResourc
return true;
}

void writeGeometry()
{
if (!m_geomSavePath.has_value())
m_geomSavePath = pfd::save_file("Save Geometry", localOutputCWD.string(),
{ "All Supported Formats (.stl, .ply, .serialized)", "*.stl *.ply *.serialized" },
pfd::opt::force_overwrite
).result();

auto& dest = m_geomSavePath.value();

if (dest.empty())
{
m_logger->log("Invalid path has been selected. Geometry won't be saved.", ILogger::ELL_ERROR);
return;
}

m_logger->log("Saving mesh to %S", ILogger::ELL_INFO, dest.c_str());

// should I do a const cast here?
const IAsset* asset = m_currentGeom.get();
IAssetWriter::SAssetWriteParams params{ const_cast<IAsset*>(asset) };
m_assetMgr->writeAsset(dest.string(), params);
m_currentGeom = nullptr;
}

// Maximum frames which can be simultaneously submitted, used to cycle through our per-frame resources like command buffers
constexpr static inline uint32_t MaxFramesInFlight = 3u;
//
Expand All @@ -416,6 +495,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;

smart_refctd_ptr<const ICPUPolygonGeometry> m_currentGeom;

bool m_saveGeomOnExit;
std::optional<nbl::system::path> m_geomSavePath;
};

NBL_MAIN_FUNC(MeshLoadersApp)