Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions src/qmlSfmData/CameraLocatorEntity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,23 +58,23 @@ CameraLocatorEntity::CameraLocatorEntity(const aliceVision::IndexT& viewId,
tr.y() = sin(vfov / 2.0f);
tr.z() = cos(vfov / 2.0f);

const float vslice = vfov / static_cast<double>(subdiv);
const float hslice = hfov / static_cast<double>(subdiv);
const float vslice = vfov / static_cast<float>(subdiv);
const float hslice = hfov / static_cast<float>(subdiv);

Eigen::Vector3d vZ = - Eigen::Vector3d::UnitZ() * radius;

for (int vid = 0; vid < subdiv; vid++)
{
float vangle1 = - vfov / 2.0f + (vid) * vslice;
float vangle2 = - vfov / 2.0f + (vid + 1) * vslice;
float vangle1 = - vfov / 2.0f + static_cast<float>(vid) * vslice;
float vangle2 = - vfov / 2.0f + static_cast<float>(vid + 1) * vslice;

Eigen::AngleAxis<double> Rv1(vangle1, Eigen::Vector3d::UnitX());
Eigen::AngleAxis<double> Rv2(vangle2, Eigen::Vector3d::UnitX());

for (int hid = 0; hid < subdiv; hid++)
{
float hangle1 = - hfov / 2.0f + (hid) * hslice;
float hangle2 = - hfov / 2.0f + (hid + 1) * hslice;
float hangle1 = - hfov / 2.0f + static_cast<float>(hid) * hslice;
float hangle2 = - hfov / 2.0f + static_cast<float>(hid + 1) * hslice;

Eigen::AngleAxis<double> Rh1(hangle1, Eigen::Vector3d::UnitY());
Eigen::AngleAxis<double> Rh2(hangle2, Eigen::Vector3d::UnitY());
Expand Down
97 changes: 51 additions & 46 deletions src/qtAliceVision/AsyncFetcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@
#include <QMutexLocker>
#include <QPoint>

#include <optional>
#include <thread>
#include <chrono>

using namespace aliceVision;

namespace qtAliceVision {
namespace imgserve {

Expand All @@ -32,14 +31,18 @@
_sequence = paths;
_currentIndex = 0;

for (unsigned idx = 0; idx < _sequence.size(); idx++)
for (std::size_t idx = 0; idx < _sequence.size(); ++idx)
{
_pathToSeqId[_sequence[idx]] = idx;
_pathToSeqId[_sequence[idx]] = static_cast<unsigned>(idx);
}
Comment on lines 31 to 37
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setSequence() rebuilds _pathToSeqId without clearing it first, so paths from a previous sequence can remain mapped and incorrectly update _currentIndex in getFrame(). Clear _pathToSeqId (and ideally reserve) before repopulating it when a new sequence is set.

Copilot uses AI. Check for mistakes.
}

void AsyncFetcher::setResizeRatio(double ratio)
{
if (ratio <= 0.0)
{
return;
}
QMutexLocker locker(&_mutexResizeRatio);
_resizeRatio = ratio;
}
Expand All @@ -55,7 +58,7 @@
}
}

bool AsyncFetcher::getPrefetching()
bool AsyncFetcher::getPrefetching() const
{
return _isPrefetching;
}
Expand Down Expand Up @@ -93,7 +96,7 @@
continue;
}

if (_sequence.size() == 0)
if (_sequence.empty())
{
continue;
}
Expand All @@ -109,7 +112,7 @@
ratio = _resizeRatio;
}

_cache->get<image::RGBAfColor>(lpath, static_cast<unsigned int>(_currentIndex), ratio, false);
_cache->get<aliceVision::image::RGBAfColor>(lpath, static_cast<unsigned int>(_currentIndex), ratio, false);
}

if (_isPrefetching)
Expand All @@ -135,7 +138,6 @@
}
}

_requestSynchronous = false;
_isAsynchronous = false;
}

Expand All @@ -149,18 +151,18 @@
}
}

std::size_t AsyncFetcher::getCacheMemory()
std::size_t AsyncFetcher::getCacheMemory() const
{
return (_cache)?_cache->getMaxMemory():0;
return (_cache) ? _cache->getMaxMemory() : 0;
}

std::size_t AsyncFetcher::getCacheSize() const
{
return (_cache) ? static_cast<std::size_t>(_cache->info().getContentSize()) : 0;

Check warning on line 161 in src/qtAliceVision/AsyncFetcher.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove these redundant parentheses.

See more on https://sonarcloud.io/project/issues?id=alicevision_QtAliceVision&issues=AZ2u9gT1vn5gzXa5KID4&open=AZ2u9gT1vn5gzXa5KID4&pullRequest=97
}

std::size_t AsyncFetcher::getDiskLoads() const {
return (_cache) ? static_cast<std::size_t>(_cache->info().getLoadFromDisk()) : 0;

Check warning on line 165 in src/qtAliceVision/AsyncFetcher.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove these redundant parentheses.

See more on https://sonarcloud.io/project/issues?id=alicevision_QtAliceVision&issues=AZ2u9gT1vn5gzXa5KID5&open=AZ2u9gT1vn5gzXa5KID5&pullRequest=97
}

QVariantList AsyncFetcher::getCachedFrames() const
Expand All @@ -178,35 +180,39 @@

size_t size = _sequence.size();

