diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index e8d72857..fae95dc7 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -1,3 +1,5 @@ +# [qtAliceVision] Apply clang-format on the module +e2e5155ca87a5eeb52d27978e13977441cd07305 # [qmlSfmData] Reformatted with clang-format 271141c06f0f92b3ffc73e2283b4124b09c987d8 # [qtAliceVision] Reformatted with clang-format diff --git a/src/qtAliceVision/AsyncFetcher.cpp b/src/qtAliceVision/AsyncFetcher.cpp index 50d19959..f0f2efb3 100644 --- a/src/qtAliceVision/AsyncFetcher.cpp +++ b/src/qtAliceVision/AsyncFetcher.cpp @@ -50,7 +50,7 @@ void AsyncFetcher::setPrefetching(bool prefetch) if (_isPrefetching) { - //Make sure we're not waiting for new source + // Make sure we're not waiting for new source _semLoop.release(1); } } @@ -81,8 +81,8 @@ void AsyncFetcher::run() _requestSynchronous = false; break; } - - //Lock the thread until someone ask something + + // Lock the thread until someone ask something if (!_semLoop.tryAcquire(1, QDeadlineTimer(1s))) { continue; @@ -134,10 +134,7 @@ void AsyncFetcher::run() _isAsynchronous = false; } -void AsyncFetcher::stopAsync() -{ - _requestSynchronous = true; -} +void AsyncFetcher::stopAsync() { _requestSynchronous = true; } void AsyncFetcher::updateCacheMemory(std::size_t maxMemory) { @@ -147,15 +144,9 @@ void AsyncFetcher::updateCacheMemory(std::size_t maxMemory) } } -std::size_t AsyncFetcher::getCacheSize() const -{ - return (_cache) ? static_cast(_cache->info().getContentSize()) : 0; -} +std::size_t AsyncFetcher::getCacheSize() const { return (_cache) ? static_cast(_cache->info().getContentSize()) : 0; } -std::size_t AsyncFetcher::getDiskLoads() const -{ - return (_cache) ? static_cast(_cache->info().getLoadFromDisk()) : 0; -} +std::size_t AsyncFetcher::getDiskLoads() const { return (_cache) ? static_cast(_cache->info().getLoadFromDisk()) : 0; } QVariantList AsyncFetcher::getCachedFrames() const { @@ -218,7 +209,9 @@ bool AsyncFetcher::getFrame(const std::string& path, std::shared_ptr>& image, oiio::ParamValueList& metadatas, size_t& originalWidth, - size_t& originalHeight) + size_t& originalHeight, + bool& missingFile, + bool& loadingError) { // Need a cache if (!_cache) @@ -239,7 +232,7 @@ bool AsyncFetcher::getFrame(const std::string& path, } } - //Try to find in the cache + // Try to find in the cache std::optional ovalue = _cache->get(path, _currentIndex, _resizeRatio, onlyCache); if (ovalue.has_value()) @@ -251,6 +244,8 @@ bool AsyncFetcher::getFrame(const std::string& path, metadatas = copy_metadatas; originalWidth = value.getOriginalWidth(); originalHeight = value.getOriginalHeight(); + missingFile = value.isFileMissing(); + loadingError = value.hadErrorOnLoad(); if (image) { @@ -259,9 +254,9 @@ bool AsyncFetcher::getFrame(const std::string& path, return true; } - else + else { - //If there is no cache, then poke the fetch thread + // If there is no cache, then poke the fetch thread _semLoop.release(1); } diff --git a/src/qtAliceVision/AsyncFetcher.hpp b/src/qtAliceVision/AsyncFetcher.hpp index c7bf747a..ba3cfad3 100644 --- a/src/qtAliceVision/AsyncFetcher.hpp +++ b/src/qtAliceVision/AsyncFetcher.hpp @@ -41,9 +41,9 @@ class AsyncFetcher : public QObject, public QRunnable void setResizeRatio(double ratio); /** - * @brief Do we enable prefetching ? Means that we are prefetching next frames + * @brief Do we enable prefetching ? Means that we are prefetching next frames * in the sequence before asked. - * @param prefetch true if prefetching is activated + * @param prefetch true if prefetching is activated */ void setPrefetching(bool prefetch); @@ -54,13 +54,17 @@ class AsyncFetcher : public QObject, public QRunnable * @param metadatas the image metadatas found in the file * @param originalWidth the image width before the resize * @param originalHeight the image height before the resize + * @param missingFile the image cache entry indicates a missing file + * @param loadingError the image cache entry indicates a file loading error * @return true if the image was succesfully found in the cache */ bool getFrame(const std::string& path, std::shared_ptr>& image, oiio::ParamValueList& metadatas, std::size_t& originalWidth, - std::size_t& originalHeight); + std::size_t& originalHeight, + bool& missingFile, + bool& loadingError); /** * @brief Internal function for QT to start the asynchronous mode diff --git a/src/qtAliceVision/FloatImageViewer.cpp b/src/qtAliceVision/FloatImageViewer.cpp index e9c7a2b6..f5054b1c 100644 --- a/src/qtAliceVision/FloatImageViewer.cpp +++ b/src/qtAliceVision/FloatImageViewer.cpp @@ -325,6 +325,7 @@ FloatImageViewer::FloatImageViewer(QQuickItem* parent) connect(&_singleImageLoader, &imgserve::SingleImageLoader::requestHandled, this, &FloatImageViewer::reload); connect(&_sequenceCache, &imgserve::SequenceCache::requestHandled, this, &FloatImageViewer::reload); connect(this, &FloatImageViewer::useSequenceChanged, this, &FloatImageViewer::reload); + connect(this, &FloatImageViewer::sequenceChanged, this, &FloatImageViewer::reload); } FloatImageViewer::~FloatImageViewer() {} @@ -372,8 +373,8 @@ void FloatImageViewer::setResizeRatio(double ratio) if (ratio != _clampedResizeRatio) { - //If the clamped ratio has changed, then - //We may need to reload the image with the correct resolution + // If the clamped ratio has changed, then + // We may need to reload the image with the correct resolution Q_EMIT sourceChanged(); } @@ -458,7 +459,8 @@ void FloatImageViewer::reload() } else if (_outdated) { - qWarning() << "[QtAliceVision] FloatImageViewer: The loading status has not been updated since the last reload. Something wrong might have happened."; + qWarning() + << "[QtAliceVision] FloatImageViewer: The loading status has not been updated since the last reload. Something wrong might have happened."; setStatus(EStatus::OUTDATED_LOADING); } Q_EMIT cachedFramesChanged(); diff --git a/src/qtAliceVision/ImageCache.cpp b/src/qtAliceVision/ImageCache.cpp index 420a64cb..7ec75e10 100644 --- a/src/qtAliceVision/ImageCache.cpp +++ b/src/qtAliceVision/ImageCache.cpp @@ -83,14 +83,8 @@ void ImageCache::cleanup(size_t requestedSize, const CacheKey& toAdd) } } -void ImageCache::updateMaxMemory(unsigned long long int maxSize) -{ - _info.setMaxMemory(maxSize); -} +void ImageCache::updateMaxMemory(unsigned long long int maxSize) { _info.setMaxMemory(maxSize); } -void ImageCache::setReferenceFrameId(int referenceFrameId) -{ - _referenceFrameId = referenceFrameId; -} +void ImageCache::setReferenceFrameId(int referenceFrameId) { _referenceFrameId = referenceFrameId; } } // namespace qtAliceVision diff --git a/src/qtAliceVision/ImageCache.hpp b/src/qtAliceVision/ImageCache.hpp index 4951f557..c9d9ffb6 100644 --- a/src/qtAliceVision/ImageCache.hpp +++ b/src/qtAliceVision/ImageCache.hpp @@ -10,7 +10,6 @@ #include - namespace qtAliceVision { /** * @brief A struct used to identify a cached image using its file description, color type info and downscale level. @@ -59,9 +58,11 @@ class CacheValue { public: template - CacheValue(unsigned frameId, std::shared_ptr> img) + CacheValue(unsigned frameId, std::shared_ptr> img, bool missingFile, bool loadError) : _vimg(img), - _frameId(frameId) + _frameId(frameId), + _missingFile(missingFile), + _loadError(loadError) {} public: @@ -76,35 +77,17 @@ class CacheValue return std::get>>(_vimg); } - unsigned getOriginalWidth() const - { - return _originalWidth; - } + unsigned getOriginalWidth() const { return _originalWidth; } - unsigned getOriginalHeight() const - { - return _originalHeight; - } + unsigned getOriginalHeight() const { return _originalHeight; } - void setOriginalWidth(unsigned width) - { - _originalWidth = width; - } + void setOriginalWidth(unsigned width) { _originalWidth = width; } - void setOriginalHeight(unsigned height) - { - _originalHeight = height; - } + void setOriginalHeight(unsigned height) { _originalHeight = height; } - oiio::ParamValueList & getMetadatas() - { - return _metadatas; - } + oiio::ParamValueList& getMetadatas() { return _metadatas; } - unsigned getFrameId() const - { - return _frameId; - } + unsigned getFrameId() const { return _frameId; } /** * @brief Count the number of usages of the wrapped shared pointer. @@ -124,6 +107,18 @@ class CacheValue return std::visit([](const auto& arg) -> unsigned long long int { return arg->memorySize(); }, _vimg); } + /** + * @brief did the load failed ? + * @return true if something bad happened during the loading + */ + bool hadErrorOnLoad() const { return _loadError; } + + /** + * @brief is the file requested missing ? + * @return true if the file doesn't exist + */ + bool isFileMissing() const { return _missingFile; } + private: std::variant>, std::shared_ptr>, @@ -137,6 +132,8 @@ class CacheValue unsigned _originalHeight; oiio::ParamValueList _metadatas; unsigned _frameId; + bool _loadError; + bool _missingFile; }; /** @@ -363,6 +360,10 @@ std::optional ImageCache::get(const std::string& filename, unsigned template std::optional ImageCache::load(const CacheKey& key, unsigned frameId) { + // Increment disk access stats + // This is incremented whatever happens next + _info.incrementDisk(); + aliceVision::image::Image img; auto resized = std::make_shared>(); @@ -370,35 +371,51 @@ std::optional ImageCache::load(const CacheKey& key, unsigned frameId int height = 0; oiio::ParamValueList metadatas; - try - { - metadatas = aliceVision::image::readImageMetadata(key.filename, width, height); + bool loadError = false; + bool missingFile = false; - // load image from disk - readImage(key.filename, img, _options); - } - catch (...) + // First check if the files exists on disk + // LastWriteTime equals 0 if the file doesn't exist + if (key.lastWriteTime == 0) { - return std::nullopt; + missingFile = true; + loadError = true; } + else + { + // If the file exist, then try to load it. + try + { + // Retrieve metadatas + metadatas = aliceVision::image::readImageMetadata(key.filename, width, height); - // Compute new size, make sure the size is at least 1 - double dw = key.resizeRatio * double(img.width()); - double dh = key.resizeRatio * double(img.height()); - int tw = static_cast(std::max(1, int(std::ceil(dw)))); - int th = static_cast(std::max(1, int(std::ceil(dh)))); + // load image from disk + readImage(key.filename, img, _options); + } + catch (...) + { + loadError = true; + } + } - using TInfo = aliceVision::image::ColorTypeInfo; - cleanup(tw * th * std::size_t(TInfo::size), key); + if (!loadError) + { + // Compute new size, make sure the size is at least 1 + double dw = key.resizeRatio * double(img.width()); + double dh = key.resizeRatio * double(img.height()); + int tw = static_cast(std::max(1, int(std::ceil(dw)))); + int th = static_cast(std::max(1, int(std::ceil(dh)))); - // apply downscale - aliceVision::imageAlgo::resizeImage(tw, th, img, *resized); + using TInfo = aliceVision::image::ColorTypeInfo; + cleanup(tw * th * std::size_t(TInfo::size), key); - // Increment disk access stats - _info.incrementDisk(); + // apply downscale + aliceVision::imageAlgo::resizeImage(tw, th, img, *resized); + } // create wrapper around shared pointer - CacheValue value(frameId, resized); + // Note that we store cache item even on problem to not repeat trials + CacheValue value(frameId, resized, missingFile, loadError); // Add additional information about the image value.setOriginalHeight(static_cast(height)); diff --git a/src/qtAliceVision/Painter.cpp b/src/qtAliceVision/Painter.cpp index 741fdd1e..68ff5603 100644 --- a/src/qtAliceVision/Painter.cpp +++ b/src/qtAliceVision/Painter.cpp @@ -22,25 +22,13 @@ class PointMaterial : public QSGMaterial _size(1.0f) {} - void setColor(const QColor& color) - { - _color = color; - } + void setColor(const QColor& color) { _color = color; } - QColor getColor() const - { - return _color; - } + QColor getColor() const { return _color; } - void setSize(const float & size) - { - _size = size; - } + void setSize(const float& size) { _size = size; } - float getSize() const - { - return _size; - } + float getSize() const { return _size; } QSGMaterialType* type() const override { @@ -126,10 +114,7 @@ class PointMaterialShader : public QSGMaterialShader } }; -QSGMaterialShader* PointMaterial::createShader(QSGRendererInterface::RenderMode) const -{ - return new PointMaterialShader; -} +QSGMaterialShader* PointMaterial::createShader(QSGRendererInterface::RenderMode) const { return new PointMaterialShader; } Painter::Painter(const std::vector& layers) : _layers(layers) diff --git a/src/qtAliceVision/PhongImageViewer.cpp b/src/qtAliceVision/PhongImageViewer.cpp index 0e27ac36..7a1267bf 100644 --- a/src/qtAliceVision/PhongImageViewer.cpp +++ b/src/qtAliceVision/PhongImageViewer.cpp @@ -7,186 +7,190 @@ namespace qtAliceVision { -namespace +namespace { +class PhongImageViewerMaterialShader; + +class PhongImageViewerMaterial : public QSGMaterial { - class PhongImageViewerMaterialShader; + public: + PhongImageViewerMaterial() {} - class PhongImageViewerMaterial : public QSGMaterial + QSGMaterialType* type() const override { - public: - PhongImageViewerMaterial() {} + static QSGMaterialType type; + return &type; + } - QSGMaterialType* type() const override - { - static QSGMaterialType type; - return &type; - } + int compare(const QSGMaterial* other) const override + { + Q_ASSERT(other && type() == other->type()); + return other == this ? 0 : (other > this ? 1 : -1); + } - int compare(const QSGMaterial* other) const override - { - Q_ASSERT(other && type() == other->type()); - return other == this ? 0 : (other > this ? 1 : -1); - } + QSGMaterialShader* createShader(QSGRendererInterface::RenderMode) const override; - QSGMaterialShader* createShader(QSGRendererInterface::RenderMode) const override; + struct + { + // warning: matches layout and padding of PhongImageViewer.vert/frag shaders + QVector4D channelOrder = QVector4D(0, 1, 2, 3); + QVector4D baseColor = QVector4D(.2f, .2f, .2f, 1.f); + QVector3D lightDirection = QVector3D(0.f, 0.f, -1.f); + float textureOpacity = 1.f; + float gamma = 1.f; + float gain = 0.f; + float ka = 0.f; + float kd = 1.f; + float ks = 1.f; + float shininess = 20.f; + + } uniforms; + + std::unique_ptr sourceTexture = std::make_unique(); // should be initialized + std::unique_ptr normalTexture = std::make_unique(); // should be initialized + bool dirtyUniforms; +}; + +class PhongImageViewerMaterialShader : public QSGMaterialShader +{ + public: + PhongImageViewerMaterialShader() + { + setShaderFileName(VertexStage, QLatin1String(":/shaders/PhongImageViewer.vert.qsb")); + setShaderFileName(FragmentStage, QLatin1String(":/shaders/PhongImageViewer.frag.qsb")); + } - struct - { - // warning: matches layout and padding of PhongImageViewer.vert/frag shaders - QVector4D channelOrder = QVector4D(0, 1, 2, 3); - QVector4D baseColor = QVector4D(.2f, .2f, .2f, 1.f); - QVector3D lightDirection = QVector3D(0.f, 0.f, -1.f); - float textureOpacity = 1.f; - float gamma = 1.f; - float gain = 0.f; - float ka = 0.f; - float kd = 1.f; - float ks = 1.f; - float shininess = 20.f; - - } uniforms; - - std::unique_ptr sourceTexture = std::make_unique(); // should be initialized - std::unique_ptr normalTexture = std::make_unique(); // should be initialized - bool dirtyUniforms; - }; - - class PhongImageViewerMaterialShader : public QSGMaterialShader + bool updateUniformData(RenderState& state, QSGMaterial* newMaterial, QSGMaterial* oldMaterial) override { - public: - PhongImageViewerMaterialShader() + bool changed = false; + QByteArray* buf = state.uniformData(); + Q_ASSERT(buf->size() >= 84); + if (state.isMatrixDirty()) { - setShaderFileName(VertexStage, QLatin1String(":/shaders/PhongImageViewer.vert.qsb")); - setShaderFileName(FragmentStage, QLatin1String(":/shaders/PhongImageViewer.frag.qsb")); + const QMatrix4x4 m = state.combinedMatrix(); + memcpy(buf->data() + 0, m.constData(), 64); + changed = true; } - - bool updateUniformData(RenderState& state, QSGMaterial* newMaterial, QSGMaterial* oldMaterial) override + if (state.isOpacityDirty()) { - bool changed = false; - QByteArray* buf = state.uniformData(); - Q_ASSERT(buf->size() >= 84); - if (state.isMatrixDirty()) - { - const QMatrix4x4 m = state.combinedMatrix(); - memcpy(buf->data() + 0, m.constData(), 64); - changed = true; - } - if (state.isOpacityDirty()) { - const float opacity = state.opacity(); - memcpy(buf->data() + 64, &opacity, 4); - changed = true; - } - auto* customMaterial = static_cast(newMaterial); - if (oldMaterial != newMaterial || customMaterial->dirtyUniforms) { - memcpy(buf->data() + 80, &customMaterial->uniforms, 72); // uniforms size is 72 - customMaterial->dirtyUniforms = false; - changed = true; - } - return changed; + const float opacity = state.opacity(); + memcpy(buf->data() + 64, &opacity, 4); + changed = true; } - - void updateSampledImage(RenderState& state, int binding, QSGTexture** texture, QSGMaterial* newMaterial, QSGMaterial*) override + auto* customMaterial = static_cast(newMaterial); + if (oldMaterial != newMaterial || customMaterial->dirtyUniforms) { - PhongImageViewerMaterial* mat = static_cast(newMaterial); - - if (binding == 1) - { - mat->sourceTexture->commitTextureOperations(state.rhi(), state.resourceUpdateBatch()); - *texture = mat->sourceTexture.get(); - } - - if (binding == 2) - { - mat->normalTexture->commitTextureOperations(state.rhi(), state.resourceUpdateBatch()); - *texture = mat->normalTexture.get(); - } + memcpy(buf->data() + 80, &customMaterial->uniforms, 72); // uniforms size is 72 + customMaterial->dirtyUniforms = false; + changed = true; } - }; - - QSGMaterialShader* PhongImageViewerMaterial::createShader(QSGRendererInterface::RenderMode) const - { - return new PhongImageViewerMaterialShader; + return changed; } - class PhongImageViewerNode : public QSGGeometryNode + void updateSampledImage(RenderState& state, int binding, QSGTexture** texture, QSGMaterial* newMaterial, QSGMaterial*) override { - public: - PhongImageViewerNode() - { - auto* m = new PhongImageViewerMaterial; - setMaterial(m); - setFlag(OwnsMaterial, true); - QSGGeometry* geometry = new QSGGeometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 0); - geometry->setIndexDataPattern(QSGGeometry::StaticPattern); - geometry->setVertexDataPattern(QSGGeometry::StaticPattern); - setGeometry(geometry); - setFlag(OwnsGeometry, true); - } + PhongImageViewerMaterial* mat = static_cast(newMaterial); - void setBlending(bool value) + if (binding == 1) { - auto* m = static_cast(material()); - m->setFlag(QSGMaterial::Blending, value); + mat->sourceTexture->commitTextureOperations(state.rhi(), state.resourceUpdateBatch()); + *texture = mat->sourceTexture.get(); } - void setEmptyGeometry() + if (binding == 2) { - auto* g = geometry(); - - if (g->vertexCount() != 0) - { - g->allocate(0); - markDirty(QSGNode::DirtyGeometry); - } + mat->normalTexture->commitTextureOperations(state.rhi(), state.resourceUpdateBatch()); + *texture = mat->normalTexture.get(); } + } +}; - void setRectGeometry(const QRectF& bounds) - { - auto* g = geometry(); +QSGMaterialShader* PhongImageViewerMaterial::createShader(QSGRendererInterface::RenderMode) const { return new PhongImageViewerMaterialShader; } - if (g->vertexCount() != 4) - { - geometry()->allocate(4); - } +class PhongImageViewerNode : public QSGGeometryNode +{ + public: + PhongImageViewerNode() + { + auto* m = new PhongImageViewerMaterial; + setMaterial(m); + setFlag(OwnsMaterial, true); + QSGGeometry* geometry = new QSGGeometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 0); + geometry->setIndexDataPattern(QSGGeometry::StaticPattern); + geometry->setVertexDataPattern(QSGGeometry::StaticPattern); + setGeometry(geometry); + setFlag(OwnsGeometry, true); + } - QSGGeometry::updateTexturedRectGeometry(g, bounds, QRectF(0, 0, 1, 1)); + void setBlending(bool value) + { + auto* m = static_cast(material()); + m->setFlag(QSGMaterial::Blending, value); + } - markDirty(QSGNode::DirtyGeometry); - } + void setEmptyGeometry() + { + auto* g = geometry(); - void setSourceParameters(const QVector4D& channelOrder, float gamma, float gain) + if (g->vertexCount() != 0) { - auto* m = static_cast(material()); - m->uniforms.gamma = gamma; - m->uniforms.gain = gain; - m->uniforms.channelOrder = channelOrder; - m->dirtyUniforms = true; - markDirty(DirtyMaterial); + g->allocate(0); + markDirty(QSGNode::DirtyGeometry); } + } - void setShadingParameters(const QVector4D& baseColor, const QVector3D& lightDirection, float textureOpacity, float ka, float kd, float ks, float shininess) - { - auto* m = static_cast(material()); - m->uniforms.baseColor = baseColor; - m->uniforms.lightDirection = lightDirection; - m->uniforms.textureOpacity = textureOpacity; - m->uniforms.ka = ka; - m->uniforms.kd = kd; - m->uniforms.ks = ks; - m->uniforms.shininess = shininess; - m->dirtyUniforms = true; - markDirty(DirtyMaterial); - } + void setRectGeometry(const QRectF& bounds) + { + auto* g = geometry(); - void setTextures(std::unique_ptr sourceTexture, std::unique_ptr normalTexture) + if (g->vertexCount() != 4) { - auto* m = static_cast(material()); - m->sourceTexture = std::move(sourceTexture); - m->normalTexture = std::move(normalTexture); - markDirty(DirtyMaterial); + geometry()->allocate(4); } - }; -} + + QSGGeometry::updateTexturedRectGeometry(g, bounds, QRectF(0, 0, 1, 1)); + + markDirty(QSGNode::DirtyGeometry); + } + + void setSourceParameters(const QVector4D& channelOrder, float gamma, float gain) + { + auto* m = static_cast(material()); + m->uniforms.gamma = gamma; + m->uniforms.gain = gain; + m->uniforms.channelOrder = channelOrder; + m->dirtyUniforms = true; + markDirty(DirtyMaterial); + } + + void setShadingParameters(const QVector4D& baseColor, + const QVector3D& lightDirection, + float textureOpacity, + float ka, + float kd, + float ks, + float shininess) + { + auto* m = static_cast(material()); + m->uniforms.baseColor = baseColor; + m->uniforms.lightDirection = lightDirection; + m->uniforms.textureOpacity = textureOpacity; + m->uniforms.ka = ka; + m->uniforms.kd = kd; + m->uniforms.ks = ks; + m->uniforms.shininess = shininess; + m->dirtyUniforms = true; + markDirty(DirtyMaterial); + } + + void setTextures(std::unique_ptr sourceTexture, std::unique_ptr normalTexture) + { + auto* m = static_cast(material()); + m->sourceTexture = std::move(sourceTexture); + m->normalTexture = std::move(normalTexture); + markDirty(DirtyMaterial); + } +}; +} // namespace PhongImageViewer::PhongImageViewer(QQuickItem* parent) : QQuickItem(parent) @@ -197,8 +201,14 @@ PhongImageViewer::PhongImageViewer(QQuickItem* parent) // connects connect(this, &PhongImageViewer::sourcePathChanged, this, &PhongImageViewer::reload); connect(this, &PhongImageViewer::normalPathChanged, this, &PhongImageViewer::reload); - connect(this, &PhongImageViewer::sourceParametersChanged, this, [this] { _sourceParametersChanged = true; update(); }); - connect(this, &PhongImageViewer::shadingParametersChanged, this, [this] { _shadingParametersChanged = true; update(); }); + connect(this, &PhongImageViewer::sourceParametersChanged, this, [this] { + _sourceParametersChanged = true; + update(); + }); + connect(this, &PhongImageViewer::shadingParametersChanged, this, [this] { + _shadingParametersChanged = true; + update(); + }); connect(this, &PhongImageViewer::textureSizeChanged, this, &PhongImageViewer::update); connect(this, &PhongImageViewer::sourceSizeChanged, this, &PhongImageViewer::update); connect(this, &PhongImageViewer::imageChanged, this, &PhongImageViewer::update); @@ -210,7 +220,10 @@ PhongImageViewer::~PhongImageViewer() {} void PhongImageViewer::setStatus(EStatus status) { - if (_status == status) { return; } + if (_status == status) + { + return; + } _status = status; Q_EMIT statusChanged(); } @@ -264,10 +277,10 @@ void PhongImageViewer::reload() // copy source image _sourceImage = responseSourceImage.img; - + // copy normal image _normalImage = responseNormalImage.img; - + // images have changed _imageChanged = true; Q_EMIT imageChanged(); @@ -307,7 +320,7 @@ QSGNode* PhongImageViewer::updatePaintNode(QSGNode* oldNode, QQuickItem::UpdateP auto sourceTexture = std::make_unique(); auto normalTexture = std::make_unique(); - if(_sourceImage) + if (_sourceImage) { sourceTexture->setImage(_sourceImage); sourceTexture->setFiltering(QSGTexture::Nearest); @@ -349,10 +362,8 @@ QSGNode* PhongImageViewer::updatePaintNode(QSGNode* oldNode, QQuickItem::UpdateP } else { - const float windowRatio = static_cast(_boundingRect.width()) / - static_cast(_boundingRect.height()); - const float textureRatio = static_cast(_textureSize.width()) / - static_cast(_textureSize.height()); + const float windowRatio = static_cast(_boundingRect.width()) / static_cast(_boundingRect.height()); + const float textureRatio = static_cast(_textureSize.width()) / static_cast(_textureSize.height()); QRectF geometryRect = _boundingRect; if (windowRatio > textureRatio) @@ -404,15 +415,10 @@ QSGNode* PhongImageViewer::updatePaintNode(QSGNode* oldNode, QQuickItem::UpdateP if (isNewNode || _shadingParametersChanged) { // light direction from Yaw and Pitch - const Eigen::AngleAxis yawA(static_cast(aliceVision::degreeToRadian(_lightYaw)), - Eigen::Vector3d::UnitY()); - const Eigen::AngleAxis pitchA(static_cast(aliceVision::degreeToRadian(_lightPitch)), - Eigen::Vector3d::UnitX()); - const aliceVision::Vec3 direction = yawA.toRotationMatrix() * pitchA.toRotationMatrix() * - aliceVision::Vec3(0.0, 0.0, -1.0); - const QVector3D lightDirection(static_cast(direction.x()), - static_cast(direction.y()), - static_cast(direction.z())); + const Eigen::AngleAxis yawA(static_cast(aliceVision::degreeToRadian(_lightYaw)), Eigen::Vector3d::UnitY()); + const Eigen::AngleAxis pitchA(static_cast(aliceVision::degreeToRadian(_lightPitch)), Eigen::Vector3d::UnitX()); + const aliceVision::Vec3 direction = yawA.toRotationMatrix() * pitchA.toRotationMatrix() * aliceVision::Vec3(0.0, 0.0, -1.0); + const QVector3D lightDirection(static_cast(direction.x()), static_cast(direction.y()), static_cast(direction.z())); // linear base color from QColor const QVector4D baseColor(std::pow(static_cast(_baseColor.redF()), 2.2f), diff --git a/src/qtAliceVision/PhongImageViewer.hpp b/src/qtAliceVision/PhongImageViewer.hpp index 19e2e631..d7c6beef 100644 --- a/src/qtAliceVision/PhongImageViewer.hpp +++ b/src/qtAliceVision/PhongImageViewer.hpp @@ -27,7 +27,7 @@ class PhongImageViewer : public QQuickItem Q_PROPERTY(EChannelMode channelMode MEMBER _channelMode NOTIFY sourceParametersChanged) Q_PROPERTY(float gamma MEMBER _gamma NOTIFY sourceParametersChanged) Q_PROPERTY(float gain MEMBER _gain NOTIFY sourceParametersChanged) - + // shading parameters (material, light) Q_PROPERTY(QColor baseColor MEMBER _baseColor NOTIFY shadingParametersChanged) Q_PROPERTY(float textureOpacity MEMBER _textureOpacity NOTIFY shadingParametersChanged) @@ -41,7 +41,7 @@ class PhongImageViewer : public QQuickItem // texture Q_PROPERTY(QSize textureSize MEMBER _textureSize NOTIFY textureSizeChanged) Q_PROPERTY(QSize sourceSize READ sourceSize NOTIFY sourceSizeChanged) - + // metadata Q_PROPERTY(QVariantMap metadata READ metadata NOTIFY metadataChanged) @@ -49,13 +49,12 @@ class PhongImageViewer : public QQuickItem Q_PROPERTY(EStatus status READ status NOTIFY statusChanged) public: - enum class EStatus : quint8 { - NONE, // nothing is happening, no error has been detected - LOADING, // an image is being loaded - MISSING_FILE, // the file to load is missing - LOADING_ERROR, // generic error + NONE, // nothing is happening, no error has been detected + LOADING, // an image is being loaded + MISSING_FILE, // the file to load is missing + LOADING_ERROR, // generic error }; Q_ENUM(EStatus) @@ -83,7 +82,7 @@ class PhongImageViewer : public QQuickItem // signals Q_SIGNAL void sourcePathChanged(); - Q_SIGNAL void normalPathChanged(); + Q_SIGNAL void normalPathChanged(); Q_SIGNAL void sourceParametersChanged(); Q_SIGNAL void shadingParametersChanged(); Q_SIGNAL void textureSizeChanged(); @@ -93,11 +92,10 @@ class PhongImageViewer : public QQuickItem Q_SIGNAL void statusChanged(); private: - // set viewer status void setStatus(EStatus status); - // reload image(s) + // reload image(s) void reload(); // clear images in memory @@ -107,7 +105,6 @@ class PhongImageViewer : public QQuickItem QSGNode* updatePaintNode(QSGNode* oldNode, QQuickItem::UpdatePaintNodeData* data) override; private: - // file paths QUrl _sourcePath; QUrl _normalPath; @@ -152,4 +149,3 @@ class PhongImageViewer : public QQuickItem }; } // namespace qtAliceVision - diff --git a/src/qtAliceVision/SequenceCache.cpp b/src/qtAliceVision/SequenceCache.cpp index 53c638da..47eea868 100644 --- a/src/qtAliceVision/SequenceCache.cpp +++ b/src/qtAliceVision/SequenceCache.cpp @@ -57,10 +57,7 @@ void SequenceCache::setSequence(const QVariantList& paths) setAsyncFetching(isAsync); } -void SequenceCache::setResizeRatio(double ratio) -{ - _fetcher.setResizeRatio(ratio); -} +void SequenceCache::setResizeRatio(double ratio) { _fetcher.setResizeRatio(ratio); } void SequenceCache::setMemoryLimit(int memory) { @@ -70,10 +67,7 @@ void SequenceCache::setMemoryLimit(int memory) _fetcher.updateCacheMemory(_maxMemory); } -QVariantList SequenceCache::getCachedFrames() const -{ - return _fetcher.getCachedFrames(); -} +QVariantList SequenceCache::getCachedFrames() const { return _fetcher.getCachedFrames(); } void SequenceCache::setAsyncFetching(bool fetching) { @@ -88,10 +82,7 @@ void SequenceCache::setAsyncFetching(bool fetching) } } -void SequenceCache::setPrefetching(bool prefetching) -{ - _fetcher.setPrefetching(prefetching); -} +void SequenceCache::setPrefetching(bool prefetching) { _fetcher.setPrefetching(prefetching); } QPointF SequenceCache::getRamInfo() const { @@ -114,14 +105,27 @@ ResponseData SequenceCache::request(const RequestData& reqData) oiio::ParamValueList metadatas; size_t originalWidth = 0; size_t originalHeight = 0; + bool hadErrorOnLoad = false; + bool isFileMissing = false; - if (!_fetcher.getFrame(reqData.path, image, metadatas, originalWidth, originalHeight)) + if (!_fetcher.getFrame(reqData.path, image, metadatas, originalWidth, originalHeight, isFileMissing, hadErrorOnLoad)) { return response; } + if (isFileMissing) + { + response.error = MISSING_FILE; + return response; + } + + if (hadErrorOnLoad) + { + response.error = LOADING_ERROR; + return response; + } - //Build a new response with information fetched + // Build a new response with information fetched response.metadata.clear(); response.img = image; response.dim = QSize(static_cast(originalWidth), static_cast(originalHeight));