From e75f17a7f9bedfdfde1ca8c102d0937b358c7b46 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 5 Apr 2017 18:10:52 -0700 Subject: [PATCH] add a TextureBaker called from the FBXBaker --- libraries/model-baking/src/FBXBaker.cpp | 47 +++-------- libraries/model-baking/src/FBXBaker.h | 13 +-- .../src/ModelBakingLoggingCategory.cpp | 14 ++++ .../src/ModelBakingLoggingCategory.h | 19 +++++ libraries/model-baking/src/TextureBaker.cpp | 79 +++++++++++++++++++ libraries/model-baking/src/TextureBaker.h | 43 ++++++++++ 6 files changed, 175 insertions(+), 40 deletions(-) create mode 100644 libraries/model-baking/src/ModelBakingLoggingCategory.cpp create mode 100644 libraries/model-baking/src/ModelBakingLoggingCategory.h create mode 100644 libraries/model-baking/src/TextureBaker.cpp create mode 100644 libraries/model-baking/src/TextureBaker.h diff --git a/libraries/model-baking/src/FBXBaker.cpp b/libraries/model-baking/src/FBXBaker.cpp index 6717cbf69e..3370698738 100644 --- a/libraries/model-baking/src/FBXBaker.cpp +++ b/libraries/model-baking/src/FBXBaker.cpp @@ -16,9 +16,11 @@ #include +#include "ModelBakingLoggingCategory.h" +#include "TextureBaker.h" + #include "FBXBaker.h" -Q_LOGGING_CATEGORY(model_baking, "hifi.model-baking"); FBXBaker::FBXBaker(QUrl fbxURL, QString baseOutputPath) : _fbxURL(fbxURL), @@ -143,15 +145,12 @@ void FBXBaker::handleFBXNetworkReply() { void FBXBaker::bake() { // (1) load the scene from the FBX file - // (2) enumerate the textures found in the scene and bake them + // (2) enumerate the textures found in the scene and start a bake for them // (3) export the FBX with re-written texture references - // (4) enumerate the collected texture paths and bake the textures - // a failure at any step along the way stops the chain - importScene() && rewriteAndCollectSceneTextures() && exportScene() && bakeTextures() && removeEmbeddedMediaFolder(); - - // emit a signal saying that we are done, with whatever errors were produced - emit finished(); + importScene(); + rewriteAndBakeSceneTextures(); + exportScene(); } bool FBXBaker::importScene() { @@ -187,7 +186,7 @@ bool FBXBaker::importScene() { static const QString BAKED_TEXTURE_DIRECTORY = "textures/"; static const QString BAKED_TEXTURE_EXT = ".ktx"; -bool FBXBaker::rewriteAndCollectSceneTextures() { +bool FBXBaker::rewriteAndBakeSceneTextures() { // get a count of the textures used in the scene int numTextures = _scene->GetTextureCount(); @@ -283,6 +282,11 @@ bool FBXBaker::rewriteAndCollectSceneTextures() { // add the deduced url to the texture, associated with the resulting baked texture file name, to our hash _unbakedTextures.insert(urlToTexture, bakedTextureFileName); + + // start a bake for this texture and add it to our list to keep track of + auto bakingTexture = new TextureBaker(urlToTexture); + bakingTexture->start(); + _bakingTextures.emplace_back(bakingTexture); } } } @@ -315,31 +319,6 @@ bool FBXBaker::exportScene() { return true; } -bool FBXBaker::bakeTextures() { - // enumerate the list of unbaked textures - for (auto it = _unbakedTextures.begin(); it != _unbakedTextures.end(); ++it) { - auto& textureUrl = it.key(); - - qCDebug(model_baking) << "Baking texture at" << textureUrl; - - if (textureUrl.isLocalFile()) { - // this is a local file that we've already determined is available on the filesystem - - // load the file - QFile localTexture { textureUrl.toLocalFile() }; - - if (!localTexture.open(QIODevice::ReadOnly)) { - // add an error to the list stating that this texture couldn't be baked because it could not be loaded - } - - // call the image library to produce a compressed KTX for this image - } else { - // this is a remote texture that we'll need to download first - } - } - - return true; -} bool FBXBaker::removeEmbeddedMediaFolder() { // now that the bake is complete, remove the embedded media folder produced by the FBX SDK when it imports an FBX diff --git a/libraries/model-baking/src/FBXBaker.h b/libraries/model-baking/src/FBXBaker.h index fe28922f66..78a0dde0bb 100644 --- a/libraries/model-baking/src/FBXBaker.h +++ b/libraries/model-baking/src/FBXBaker.h @@ -13,12 +13,9 @@ #define hifi_FBXBaker_h #include -#include #include #include -Q_DECLARE_LOGGING_CATEGORY(model_baking) - namespace fbxsdk { class FbxManager; class FbxProperty; @@ -26,6 +23,8 @@ namespace fbxsdk { class FbxTexture; } +class TextureBaker; + class FBXBaker : public QObject { Q_OBJECT public: @@ -45,10 +44,8 @@ private: bool setupOutputFolder(); bool importScene(); - bool rewriteAndCollectSceneTextures(); + bool rewriteAndBakeSceneTextures(); bool exportScene(); - bool bakeTextures(); - bool bakeTexture(); bool removeEmbeddedMediaFolder(); QString pathToCopyOfOriginal() const; @@ -66,6 +63,10 @@ private: QHash _unbakedTextures; QHash _textureNameMatchCount; + + QHash _downloadedTextures; + + std::list> _bakingTextures; }; #endif // hifi_FBXBaker_h diff --git a/libraries/model-baking/src/ModelBakingLoggingCategory.cpp b/libraries/model-baking/src/ModelBakingLoggingCategory.cpp new file mode 100644 index 0000000000..c2ad6360d2 --- /dev/null +++ b/libraries/model-baking/src/ModelBakingLoggingCategory.cpp @@ -0,0 +1,14 @@ +// +// ModelBakingLoggingCategory.cpp +// libraries/model-baking/src +// +// Created by Stephen Birarda on 4/5/17. +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "ModelBakingLoggingCategory.h" + +Q_LOGGING_CATEGORY(model_baking, "hifi.model-baking"); diff --git a/libraries/model-baking/src/ModelBakingLoggingCategory.h b/libraries/model-baking/src/ModelBakingLoggingCategory.h new file mode 100644 index 0000000000..600618ed5e --- /dev/null +++ b/libraries/model-baking/src/ModelBakingLoggingCategory.h @@ -0,0 +1,19 @@ +// +// ModelBakingLoggingCategory.h +// libraries/model-baking/src +// +// Created by Stephen Birarda on 4/5/17. +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_ModelBakingLoggingCategory_h +#define hifi_ModelBakingLoggingCategory_h + +#include + +Q_DECLARE_LOGGING_CATEGORY(model_baking) + +#endif // hifi_ModelBakingLoggingCategory_h diff --git a/libraries/model-baking/src/TextureBaker.cpp b/libraries/model-baking/src/TextureBaker.cpp new file mode 100644 index 0000000000..ce86b18479 --- /dev/null +++ b/libraries/model-baking/src/TextureBaker.cpp @@ -0,0 +1,79 @@ +// +// TextureBaker.cpp +// libraries/model-baker/src +// +// Created by Stephen Birarda on 4/5/17. +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include +#include + +#include + +#include "ModelBakingLoggingCategory.h" + +#include "TextureBaker.h" + +TextureBaker::TextureBaker(const QUrl& textureURL) : + _textureURL(textureURL) +{ + +} + +void TextureBaker::start() { + + // check if the texture is local or first needs to be downloaded + if (_textureURL.isLocalFile()) { + // load up the local file + QFile localTexture { _textureURL.toLocalFile() }; + + if (!localTexture.open(QIODevice::ReadOnly)) { + qCWarning(model_baking) << "Unable to open local texture at" << _textureURL << "for baking"; + + emit finished(); + return; + } + + _originalTexture = localTexture.readAll(); + + // start the bake now that we have everything in place + bake(); + } else { + // remote file, kick off a download + auto& networkAccessManager = NetworkAccessManager::getInstance(); + + QNetworkRequest networkRequest; + + // setup the request to follow re-directs and always hit the network + networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); + networkRequest.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork); + + networkRequest.setUrl(_textureURL); + + qCDebug(model_baking) << "Downloading" << _textureURL; + + auto networkReply = networkAccessManager.get(networkRequest); + connect(networkReply, &QNetworkReply::finished, this, &TextureBaker::handleTextureNetworkReply); + } +} + +void TextureBaker::handleTextureNetworkReply() { + QNetworkReply* requestReply = qobject_cast(sender()); + + if (requestReply->error() == QNetworkReply::NoError) { + qCDebug(model_baking) << "Downloaded texture at" << _textureURL; + _originalTexture = requestReply->readAll(); + } else { + qCDebug(model_baking) << "Error downloading texture" << requestReply->errorString(); + } +} + +void TextureBaker::bake() { + qCDebug(model_baking) << "Baking texture at" << _textureURL; + + // call image library to asynchronously bake this texture +} diff --git a/libraries/model-baking/src/TextureBaker.h b/libraries/model-baking/src/TextureBaker.h new file mode 100644 index 0000000000..5544352005 --- /dev/null +++ b/libraries/model-baking/src/TextureBaker.h @@ -0,0 +1,43 @@ +// +// TextureBaker.h +// libraries/model-baker/src +// +// Created by Stephen Birarda on 4/5/17. +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_TextureBaker_h +#define hifi_TextureBaker_h + +#include +#include + +class TextureBaker : public QObject { + Q_OBJECT + +public: + TextureBaker(const QUrl& textureURL); + + void start(); + + const QByteArray& getOriginalTexture() const { return _originalTexture; } + + const QUrl& getTextureURL() const { return _textureURL; } + +signals: + void finished(); + +private slots: + void handleTextureNetworkReply(); + +private: + void bake(); + + QUrl _textureURL; + QByteArray _originalTexture; +}; + +#endif // hifi_TextureBaker_h