From f3fc5769e85557ba3406e70b8b51c57d918d1472 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 28 Nov 2017 16:51:53 -0800 Subject: [PATCH] Move asset baking on asset server to separate process --- .../src/assets/BakeAssetTask.cpp | 69 +++++++++++++++++-- assignment-client/src/assets/BakeAssetTask.h | 2 + .../src/RenderableModelEntityItem.cpp | 2 +- tools/oven/CMakeLists.txt | 2 +- tools/oven/src/BakerCLI.cpp | 29 +++++--- tools/oven/src/BakerCLI.h | 12 +++- tools/oven/src/Oven.cpp | 7 +- tools/oven/src/ui/BakeWidget.h | 1 + 8 files changed, 105 insertions(+), 19 deletions(-) diff --git a/assignment-client/src/assets/BakeAssetTask.cpp b/assignment-client/src/assets/BakeAssetTask.cpp index 6c78d2baf3..ca96a0d36c 100644 --- a/assignment-client/src/assets/BakeAssetTask.cpp +++ b/assignment-client/src/assets/BakeAssetTask.cpp @@ -12,16 +12,23 @@ #include "BakeAssetTask.h" #include +#include #include #include #include +static const int OVEN_STATUS_CODE_SUCCESS { 0 }; +static const int OVEN_STATUS_CODE_FAIL { 1 }; +static const int OVEN_STATUS_CODE_ABORT { 2 }; + BakeAssetTask::BakeAssetTask(const AssetHash& assetHash, const AssetPath& assetPath, const QString& filePath) : _assetHash(assetHash), _assetPath(assetPath), _filePath(filePath) { + qRegisterMetaType("QProcess::ProcessError"); + qRegisterMetaType("QProcess::ExitStatus"); } @@ -43,22 +50,74 @@ void cleanupTempFiles(QString tempOutputDir, std::vector files) { void BakeAssetTask::run() { _isBaking.store(true); + QString tempOutputDir = PathUtils::generateTemporaryDir(); + _outputDir = tempOutputDir; + auto base = QFileInfo(QCoreApplication::applicationFilePath()).absoluteDir(); + QString path = base.absolutePath() + "/../../tools/oven/RelWithDebInfo/oven.exe"; + path = base.absolutePath() + "/../tools/oven/oven"; + //path = "C:/Users/huffm/dev/hifi/build17/tools/oven/RelWithDebInfo/oven.exe"; + QString extension = _assetPath.mid(_assetPath.lastIndexOf('.') + 1); + QStringList args { + "-i", _filePath, + "-o", tempOutputDir, + "-t", extension, + }; + + qDebug().noquote() << "Path: " << path << args.join(' '); + QProcess* proc = new QProcess(); + + connect(proc, static_cast(&QProcess::finished), + this, [this, proc, tempOutputDir](int exitCode, QProcess::ExitStatus exitStatus) { + qDebug() << "Finished process: " << exitCode << exitStatus; + qDebug() << "stdout: " << proc->readAllStandardOutput(); + + auto files = _outputDir.entryInfoList(QDir::Files); + QVector outputFiles; + for (auto& file : files) { + qDebug() << "Output file: " << file.absoluteFilePath(); + outputFiles.push_back(file.absoluteFilePath()); + } + + if (exitCode == OVEN_STATUS_CODE_SUCCESS) { + emit bakeComplete(_assetHash, _assetPath, tempOutputDir, outputFiles); + } else if (exitCode == OVEN_STATUS_CODE_ABORT) { + emit bakeAborted(_assetHash, _assetPath); + } else { + QString errors; + if (exitCode == OVEN_STATUS_CODE_FAIL) { + } + emit bakeFailed(_assetHash, _assetPath, errors); + } + + }); + connect(proc, &QProcess::errorOccurred, this, []() { + qDebug() << "Error occurred :("; + }); + connect(proc, &QProcess::started, this, []() { + qDebug() << "Process started"; + }); + + qDebug() << "Starting process!"; + proc->start(path, args, QIODevice::ReadOnly); + proc->waitForStarted(); + qDebug() << "Started"; + proc->waitForFinished(); + qDebug() << "Finished"; + + return; + qRegisterMetaType >("QVector"); TextureBakerThreadGetter fn = []() -> QThread* { return QThread::currentThread(); }; - QString tempOutputDir; - if (_assetPath.endsWith(".fbx")) { - tempOutputDir = PathUtils::generateTemporaryDir(); _baker = std::unique_ptr { new FBXBaker(QUrl("file:///" + _filePath), fn, tempOutputDir) }; } else if (_assetPath.endsWith(".js", Qt::CaseInsensitive)) { _baker = std::unique_ptr{ - new JSBaker(QUrl("file:///" + _filePath), PathUtils::generateTemporaryDir()) + new JSBaker(QUrl("file:///" + _filePath), tempOutputDir) }; } else { - tempOutputDir = PathUtils::generateTemporaryDir(); _baker = std::unique_ptr { new TextureBaker(QUrl("file:///" + _filePath), image::TextureUsage::CUBE_TEXTURE, tempOutputDir) diff --git a/assignment-client/src/assets/BakeAssetTask.h b/assignment-client/src/assets/BakeAssetTask.h index 90458ac223..48461bc1b3 100644 --- a/assignment-client/src/assets/BakeAssetTask.h +++ b/assignment-client/src/assets/BakeAssetTask.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -44,6 +45,7 @@ private: AssetHash _assetHash; AssetPath _assetPath; QString _filePath; + QDir _outputDir; std::unique_ptr _baker; std::atomic _wasAborted { false }; std::atomic _didFinish { false }; diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 06b81ff428..c992eb5dc4 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -1149,7 +1149,7 @@ bool ModelEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoin if (model && model->isLoaded()) { if (!entity->_dimensionsInitialized || entity->_needsInitialSimulation) { return true; - } + } // Check to see if we need to update the model bounds if (entity->needsUpdateModelBounds()) { diff --git a/tools/oven/CMakeLists.txt b/tools/oven/CMakeLists.txt index 1022c204c5..fd027c40fe 100644 --- a/tools/oven/CMakeLists.txt +++ b/tools/oven/CMakeLists.txt @@ -17,4 +17,4 @@ if (UNIX) endif() endif () -set_target_properties(${TARGET_NAME} PROPERTIES EXCLUDE_FROM_ALL TRUE EXCLUDE_FROM_DEFAULT_BUILD TRUE) +set_target_properties(${TARGET_NAME} PROPERTIES EXCLUDE_FROM_ALL FALSE EXCLUDE_FROM_DEFAULT_BUILD FALSE) diff --git a/tools/oven/src/BakerCLI.cpp b/tools/oven/src/BakerCLI.cpp index 5ab995be95..01276c34c8 100644 --- a/tools/oven/src/BakerCLI.cpp +++ b/tools/oven/src/BakerCLI.cpp @@ -22,22 +22,28 @@ BakerCLI::BakerCLI(Oven* parent) : QObject(parent) { } -void BakerCLI::bakeFile(QUrl inputUrl, const QString outputPath) { +void BakerCLI::bakeFile(QUrl inputUrl, const QString& outputPath, const QString& type) { // if the URL doesn't have a scheme, assume it is a local file if (inputUrl.scheme() != "http" && inputUrl.scheme() != "https" && inputUrl.scheme() != "ftp") { inputUrl.setScheme("file"); } - static const QString MODEL_EXTENSION { ".fbx" }; + qDebug() << "Type: " << type; + + static const QString MODEL_EXTENSION { "fbx" }; + + QString extension = type; + + if (extension.isNull()) { + auto url = inputUrl.toDisplayString(); + extension = url.mid(url.lastIndexOf('.')); + } // check what kind of baker we should be creating - bool isFBX = inputUrl.toDisplayString().endsWith(MODEL_EXTENSION, Qt::CaseInsensitive); - bool isSupportedImage = false; + bool isFBX = extension == MODEL_EXTENSION;//inputUrl.toDisplayString().endsWith(MODEL_EXTENSION, Qt::CaseInsensitive); - for (QByteArray format : QImageReader::supportedImageFormats()) { - isSupportedImage |= inputUrl.toDisplayString().endsWith(format, Qt::CaseInsensitive); - } + bool isSupportedImage = QImageReader::supportedImageFormats().contains(extension.toLatin1()); // create our appropiate baker if (isFBX) { @@ -60,5 +66,12 @@ void BakerCLI::bakeFile(QUrl inputUrl, const QString outputPath) { void BakerCLI::handleFinishedBaker() { qCDebug(model_baking) << "Finished baking file."; - QApplication::exit(_baker.get()->hasErrors()); + int exitCode = OVEN_STATUS_CODE_SUCCESS; + // Do we need this? + if (_baker.get()->wasAborted()) { + exitCode = OVEN_STATUS_CODE_ABORT; + } else if (_baker.get()->hasErrors()) { + exitCode = OVEN_STATUS_CODE_FAIL; + } + QApplication::exit(exitCode); } diff --git a/tools/oven/src/BakerCLI.h b/tools/oven/src/BakerCLI.h index cb2b908059..a6d96cab9b 100644 --- a/tools/oven/src/BakerCLI.h +++ b/tools/oven/src/BakerCLI.h @@ -14,15 +14,23 @@ #include +#include + #include "Baker.h" #include "Oven.h" +static const int OVEN_STATUS_CODE_SUCCESS { 0 }; +static const int OVEN_STATUS_CODE_FAIL { 1 }; +static const int OVEN_STATUS_CODE_ABORT { 2 }; + +static const QString OVEN_ERROR_FILENAME = "errors.txt"; + class BakerCLI : public QObject { Q_OBJECT public: BakerCLI(Oven* parent); - void bakeFile(QUrl inputUrl, const QString outputPath); + void bakeFile(QUrl inputUrl, const QString& outputPath, const QString& type = QString::null); private slots: void handleFinishedBaker(); @@ -31,4 +39,4 @@ private: std::unique_ptr _baker; }; -#endif // hifi_BakerCLI_h \ No newline at end of file +#endif // hifi_BakerCLI_h diff --git a/tools/oven/src/Oven.cpp b/tools/oven/src/Oven.cpp index d91206a592..9de06a35bb 100644 --- a/tools/oven/src/Oven.cpp +++ b/tools/oven/src/Oven.cpp @@ -24,6 +24,7 @@ static const QString OUTPUT_FOLDER = "/Users/birarda/code/hifi/lod/test-oven/exp static const QString CLI_INPUT_PARAMETER = "i"; static const QString CLI_OUTPUT_PARAMETER = "o"; +static const QString CLI_TYPE_PARAMETER = "t"; Oven::Oven(int argc, char* argv[]) : QApplication(argc, argv) @@ -39,7 +40,8 @@ Oven::Oven(int argc, char* argv[]) : parser.addOptions({ { CLI_INPUT_PARAMETER, "Path to file that you would like to bake.", "input" }, - { CLI_OUTPUT_PARAMETER, "Path to folder that will be used as output.", "output" } + { CLI_OUTPUT_PARAMETER, "Path to folder that will be used as output.", "output" }, + { CLI_TYPE_PARAMETER, "Type of asset.", "type" } }); parser.addHelpOption(); parser.process(*this); @@ -59,7 +61,8 @@ Oven::Oven(int argc, char* argv[]) : BakerCLI* cli = new BakerCLI(this); QUrl inputUrl(QDir::fromNativeSeparators(parser.value(CLI_INPUT_PARAMETER))); QUrl outputUrl(QDir::fromNativeSeparators(parser.value(CLI_OUTPUT_PARAMETER))); - cli->bakeFile(inputUrl, outputUrl.toString()); + QString type = parser.isSet(CLI_TYPE_PARAMETER) ? parser.value(CLI_TYPE_PARAMETER) : QString::null; + cli->bakeFile(inputUrl, outputUrl.toString(), type); } else { parser.showHelp(); QApplication::quit(); diff --git a/tools/oven/src/ui/BakeWidget.h b/tools/oven/src/ui/BakeWidget.h index 00996128ed..d71bd71252 100644 --- a/tools/oven/src/ui/BakeWidget.h +++ b/tools/oven/src/ui/BakeWidget.h @@ -13,6 +13,7 @@ #define hifi_BakeWidget_h #include +#include #include