double resizeRatio;
{
// Build cached frames intervals
for (std::size_t i = 0; i < size; ++i)
{
const int frame = static_cast<int>(i);
QMutexLocker locker(&_mutexResizeRatio);
resizeRatio = _resizeRatio;
}

// Check if current frame is in cache
if (_cache->contains<aliceVision::image::RGBAfColor>(_sequence[i], _resizeRatio))
// Build cached frames intervals
for (std::size_t i = 0; i < size; ++i)
{
const int frame = static_cast<int>(i);

// Check if current frame is in cache
if (_cache->contains<aliceVision::image::RGBAfColor>(_sequence[i], resizeRatio))
{
// Either grow currently open region or create a new region
if (regionOpen)
{
// Either grow currently open region or create a new region
if (regionOpen)
{
region.second = frame;
}
else
{
region.first = frame;
region.second = frame;
regionOpen = true;
}
region.second = frame;
}
else
{
// Close currently open region
if (regionOpen)
{
intervals.append(QPoint(region.first, region.second));
regionOpen = false;
}
region.first = frame;
region.second = frame;
regionOpen = true;
}
}
else
{
// Close currently open region
if (regionOpen)
{
intervals.append(QPoint(region.first, region.second));
regionOpen = false;
}
}
}
Expand All @@ -221,7 +227,7 @@
}

bool AsyncFetcher::getFrame(const std::string& path,
std::shared_ptr<image::Image<image::RGBAfColor>>& image,
std::shared_ptr<aliceVision::image::Image<aliceVision::image::RGBAfColor>>& image,
oiio::ParamValueList& metadatas,
size_t& originalWidth,
size_t& originalHeight,
Expand All @@ -238,25 +244,26 @@
bool onlyCache = _isAsynchronous;

// Upgrade the thread with the current Index
for (std::size_t idx = 0; idx < _sequence.size(); ++idx)
auto it = _pathToSeqId.find(path);
if (it != _pathToSeqId.end())
{
if (_sequence[idx] == path)
{
_currentIndex = static_cast<int>(idx);
break;
}
_currentIndex = static_cast<int>(it->second);
}

// Try to find in the cache
std::optional<CacheValue> ovalue = _cache->get<aliceVision::image::RGBAfColor>(path, _currentIndex, _resizeRatio, onlyCache);
double ratio;
{
QMutexLocker locker(&_mutexResizeRatio);
ratio = _resizeRatio;
}
std::optional<CacheValue> ovalue = _cache->get<aliceVision::image::RGBAfColor>(path, static_cast<unsigned int>(_currentIndex), ratio, onlyCache);

if (ovalue.has_value())
{
auto& value = ovalue.value();
image = value.get<aliceVision::image::RGBAfColor>();

oiio::ParamValueList copy_metadatas = value.getMetadatas();
metadatas = copy_metadatas;
metadatas = value.getMetadatas();
originalWidth = value.getOriginalWidth();
originalHeight = value.getOriginalHeight();
missingFile = value.isFileMissing();
Expand All @@ -271,7 +278,7 @@
}
else
{
// If there is no cache, then poke the fetch thread
// Image not yet in cache; poke the fetch thread to load it
_semLoop.release(1);
}

Expand All @@ -280,5 +287,3 @@

} // namespace imgserve
} // namespace qtAliceVision

#include "AsyncFetcher.moc"
8 changes: 4 additions & 4 deletions src/qtAliceVision/AsyncFetcher.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class AsyncFetcher : public QObject, public QRunnable
* in the sequence before asked.
* @return true if prefetching is activated
*/
bool getPrefetching();
bool getPrefetching() const;

/**
* @brief retrieve a frame from the cache in both sync and async mode
Expand Down Expand Up @@ -105,10 +105,10 @@ class AsyncFetcher : public QObject, public QRunnable
void updateCacheMemory(std::size_t maxMemory);

/**
* @brief update maxMemory for the cache
* @brief get the maximum memory allowed for the cache
* @return the number of bytes allowed in the cache
*/
std::size_t getCacheMemory();
std::size_t getCacheMemory() const;

/**
* @brief get a list of regions containing the image frames
Expand All @@ -131,7 +131,7 @@ class AsyncFetcher : public QObject, public QRunnable
QAtomicInt _requestSynchronous;

double _resizeRatio;
QMutex _mutexResizeRatio;
mutable QMutex _mutexResizeRatio;
QSemaphore _semLoop;
};

Expand Down
21 changes: 15 additions & 6 deletions src/qtAliceVision/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ set(PLUGIN_SOURCES
MViewStats.cpp
MTracks.cpp
FloatImageViewer.cpp
FloatImageViewerMaterial.cpp
FloatImageViewerMaterialShader.cpp
FloatImageViewerNode.cpp
FloatTexture.cpp
Surface.cpp
MSfMDataStats.cpp
Expand All @@ -26,6 +29,9 @@ set(PLUGIN_HEADERS
MTracks.hpp
MViewStats.hpp
FloatImageViewer.hpp
FloatImageViewerMaterial.hpp
FloatImageViewerMaterialShader.hpp
FloatImageViewerNode.hpp
FloatTexture.hpp
MSfMDataStats.hpp
PanoramaViewer.hpp
Expand Down Expand Up @@ -76,12 +82,15 @@ qt6_add_shaders(qtAliceVisionPlugin "qtAliceVisionPlugin_shaders"
BATCHABLE
PRECOMPILE
OPTIMIZED
PREFIX "/shaders"
FILES FloatImageViewer.vert FloatImageViewer.frag
FeaturesViewer.vert FeaturesViewer.frag
PhongImageViewer.vert PhongImageViewer.frag
ImageOverlay.frag
AttributeItemDelegate.frag
#PREFIX "/shaders"
FILES shaders/FloatImageViewer.vert
shaders/FloatImageViewer.frag
shaders/FeaturesViewer.vert
shaders/FeaturesViewer.frag
shaders/PhongImageViewer.vert
shaders/PhongImageViewer.frag
shaders/ImageOverlay.frag
shaders/AttributeItemDelegate.frag
)

target_link_libraries(qtAliceVisionPlugin
Expand Down
Loading