diff --git a/modules/base/lightsource/cameralightsource.cpp b/modules/base/lightsource/cameralightsource.cpp index 69b8789081..a012e25434 100644 --- a/modules/base/lightsource/cameralightsource.cpp +++ b/modules/base/lightsource/cameralightsource.cpp @@ -72,7 +72,7 @@ CameraLightSource::CameraLightSource(const ghoul::Dictionary& dictionary) , _intensity(IntensityInfo, 1.f, 0.f, 1.f) { addProperty(_intensity); - + documentation::testSpecificationAndThrow(Documentation(), dictionary, "CameraLightSource"); diff --git a/modules/base/lightsource/scenegraphlightsource.cpp b/modules/base/lightsource/scenegraphlightsource.cpp index b672e38bf4..5d13ebd099 100644 --- a/modules/base/lightsource/scenegraphlightsource.cpp +++ b/modules/base/lightsource/scenegraphlightsource.cpp @@ -91,7 +91,7 @@ SceneGraphLightSource::SceneGraphLightSource(const ghoul::Dictionary& dictionary { addProperty(_intensity); addProperty(_sceneGraphNodeReference); - + documentation::testSpecificationAndThrow(Documentation(), dictionary, "SceneGraphLightSource"); diff --git a/modules/base/timeframe/timeframeunion.cpp b/modules/base/timeframe/timeframeunion.cpp index 9b53041764..40efc5c796 100644 --- a/modules/base/timeframe/timeframeunion.cpp +++ b/modules/base/timeframe/timeframeunion.cpp @@ -34,7 +34,7 @@ namespace { constexpr const openspace::properties::Property::PropertyInfo TimeFramesInfo = { "TimeFrames", "Time Frames", - "A vector of time frames to combine into one." + "A vector of time frames to combine into one. " "The time frame is active when any of the contained time frames are, " "but not in gaps between contained time frames." }; @@ -94,8 +94,6 @@ TimeFrameUnion::TimeFrameUnion(const ghoul::Dictionary& dictionary) subFrame.setDescription(k); addPropertySubOwner(*_timeFrames.back()); } - - } } // namespace openspace diff --git a/modules/imgui/src/guispacetimecomponent.cpp b/modules/imgui/src/guispacetimecomponent.cpp index 55a50869f6..ac85089ead 100644 --- a/modules/imgui/src/guispacetimecomponent.cpp +++ b/modules/imgui/src/guispacetimecomponent.cpp @@ -324,14 +324,9 @@ void GuiSpaceTimeComponent::render() { if (valueChanged) { // If the value changed, we want to change the delta time to the new value - double newDeltaTime = convertTime( - _deltaTime, - _deltaTimeUnit, - TimeUnit::Second - ); - + double newDt = convertTime(_deltaTime, _deltaTimeUnit, TimeUnit::Second); OsEng.scriptEngine().queueScript( - "openspace.time.interpolateDeltaTime(" + std::to_string(newDeltaTime) + ")", + "openspace.time.interpolateDeltaTime(" + std::to_string(newDt) + ")", scripting::ScriptEngine::RemoteScripting::No ); } diff --git a/modules/multiresvolume/CMakeLists.txt b/modules/multiresvolume/CMakeLists.txt index 32ffef6400..6686486264 100644 --- a/modules/multiresvolume/CMakeLists.txt +++ b/modules/multiresvolume/CMakeLists.txt @@ -45,8 +45,10 @@ source_group("Header Files" FILES ${HEADER_FILES}) set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/rendering/atlasmanager.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/rendering/brickcover.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/brickmanager.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/rendering/multiresvolumeraycaster.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/rendering/brickselection.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/rendering/multiresvolumeraycaster.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/shenbrickselector.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/tfbrickselector.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/localtfbrickselector.cpp diff --git a/modules/multiresvolume/multiresvolumemodule.cpp b/modules/multiresvolume/multiresvolumemodule.cpp index f7eb813d19..14175dac5b 100644 --- a/modules/multiresvolume/multiresvolumemodule.cpp +++ b/modules/multiresvolume/multiresvolumemodule.cpp @@ -24,14 +24,12 @@ #include +#include #include #include - #include #include -#include - namespace openspace { MultiresVolumeModule::MultiresVolumeModule() : OpenSpaceModule(Name) {} diff --git a/modules/multiresvolume/rendering/atlasmanager.cpp b/modules/multiresvolume/rendering/atlasmanager.cpp index cdb5d856bf..c10a87c406 100644 --- a/modules/multiresvolume/rendering/atlasmanager.cpp +++ b/modules/multiresvolume/rendering/atlasmanager.cpp @@ -25,16 +25,8 @@ #include #include -#include #include #include -#include -#include -#include - -namespace { - constexpr const char* _loggerCat = "AtlasManager"; -} // namespace namespace openspace { @@ -43,17 +35,17 @@ AtlasManager::AtlasManager(TSP* tsp) : _tsp(tsp) {} bool AtlasManager::initialize() { TSP::Header header = _tsp->header(); - _nBricksPerDim = header.xNumBricks_; + _nBricksPerDim = header.xNumBricks; _nOtLeaves = _nBricksPerDim * _nBricksPerDim * _nBricksPerDim; _nOtNodes = _tsp->numOTNodes(); - _nOtLevels = static_cast(log(_nOtLeaves)/log(8) + 1); + _nOtLevels = static_cast(log(_nOtLeaves) / log(8) + 1); _paddedBrickDim = _tsp->paddedBrickDim(); _nBricksInMap = _nBricksPerDim * _nBricksPerDim * _nBricksPerDim; _atlasDim = _nBricksPerDim * _paddedBrickDim; _nBrickVals = _paddedBrickDim*_paddedBrickDim*_paddedBrickDim; _brickSize = _nBrickVals * sizeof(float); _volumeSize = _brickSize * _nOtLeaves; - _atlasMap = std::vector(_nOtLeaves, NOT_USED); + _atlasMap = std::vector(_nOtLeaves, NotUsedIndex); _nBricksInAtlas = _nBricksInMap; _freeAtlasCoords = std::vector(_nBricksInAtlas, 0); @@ -63,9 +55,9 @@ bool AtlasManager::initialize() { } _textureAtlas = new ghoul::opengl::Texture( - glm::size3_t(_atlasDim, _atlasDim, _atlasDim), - ghoul::opengl::Texture::Format::RGBA, - GL_RGBA, + glm::size3_t(_atlasDim, _atlasDim, _atlasDim), + ghoul::opengl::Texture::Format::RGBA, + GL_RGBA, GL_FLOAT ); _textureAtlas->uploadTexture(); @@ -114,10 +106,12 @@ void AtlasManager::updateAtlas(BufferIndex bufferIndex, std::vector& brickI glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _pboHandle[bufferIndex]); glBufferData(GL_PIXEL_UNPACK_BUFFER, _volumeSize, nullptr, GL_STREAM_DRAW); - float* mappedBuffer = reinterpret_cast(glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY)); + float* mappedBuffer = reinterpret_cast( + glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY) + ); if (!mappedBuffer) { - LERROR("Failed to map PBO"); + LERRORC("AtlasManager", "Failed to map PBO"); std::cout << glGetError() << std::endl; return; } @@ -152,7 +146,7 @@ void AtlasManager::updateAtlas(BufferIndex bufferIndex, std::vector& brickI pboToAtlas(bufferIndex); glBindBuffer(GL_SHADER_STORAGE_BUFFER, _atlasMapBuffer); - GLint *to = reinterpret_cast( + GLint* to = reinterpret_cast( glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_WRITE_ONLY) ); memcpy(to, _atlasMap.data(), sizeof(GLint)*_atlasMap.size()); @@ -160,16 +154,25 @@ void AtlasManager::updateAtlas(BufferIndex bufferIndex, std::vector& brickI glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); } -void AtlasManager::addToAtlas(int firstBrickIndex, int lastBrickIndex, float* mappedBuffer) { - while (_brickMap.count(firstBrickIndex) && firstBrickIndex <= lastBrickIndex) firstBrickIndex++; - while (_brickMap.count(lastBrickIndex) && lastBrickIndex >= firstBrickIndex) lastBrickIndex--; - if (lastBrickIndex < firstBrickIndex) return; +void AtlasManager::addToAtlas(int firstBrickIndex, int lastBrickIndex, + float* mappedBuffer) +{ + while (_brickMap.count(firstBrickIndex) && firstBrickIndex <= lastBrickIndex) { + firstBrickIndex++; + } + while (_brickMap.count(lastBrickIndex) && lastBrickIndex >= firstBrickIndex) { + lastBrickIndex--; + } + if (lastBrickIndex < firstBrickIndex) { + return; + } int sequenceLength = lastBrickIndex - firstBrickIndex + 1; float* sequenceBuffer = new float[sequenceLength*_nBrickVals]; size_t bufferSize = sequenceLength * _brickSize; - long long offset = TSP::dataPosition() + static_cast(firstBrickIndex) * static_cast(_brickSize); + long long offset = TSP::dataPosition() + static_cast(firstBrickIndex) * + static_cast(_brickSize); _tsp->file().seekg(offset); _tsp->file().read(reinterpret_cast(sequenceBuffer), bufferSize); _nDiskReads++; @@ -178,12 +181,18 @@ void AtlasManager::addToAtlas(int firstBrickIndex, int lastBrickIndex, float* ma if (!_brickMap.count(brickIndex)) { unsigned int atlasCoords = _freeAtlasCoords.back(); _freeAtlasCoords.pop_back(); - int level = _nOtLevels - static_cast(floor(log((7.0 * (float(brickIndex % _nOtNodes)) + 1.0))/log(8)) - 1); + int level = _nOtLevels - static_cast( + floor(log((7.0 * (float(brickIndex % _nOtNodes)) + 1.0))/log(8)) - 1 + ); ghoul_assert(atlasCoords <= 0x0FFFFFFF, "@MISSING"); unsigned int atlasData = (level << 28) + atlasCoords; - _brickMap.insert(std::pair(brickIndex, atlasData)); + _brickMap.emplace(brickIndex, atlasData); _nStreamedBricks++; - fillVolume(&sequenceBuffer[_nBrickVals*(brickIndex - firstBrickIndex)], mappedBuffer, atlasCoords); + fillVolume( + &sequenceBuffer[_nBrickVals*(brickIndex - firstBrickIndex)], + mappedBuffer, + atlasCoords + ); } } @@ -213,10 +222,8 @@ void AtlasManager::fillVolume(float* in, float* out, unsigned int linearAtlasCoo for (unsigned int zValCoord = zMin; zValCoorddimensions(); glBindTexture(GL_TEXTURE_3D, *_textureAtlas); glTexSubImage3D( - GL_TEXTURE_3D, // target - 0, // level - 0, // xoffset - 0, // yoffset - 0, // zoffset - static_cast(dim[0]), // width - static_cast(dim[1]), // height - static_cast(dim[2]), // depth - GL_RED, // format - GL_FLOAT, // type - nullptr // *pixels + GL_TEXTURE_3D, + 0, + 0, + 0, + 0, + static_cast(dim[0]), + static_cast(dim[1]), + static_cast(dim[2]), + GL_RED, + GL_FLOAT, + nullptr ); glBindTexture(GL_TEXTURE_3D, 0); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); @@ -251,19 +258,19 @@ ghoul::opengl::Texture& AtlasManager::textureAtlas() { return *_textureAtlas; } -unsigned int AtlasManager::getNumDiskReads() { +unsigned int AtlasManager::numDiskReads() const { return _nDiskReads; } -unsigned int AtlasManager::getNumUsedBricks() { +unsigned int AtlasManager::numUsedBricks() const { return _nUsedBricks; } -unsigned int AtlasManager::getNumStreamedBricks() { +unsigned int AtlasManager::numStreamedBricks() const { return _nStreamedBricks; } -glm::size3_t AtlasManager::textureSize() { +glm::size3_t AtlasManager::textureSize() const { return _textureAtlas->dimensions(); } diff --git a/modules/multiresvolume/rendering/atlasmanager.h b/modules/multiresvolume/rendering/atlasmanager.h index a524125c9d..68b76ee692 100644 --- a/modules/multiresvolume/rendering/atlasmanager.h +++ b/modules/multiresvolume/rendering/atlasmanager.h @@ -40,7 +40,10 @@ class TSP; class AtlasManager { public: - enum BufferIndex { EVEN = 0, ODD = 1 }; + enum BufferIndex { + EVEN = 0, + ODD = 1 + }; AtlasManager(TSP* tsp); ~AtlasManager() = default; @@ -54,14 +57,15 @@ public: void pboToAtlas(BufferIndex bufferIndex); ghoul::opengl::Texture& textureAtlas(); - glm::size3_t textureSize(); - unsigned int getNumDiskReads(); - unsigned int getNumUsedBricks(); - unsigned int getNumStreamedBricks(); + unsigned int numDiskReads() const; + unsigned int numUsedBricks() const; + unsigned int numStreamedBricks() const; + + glm::size3_t textureSize() const; private: - const unsigned int NOT_USED = std::numeric_limits::max(); + const unsigned int NotUsedIndex = std::numeric_limits::max(); TSP* _tsp; unsigned int _pboHandle[2]; diff --git a/modules/multiresvolume/rendering/brickcover.h b/modules/multiresvolume/rendering/brickcover.h index fc6f89ec24..3991781abf 100644 --- a/modules/multiresvolume/rendering/brickcover.h +++ b/modules/multiresvolume/rendering/brickcover.h @@ -28,40 +28,17 @@ namespace openspace { struct BrickCover { - int lowX, highX, lowY, highY, lowZ, highZ; + BrickCover(); + BrickCover(int numBricks); - BrickCover() {} + BrickCover split(bool x, bool y, bool z) const; - BrickCover(int numBricks) { - lowX = lowY = lowZ = 0; - highX = highY = highZ = numBricks; - } - - BrickCover split(bool x, bool y, bool z) { - BrickCover child; - if (x) { - child.lowX = lowX + (highX - lowX) / 2; - child.highX = highX; - } else { - child.lowX = lowX; - child.highX = lowX + (highX - lowX) / 2; - } - if (y) { - child.lowY = lowY + (highY - lowY) / 2; - child.highY = highY; - } else { - child.lowY = lowY; - child.highY = lowY + (highY - lowY) / 2; - } - if (z) { - child.lowZ = lowZ + (highZ - lowZ) / 2; - child.highZ = highZ; - } else { - child.lowZ = lowZ; - child.highZ = lowZ + (highZ - lowZ) / 2; - } - return child; - } + int lowX; + int highX; + int lowY; + int highY; + int lowZ; + int highZ; }; } // namespace openspace diff --git a/modules/multiresvolume/rendering/brickmanager.cpp b/modules/multiresvolume/rendering/brickmanager.cpp index c3875329f0..e79730a6fd 100644 --- a/modules/multiresvolume/rendering/brickmanager.cpp +++ b/modules/multiresvolume/rendering/brickmanager.cpp @@ -24,13 +24,11 @@ #include -#include +#include +#include #include #include - -#include -#include -#include +#include namespace { constexpr const char* _loggerCat = "BrickManager"; @@ -38,86 +36,65 @@ namespace { namespace openspace { -BrickManager::BrickManager(TSP* tsp) +BrickManager::BrickManager(TSP* tsp) : _tsp(tsp) - , numBricks_(0) - , brickDim_(0) - , paddedBrickDim_(0) - , atlasDim_(0) - , numBrickVals_(0) - , numBricksFrame_(0) - , numBricksTree_(0) - , brickSize_(0) - , volumeSize_(0) - , numValsTot_(0) - , xCoord_(0) - , yCoord_(0) - , zCoord_(0) - , textureAtlas_(nullptr) - , hasReadHeader_(false) - , atlasInitialized_(false) {} -BrickManager::~BrickManager() { - -} +BrickManager::~BrickManager() {} bool BrickManager::readHeader() { - - if (!_tsp->file().is_open()) + if (!_tsp->file().is_open()) { return false; + } _header = _tsp->header(); - LDEBUG(fmt::format("Grid type: {}", _header.gridType_)); - LDEBUG(fmt::format("Original num timesteps: {}", _header.numOrigTimesteps_)); - LDEBUG(fmt::format("Num timesteps: {}", _header.numTimesteps_)); + LDEBUG(fmt::format("Grid type: {}", _header.gridType)); + LDEBUG(fmt::format("Original num timesteps: {}", _header.numOrigTimesteps)); + LDEBUG(fmt::format("Num timesteps: {}", _header.numTimesteps)); LDEBUG(fmt::format( - "Brick dims: {} {} {}", - _header.xBrickDim_, - _header.yBrickDim_, - _header.zBrickDim_ + "Brick dims: {} {} {}", _header.xBrickDim, _header.yBrickDim, _header.zBrickDim )); LDEBUG(fmt::format( "Num bricks: {} {} {}", - _header.xNumBricks_, - _header.yNumBricks_, - _header.zNumBricks_ + _header.xNumBricks, + _header.yNumBricks, + _header.zNumBricks )); - brickDim_ = _header.xBrickDim_; - numBricks_ = _header.xNumBricks_; - paddedBrickDim_ = brickDim_ + paddingWidth_ * 2; - atlasDim_ = paddedBrickDim_*numBricks_; + _brickDim = _header.xBrickDim; + _numBricks = _header.xNumBricks; + _paddedBrickDim = _brickDim + _paddingWidth * 2; + _atlasDim = _paddedBrickDim*_numBricks; - LDEBUG(fmt::format("Padded brick dim: {}", paddedBrickDim_)); - LDEBUG(fmt::format("Atlas dim: {}", atlasDim_)); + LDEBUG(fmt::format("Padded brick dim: {}", _paddedBrickDim)); + LDEBUG(fmt::format("Atlas dim: {}", _atlasDim)); - numBrickVals_ = paddedBrickDim_*paddedBrickDim_*paddedBrickDim_; + _numBrickVals = _paddedBrickDim*_paddedBrickDim*_paddedBrickDim; // Number of bricks per frame - numBricksFrame_ = numBricks_*numBricks_*numBricks_; + _numBricksFrame = _numBricks*_numBricks*_numBricks; // Calculate number of bricks in tree unsigned int numOTLevels = static_cast( - log(static_cast(numBricks_)) / log(2) + 1 + log(static_cast(_numBricks)) / log(2) + 1 ); unsigned int numOTNodes = static_cast((pow(8, numOTLevels) - 1) / 7); - unsigned int numBSTNodes = _header.numTimesteps_ * 2 - 1; - numBricksTree_ = numOTNodes * numBSTNodes; + unsigned int numBSTNodes = _header.numTimesteps * 2 - 1; + _numBricksTree = numOTNodes * numBSTNodes; LDEBUG(fmt::format("Num OT levels: {}", numOTLevels)); LDEBUG(fmt::format("Num OT nodes: {}", numOTNodes)); LDEBUG(fmt::format("Num BST nodes: {}", numBSTNodes)); - LDEBUG(fmt::format("Num bricks in tree: {}", numBricksTree_)); - LDEBUG(fmt::format("Num values per brick: {}", numBrickVals_)); + LDEBUG(fmt::format("Num bricks in tree: {}", _numBricksTree)); + LDEBUG(fmt::format("Num values per brick: {}", _numBrickVals)); - brickSize_ = sizeof(float)*numBrickVals_; - volumeSize_ = brickSize_*numBricksFrame_; - numValsTot_ = numBrickVals_*numBricksFrame_; + _brickSize = sizeof(float) * _numBrickVals; + _volumeSize = _brickSize * _numBricksFrame; + _numValsTot = _numBrickVals * _numBricksFrame; _tsp->file().seekg(0, _tsp->file().end); long long fileSize = _tsp->file().tellg(); - long long calcFileSize = static_cast(numBricksTree_)* - static_cast(brickSize_) + TSP::dataPosition(); + long long calcFileSize = static_cast(_numBricksTree) * + static_cast(_brickSize) + TSP::dataPosition(); if (fileSize != calcFileSize) { @@ -127,64 +104,61 @@ bool BrickManager::readHeader() { return false; } - hasReadHeader_ = true; + _hasReadHeader = true; // Hold two brick lists - brickLists_.resize(2); + _brickLists.resize(2); // Make sure the brick list can hold the maximum number of bricks // Each entry holds tree coordinates - brickLists_[EVEN].resize(numBricksTree_ * 3, -1); - brickLists_[ODD].resize(numBricksTree_ * 3, -1); + _brickLists[EVEN].resize(_numBricksTree * 3, -1); + _brickLists[ODD].resize(_numBricksTree * 3, -1); // Allocate space for keeping tracks of bricks in PBO - bricksInPBO_.resize(2); - bricksInPBO_[EVEN].resize(numBricksTree_, -1); - bricksInPBO_[ODD].resize(numBricksTree_, -1); + _bricksInPBO.resize(2); + _bricksInPBO[EVEN].resize(_numBricksTree, -1); + _bricksInPBO[ODD].resize(_numBricksTree, -1); // Allocate space for keeping track of the used coordinates in atlas - usedCoords_.resize(2); - usedCoords_[EVEN].resize(numBricksFrame_, false); - usedCoords_[ODD].resize(numBricksFrame_, false); + _usedCoords.resize(2); + _usedCoords[EVEN].resize(_numBricksFrame, false); + _usedCoords[ODD].resize(_numBricksFrame, false); return true; } bool BrickManager::initialize() { - if (atlasInitialized_) { + if (_atlasInitialized) { LWARNING("InitAtlas() - already initialized"); } - if (!hasReadHeader_) { + if (!_hasReadHeader) { LWARNING("InitAtlas() - Has not read header, trying to read"); return readHeader(); } // Prepare the 3D texture std::vector dims; - dims.push_back(atlasDim_); - dims.push_back(atlasDim_); - dims.push_back(atlasDim_); - textureAtlas_ = new ghoul::opengl::Texture( - glm::size3_t(atlasDim_, atlasDim_, atlasDim_), - ghoul::opengl::Texture::Format::RGBA, - GL_RGBA, - GL_FLOAT); - textureAtlas_->uploadTexture(); - //textureAtlas_ = Texture3D::New(dims); + dims.push_back(_atlasDim); + dims.push_back(_atlasDim); + dims.push_back(_atlasDim); + _textureAtlas = new ghoul::opengl::Texture( + glm::size3_t(_atlasDim, _atlasDim, _atlasDim), + ghoul::opengl::Texture::Format::RGBA, + GL_RGBA, + GL_FLOAT + ); + _textureAtlas->uploadTexture(); - //if (!textureAtlas_->Init()) return false; + _atlasInitialized = true; - atlasInitialized_ = true; - - - glGenBuffers(2, pboHandle_); + glGenBuffers(2, _pboHandle); return true; } -bool BrickManager::BuildBrickList(BUFFER_INDEX _bufIdx, - std::vector &_brickRequest) { - +bool BrickManager::buildBrickList(BUFFER_INDEX bufferIndex, + std::vector &brickRequest) +{ // Keep track of number bricks used and number of bricks cached // (for benchmarking) int numBricks = 0; @@ -193,100 +167,84 @@ bool BrickManager::BuildBrickList(BUFFER_INDEX _bufIdx, // For every non-zero entry in the request list, assign a texture atlas // coordinate. For zero entries, signal "no brick" using -1. - for (unsigned int i = 0; i<_brickRequest.size(); ++i) { - - if (_brickRequest[i] > 0) { - + for (unsigned int i = 0; i < brickRequest.size(); ++i) { + if (brickRequest[i] > 0) { numBricks++; //INFO("Checking brick " << i); // If the brick is already in the atlas, keep the coordinate - if (bricksInPBO_[_bufIdx][i] != -1) { - + if (_bricksInPBO[bufferIndex][i] != -1) { numCached++; // Get the corresponding coordinates from index int x, y, z; - CoordsFromLin(bricksInPBO_[_bufIdx][i], x, y, z); - brickLists_[_bufIdx][3 * i + 0] = x; - brickLists_[_bufIdx][3 * i + 1] = y; - brickLists_[_bufIdx][3 * i + 2] = z; + coordinatesFromLinear(_bricksInPBO[bufferIndex][i], x, y, z); + _brickLists[bufferIndex][3 * i + 0] = x; + _brickLists[bufferIndex][3 * i + 1] = y; + _brickLists[bufferIndex][3 * i + 2] = z; // Mark coordinate as used - usedCoords_[_bufIdx][bricksInPBO_[_bufIdx][i]] = true; - + _usedCoords[bufferIndex][_bricksInPBO[bufferIndex][i]] = true; } else { - - // If coord is already usedi by another brick, + // If coord is already usedi by another brick, // skip it and try the next one - while (usedCoords_[_bufIdx][LinearCoord(xCoord_, yCoord_, zCoord_)]) { - IncCoord(); + while (_usedCoords[bufferIndex][ + linearCoordinates(_xCoord, _yCoord, _zCoord) + ]) + { + incrementCoordinates(); } - brickLists_[_bufIdx][3 * i + 0] = xCoord_; - brickLists_[_bufIdx][3 * i + 1] = yCoord_; - brickLists_[_bufIdx][3 * i + 2] = zCoord_; - usedCoords_[_bufIdx][LinearCoord(xCoord_, yCoord_, zCoord_)] = true; + _brickLists[bufferIndex][3 * i + 0] = _xCoord; + _brickLists[bufferIndex][3 * i + 1] = _yCoord; + _brickLists[bufferIndex][3 * i + 2] = _zCoord; + _usedCoords[bufferIndex][ + linearCoordinates(_xCoord, _yCoord, _zCoord) + ] = true; - IncCoord(); + incrementCoordinates(); } - - } else { - // -1 is for "not used" - brickLists_[_bufIdx][3 * i + 0] = -1; - brickLists_[_bufIdx][3 * i + 1] = -1; - brickLists_[_bufIdx][3 * i + 2] = -1; - + _brickLists[bufferIndex][3 * i + 0] = -1; + _brickLists[bufferIndex][3 * i + 1] = -1; + _brickLists[bufferIndex][3 * i + 2] = -1; } // Reset brick list during iteration - _brickRequest[i] = 0; - + brickRequest[i] = 0; } - // Brick list is build, reset coordinate list - for (auto it = usedCoords_[_bufIdx].begin(); - it != usedCoords_[_bufIdx].end(); ++it) { - *it = false; - } - - //INFO("bricks NOT used: " << (float)(numBricksFrame_-numBricks) / (float)(numBricksFrame_)); - //INFO("bricks cached: " << (float)numCached / (float)(numBricksFrame_)); + std::fill(_usedCoords[bufferIndex].begin(), _usedCoords[bufferIndex].end(), false); return true; } -bool BrickManager::FillVolume(float *_in, float *_out, - unsigned int _x, - unsigned int _y, - unsigned int _z) { +bool BrickManager::fillVolume(float* in, float* out, unsigned int x, unsigned int y, + unsigned int z) +{ //timer_.start(); - unsigned int xMin = _x*paddedBrickDim_; - unsigned int yMin = _y*paddedBrickDim_; - unsigned int zMin = _z*paddedBrickDim_; - unsigned int xMax = xMin + paddedBrickDim_; - unsigned int yMax = yMin + paddedBrickDim_; - unsigned int zMax = zMin + paddedBrickDim_; + unsigned int xMin = x * _paddedBrickDim; + unsigned int yMin = y * _paddedBrickDim; + unsigned int zMin = z * _paddedBrickDim; + unsigned int xMax = xMin + _paddedBrickDim; + unsigned int yMax = yMin + _paddedBrickDim; + unsigned int zMax = zMin + _paddedBrickDim; // Loop over the brick using three loops unsigned int from = 0; - for (unsigned int zValCoord = zMin; zValCoord(_header.xNumBricks_)) { - xCoord_ = 0; - yCoord_++; - if (yCoord_ == static_cast(_header.yNumBricks_)) { - yCoord_ = 0; - zCoord_++; - if (zCoord_ == static_cast(_header.zNumBricks_)) { - zCoord_ = 0; + _xCoord++; + if (_xCoord == static_cast(_header.xNumBricks)) { + _xCoord = 0; + _yCoord++; + if (_yCoord == static_cast(_header.yNumBricks)) { + _yCoord = 0; + _zCoord++; + if (_zCoord == static_cast(_header.zNumBricks)) { + _zCoord = 0; } } } } -unsigned int BrickManager::LinearCoord(int _x, int _y, int _z) { - return _x + _y*_header.xNumBricks_ + _z*_header.xNumBricks_*_header.yNumBricks_; +unsigned int BrickManager::linearCoordinates(int x, int y, int z) { + return x + y * _header.xNumBricks + z * _header.xNumBricks * _header.yNumBricks; } -void BrickManager::CoordsFromLin(int _idx, int &_x, int &_y, int &_z) { - _x = _idx % _header.xNumBricks_; - _idx /= _header.xNumBricks_; - _y = _idx % _header.yNumBricks_; - _idx /= _header.yNumBricks_; - _z = _idx; +void BrickManager::coordinatesFromLinear(int idx, int& x, int& y, int& z) { + x = idx % _header.xNumBricks; + idx /= _header.xNumBricks; + y = idx % _header.yNumBricks; + idx /= _header.yNumBricks; + z = idx; } - -bool BrickManager::DiskToPBO(BUFFER_INDEX _pboIndex) { - +bool BrickManager::diskToPBO(BUFFER_INDEX pboIndex) { // Map PBO - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pboHandle_[_pboIndex]); - glBufferData(GL_PIXEL_UNPACK_BUFFER, volumeSize_, nullptr, GL_STREAM_DRAW); - float *mappedBuffer = reinterpret_cast( + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _pboHandle[pboIndex]); + glBufferData(GL_PIXEL_UNPACK_BUFFER, _volumeSize, nullptr, GL_STREAM_DRAW); + float* mappedBuffer = reinterpret_cast( glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY) ); @@ -339,18 +295,18 @@ bool BrickManager::DiskToPBO(BUFFER_INDEX _pboIndex) { // Loop over brick request list unsigned int brickIndex = 0; - while (brickIndex < brickLists_[_pboIndex].size() / 3) { - + while (brickIndex < _brickLists[pboIndex].size() / 3) { // Find first active brick index in list - while (brickIndex(brickIndex) * - static_cast(brickSize_); + static_cast(_brickSize); */ long long offset = TSP::dataPosition() + - static_cast(brickIndex)* - static_cast(brickSize_); + static_cast(brickIndex) * static_cast(_brickSize); // Skip reading if all bricks in sequence is already in PBO if (inPBO != sequence) { - //timer_.start(); /* @@ -398,7 +353,7 @@ bool BrickManager::DiskToPBO(BUFFER_INDEX _pboIndex) { return false; } INFO("in.tellg(): " << in_.tellg()); - in_.read(reinterpret_cast(seqBuffer), brickSize_*sequence); + in_.read(reinterpret_cast(seqBuffer), _brickSize*sequence); */ _tsp->file().seekg(offset); @@ -407,34 +362,33 @@ bool BrickManager::DiskToPBO(BUFFER_INDEX _pboIndex) { //timer_.stop(); //double time = timer_.elapsed().wall / 1.0e9; - //double mb = (brickSize_*sequence) / 1048576.0; + //double mb = (_brickSize*sequence) / 1048576.0; //INFO("Disk read "<( - brickLists_[_pboIndex][3 * (brickIndex + i) + 0]); + _brickLists[pboIndex][3 * (brickIndex + i) + 0] + ); unsigned int y = static_cast( - brickLists_[_pboIndex][3 * (brickIndex + i) + 1]); + _brickLists[pboIndex][3 * (brickIndex + i) + 1] + ); unsigned int z = static_cast( - brickLists_[_pboIndex][3 * (brickIndex + i) + 2]); + _brickLists[pboIndex][3 * (brickIndex + i) + 2] + ); // Put each brick in the correct buffer place. // This needs to be done because the values are in brick order, and // the volume needs to be filled with one big float array. - FillVolume(&seqBuffer[numBrickVals_*i], mappedBuffer, x, y, z); + fillVolume(&seqBuffer[_numBrickVals*i], mappedBuffer, x, y, z); // Update the atlas list since the brick will be uploaded //INFO(brickIndex+i); - bricksInPBO_[_pboIndex][brickIndex + i] = LinearCoord(x, y, z); - + _bricksInPBO[pboIndex][brickIndex + i] = linearCoordinates(x, y, z); } } } // if in pbo @@ -451,22 +405,22 @@ bool BrickManager::DiskToPBO(BUFFER_INDEX _pboIndex) { return true; } -bool BrickManager::PBOToAtlas(BUFFER_INDEX _pboIndex) { - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pboHandle_[_pboIndex]); - glm::size3_t dim = textureAtlas_->dimensions(); - glBindTexture(GL_TEXTURE_3D, *textureAtlas_); +bool BrickManager::pboToAtlas(BUFFER_INDEX _pboIndex) { + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _pboHandle[_pboIndex]); + glm::size3_t dim = _textureAtlas->dimensions(); + glBindTexture(GL_TEXTURE_3D, *_textureAtlas); glTexSubImage3D( - GL_TEXTURE_3D, // target - 0, // level - 0, // xoffset - 0, // yoffset - 0, // zoffset - static_cast(dim[0]), // width - static_cast(dim[1]), // height - static_cast(dim[2]), // depth - GL_RED, // format - GL_FLOAT, // type - nullptr // *pixels + GL_TEXTURE_3D, + 0, + 0, + 0, + 0, + static_cast(dim[0]), + static_cast(dim[1]), + static_cast(dim[2]), + GL_RED, + GL_FLOAT, + nullptr ); glBindTexture(GL_TEXTURE_3D, 0); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); @@ -475,15 +429,15 @@ bool BrickManager::PBOToAtlas(BUFFER_INDEX _pboIndex) { } ghoul::opengl::Texture* BrickManager::textureAtlas() { - return textureAtlas_; + return _textureAtlas; } -unsigned int BrickManager::pbo(BUFFER_INDEX _pboIndex) { - return pboHandle_[_pboIndex]; +unsigned int BrickManager::pbo(BUFFER_INDEX pboIndex) const { + return _pboHandle[pboIndex]; } const std::vector& BrickManager::brickList(BUFFER_INDEX index) const { - return brickLists_.at(index); + return _brickLists.at(index); } -} +} // namespace diff --git a/modules/multiresvolume/rendering/brickmanager.h b/modules/multiresvolume/rendering/brickmanager.h index 1f40759a39..e8580fdbd3 100644 --- a/modules/multiresvolume/rendering/brickmanager.h +++ b/modules/multiresvolume/rendering/brickmanager.h @@ -27,7 +27,6 @@ #include -#include #include namespace ghoul::opengl { class Texture; } @@ -45,61 +44,58 @@ public: bool initialize(); - bool BuildBrickList(BUFFER_INDEX _bufIdx, std::vector &_brickRequest); + bool buildBrickList(BUFFER_INDEX bufferIndex, std::vector& brickRequest); - bool FillVolume(float *_in, float *_out, - unsigned int _x, - unsigned int _y, - unsigned int _z); - bool DiskToPBO(BUFFER_INDEX _pboIndex); - bool PBOToAtlas(BUFFER_INDEX _pboIndex); + bool fillVolume(float* in, float* out, unsigned int x, unsigned int y, + unsigned int z); + bool diskToPBO(BUFFER_INDEX pboIndex); + bool pboToAtlas(BUFFER_INDEX pboIndex); ghoul::opengl::Texture* textureAtlas(); - unsigned int pbo(BUFFER_INDEX _pboIndex); + unsigned int pbo(BUFFER_INDEX pboIndex) const; const std::vector& brickList(BUFFER_INDEX index) const; private: + void incrementCoordinates(); + unsigned int linearCoordinates(int x, int y, int z); + void coordinatesFromLinear(int idx, int& x, int& y, int& z); - void IncCoord(); - unsigned int LinearCoord(int _x, int _y, int _z); - void CoordsFromLin(int _idx, int &_x, int &_y, int &_z); - - TSP* _tsp; + TSP* _tsp = nullptr; TSP::Header _header; - unsigned int numBricks_; - unsigned int brickDim_; - unsigned int paddedBrickDim_; - unsigned int atlasDim_; + unsigned int _numBricks = 0; + unsigned int _brickDim = 0; + unsigned int _paddedBrickDim = 0; + unsigned int _atlasDim = 0; - const unsigned int paddingWidth_ = 1; + const unsigned int _paddingWidth = 1; - unsigned int numBrickVals_; - unsigned int numBricksFrame_; - unsigned int numBricksTree_; - unsigned int brickSize_; - unsigned int volumeSize_; - unsigned int numValsTot_; + unsigned int _numBrickVals = 0; + unsigned int _numBricksFrame = 0; + unsigned int _numBricksTree = 0; + unsigned int _brickSize = 0; + unsigned int _volumeSize = 0; + unsigned int _numValsTot = 0; // Texture coordinates to be assigned - int xCoord_; - int yCoord_; - int zCoord_; + int _xCoord = 0; + int _yCoord = 0; + int _zCoord = 0; // Texture where the actual atlas is kept - ghoul::opengl::Texture* textureAtlas_; + ghoul::opengl::Texture* _textureAtlas = nullptr; - std::vector > brickLists_; + std::vector> _brickLists; - bool hasReadHeader_; - bool atlasInitialized_; + bool _hasReadHeader = false; + bool _atlasInitialized = false; // PBOs - unsigned int pboHandle_[2]; + unsigned int _pboHandle[2]; // Caching, one for each PBO - std::vector > bricksInPBO_; - std::vector > usedCoords_; + std::vector> _bricksInPBO; + std::vector> _usedCoords; }; } // namespace openspace diff --git a/modules/multiresvolume/rendering/brickselection.h b/modules/multiresvolume/rendering/brickselection.h index e12c73269e..9d7dfe852a 100644 --- a/modules/multiresvolume/rendering/brickselection.h +++ b/modules/multiresvolume/rendering/brickselection.h @@ -36,6 +36,19 @@ struct BrickSelection { Spatial = 2 }; + BrickSelection(); + BrickSelection(int numBricks, int numTimeSteps, SplitType splitType, + float splitPoints); + + BrickSelection splitSpatially(bool x, bool y, bool z, unsigned int childBrickIndex, + SplitType childSplitType, float childSplitPoints); + + BrickSelection splitTemporally(bool t, unsigned int childBrickIndex, + SplitType childSplitType, float childSplitPoints); + + int centerT() const; + bool timestepInRightChild(int timestep) const; + unsigned int brickIndex; float splitPoints; BrickSelection::SplitType splitType; @@ -44,69 +57,6 @@ struct BrickSelection { int highT; int nSpatialSplits; int nTemporalSplits; - - BrickSelection() {} - - BrickSelection(int numBricks, int numTimeSteps, SplitType splitType_, - float splitPoints_) - { - cover = BrickCover(numBricks); - lowT = 0; - highT = numTimeSteps; - brickIndex = 0; - splitType = splitType_; - splitPoints = splitPoints_; - nSpatialSplits = 0; - nTemporalSplits = 0; - } - - BrickSelection splitSpatially(bool x, bool y, bool z, unsigned int childBrickIndex, - SplitType childSplitType, float childSplitPoints) - { - BrickSelection child; - child.cover = cover.split(x, y, z); - child.brickIndex = childBrickIndex; - child.splitPoints = childSplitPoints; - child.splitType = childSplitType; - child.nSpatialSplits = nSpatialSplits + 1; - child.nTemporalSplits = nTemporalSplits; - child.lowT = lowT; - child.highT = highT; - return child; - } - - BrickSelection splitTemporally(bool t, unsigned int childBrickIndex, - SplitType childSplitType, float childSplitPoints) - { - BrickSelection child; - child.cover = cover; - child.brickIndex = childBrickIndex; - child.splitPoints = childSplitPoints; - child.splitType = childSplitType; - if (t) { - child.lowT = centerT(); - child.highT = highT; - } else { - child.lowT = lowT; - child.highT = centerT(); - } - child.nSpatialSplits = nSpatialSplits; - child.nTemporalSplits = nTemporalSplits + 1; - - return child; - } - - int centerT() { - return lowT + (highT - lowT) / 2; - } - - bool timestepInRightChild(int timestep) { - return timestep >= centerT(); - } - - static bool compareSplitPoints(const BrickSelection& a, const BrickSelection& b) { - return a.splitPoints < b.splitPoints; - } }; } // namespace openspace diff --git a/modules/multiresvolume/rendering/brickselector.h b/modules/multiresvolume/rendering/brickselector.h index 881b24028d..b86762e2c8 100644 --- a/modules/multiresvolume/rendering/brickselector.h +++ b/modules/multiresvolume/rendering/brickselector.h @@ -33,8 +33,7 @@ class BrickSelector { public: virtual ~BrickSelector() {}; virtual bool initialize() { return true; }; - virtual void selectBricks(int timestep, - std::vector& bricks) = 0; + virtual void selectBricks(int timestep, std::vector& bricks) = 0; }; } // namespace openspace diff --git a/modules/multiresvolume/rendering/errorhistogrammanager.cpp b/modules/multiresvolume/rendering/errorhistogrammanager.cpp index 01a6f51fb4..1cfc3de1ad 100644 --- a/modules/multiresvolume/rendering/errorhistogrammanager.cpp +++ b/modules/multiresvolume/rendering/errorhistogrammanager.cpp @@ -22,29 +22,17 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include -#include -#include -#include - #include -#include +#include #include - #include #include -namespace { - constexpr const char* _loggerCat = "ErrorHistogramManager"; -} // namespace - namespace openspace { ErrorHistogramManager::ErrorHistogramManager(TSP* tsp) : _tsp(tsp) {} -ErrorHistogramManager::~ErrorHistogramManager() {} - bool ErrorHistogramManager::buildHistograms(int numBins) { _numBins = numBins; @@ -52,8 +40,8 @@ bool ErrorHistogramManager::buildHistograms(int numBins) { if (!_file->is_open()) { return false; } - _minBin = 0.0; // Should be calculated from tsp file - _maxBin = 1.0; // Should be calculated from tsp file as (maxValue - minValue) + _minBin = 0.f; // Should be calculated from tsp file + _maxBin = 1.f; // Should be calculated from tsp file as (maxValue - minValue) unsigned int numOtLevels = _tsp->numOTLevels(); unsigned int numOtLeaves = static_cast(pow(8, numOtLevels - 1)); @@ -63,11 +51,14 @@ bool ErrorHistogramManager::buildHistograms(int numBins) { _numInnerNodes = _tsp->numTotalNodes() - numOtLeaves * numBstLeaves; _histograms = std::vector(_numInnerNodes); - LINFO(fmt::format("Build {} histograms with {} bins each", _numInnerNodes, numBins)); + LINFOC( + "ErrorHistogramManager", + fmt::format("Build {} histograms with {} bins each", _numInnerNodes, numBins) + ); // All TSP Leaves int numOtNodes = _tsp->numOTNodes(); - int otOffset = (pow(8, numOtLevels - 1) - 1) / 7; + int otOffset = static_cast((pow(8, numOtLevels - 1) - 1) / 7); int numBstNodes = _tsp->numBSTNodes(); int bstOffset = numBstNodes / 2; @@ -79,7 +70,9 @@ bool ErrorHistogramManager::buildHistograms(int numBins) { for (int bst = bstOffset; bst < numBstNodes; bst++) { for (int ot = otOffset; ot < numOtNodes; ot++) { success &= buildFromLeaf(bst, ot); - if (!success) return false; + if (!success) { + return false; + } pb.print(++processedLeaves); } } @@ -87,7 +80,9 @@ bool ErrorHistogramManager::buildHistograms(int numBins) { return success; } -bool ErrorHistogramManager::buildFromLeaf(unsigned int bstOffset, unsigned int octreeOffset) { +bool ErrorHistogramManager::buildFromLeaf(unsigned int bstOffset, + unsigned int octreeOffset) +{ // Traverse all ancestors of leaf and add errors to their histograms unsigned int brickDim = _tsp->brickDim(); @@ -104,8 +99,7 @@ bool ErrorHistogramManager::buildFromLeaf(unsigned int bstOffset, unsigned int o unsigned int bstLevel = 0; do { - - glm::vec3 leafOffset(0.0); // Leaf offset in leaf sized voxels + glm::vec3 leafOffset(0.f); // Leaf offset in leaf sized voxels unsigned int octreeLevel = 0; unsigned int octreeNode = octreeOffset; bool octreeLastOnly = true; @@ -127,21 +121,31 @@ bool ErrorHistogramManager::buildFromLeaf(unsigned int bstOffset, unsigned int o ancestorVoxels = it->second; } - float voxelScale = pow(2, octreeLevel); - float invVoxelScale = 1.0 / voxelScale; + float voxelScale = static_cast(pow(2.f, octreeLevel)); + float invVoxelScale = 1.f / voxelScale; // Calculate leaf offset in ancestor sized voxels - glm::vec3 ancestorOffset = (leafOffset * invVoxelScale) + glm::vec3(padding - 0.5); + glm::vec3 ancestorOffset = (leafOffset * invVoxelScale) + + glm::vec3(padding - 0.5f); for (int z = 0; z < static_cast(brickDim); z++) { for (int y = 0; y < static_cast(brickDim); y++) { for (int x = 0; x < static_cast(brickDim); x++) { - glm::vec3 leafSamplePoint = glm::vec3(x, y, z) + glm::vec3(padding); - glm::vec3 ancestorSamplePoint = ancestorOffset + (glm::vec3(x, y, z) + glm::vec3(0.5)) * invVoxelScale; + glm::vec3 leafSamplePoint = glm::vec3(x, y, z) + + glm::vec3(static_cast(padding)); + glm::vec3 ancestorSamplePoint = ancestorOffset + + (glm::vec3(x, y, z) + glm::vec3(0.5)) * invVoxelScale; float leafValue = leafValues[linearCoords(leafSamplePoint)]; - float ancestorValue = interpolate(ancestorSamplePoint, ancestorVoxels); + float ancestorValue = interpolate( + ancestorSamplePoint, + ancestorVoxels + ); - _histograms[innerNodeIndex].addRectangle(leafValue, ancestorValue, std::abs(leafValue - ancestorValue)); + _histograms[innerNodeIndex].addRectangle( + leafValue, + ancestorValue, + std::abs(leafValue - ancestorValue) + ); } } } @@ -156,7 +160,7 @@ bool ErrorHistogramManager::buildFromLeaf(unsigned int bstOffset, unsigned int o octreeLastOnly &= octreeChild == 7; octreeNode = parentOffset(octreeNode, 8); - int childSize = pow(2, octreeLevel) * brickDim; + int childSize = static_cast(pow(2, octreeLevel) * brickDim); leafOffset.x += (octreeChild % 2) * childSize; leafOffset.y += ((octreeChild / 2) % 2) * childSize; leafOffset.z += (octreeChild / 4) * childSize; @@ -191,8 +195,8 @@ bool ErrorHistogramManager::loadFromFile(const std::string& filename) { _histograms = std::vector(_numInnerNodes); - for (int i = 0; i < _numInnerNodes; ++i) { - int offset = i*_numBins; + for (int i = 0; i < static_cast(_numInnerNodes); ++i) { + int offset = i * _numBins; float* data = new float[_numBins]; memcpy(data, &histogramData[offset], sizeof(float) * _numBins); _histograms[i] = Histogram(_minBin, _maxBin, _numBins, data); @@ -231,7 +235,7 @@ bool ErrorHistogramManager::saveToFile(const std::string& filename) { return true; } -unsigned int ErrorHistogramManager::linearCoords(glm::vec3 coords) const { +unsigned int ErrorHistogramManager::linearCoords(const glm::vec3& coords) const { return linearCoords(glm::ivec3(coords)); } @@ -239,47 +243,50 @@ unsigned int ErrorHistogramManager::linearCoords(int x, int y, int z) const { return linearCoords(glm::ivec3(x, y, z)); } -unsigned int ErrorHistogramManager::linearCoords(glm::ivec3 coords) const { - unsigned int paddedBrickDim = _tsp->paddedBrickDim(); - return coords.z * paddedBrickDim * paddedBrickDim + coords.y * paddedBrickDim + coords.x; +unsigned int ErrorHistogramManager::linearCoords(const glm::ivec3& coords) const { + const unsigned int paddedBrickDim = _tsp->paddedBrickDim(); + return coords.z * paddedBrickDim * paddedBrickDim + + coords.y * paddedBrickDim + coords.x; } -float ErrorHistogramManager::interpolate(glm::vec3 samplePoint, const std::vector& voxels) const { - int lowX = samplePoint.x; - int lowY = samplePoint.y; - int lowZ = samplePoint.z; +float ErrorHistogramManager::interpolate(const glm::vec3& samplePoint, + const std::vector& voxels) const +{ + const int lowX = static_cast(samplePoint.x); + const int lowY = static_cast(samplePoint.y); + const int lowZ = static_cast(samplePoint.z); - int highX = ceil(samplePoint.x); - int highY = ceil(samplePoint.y); - int highZ = ceil(samplePoint.z); + const int highX = static_cast(ceil(samplePoint.x)); + const int highY = static_cast(ceil(samplePoint.y)); + const int highZ = static_cast(ceil(samplePoint.z)); - float interpolatorX = 1.0 - (samplePoint.x - lowX); - float interpolatorY = 1.0 - (samplePoint.y - lowY); - float interpolatorZ = 1.0 - (samplePoint.z - lowZ); + const float interpolatorX = 1.f - (samplePoint.x - lowX); + const float interpolatorY = 1.f - (samplePoint.y - lowY); + const float interpolatorZ = 1.f - (samplePoint.z - lowZ); - float v000 = voxels[linearCoords(lowX, lowY, lowZ)]; - float v001 = voxels[linearCoords(lowX, lowY, highZ)]; - float v010 = voxels[linearCoords(lowX, highY, lowZ)]; - float v011 = voxels[linearCoords(lowX, highY, highZ)]; - float v100 = voxels[linearCoords(highX, lowY, lowZ)]; - float v101 = voxels[linearCoords(highX, lowY, highZ)]; - float v110 = voxels[linearCoords(highX, highY, lowZ)]; - float v111 = voxels[linearCoords(highX, highY, highZ)]; + const float v000 = voxels[linearCoords(lowX, lowY, lowZ)]; + const float v001 = voxels[linearCoords(lowX, lowY, highZ)]; + const float v010 = voxels[linearCoords(lowX, highY, lowZ)]; + const float v011 = voxels[linearCoords(lowX, highY, highZ)]; + const float v100 = voxels[linearCoords(highX, lowY, lowZ)]; + const float v101 = voxels[linearCoords(highX, lowY, highZ)]; + const float v110 = voxels[linearCoords(highX, highY, lowZ)]; + const float v111 = voxels[linearCoords(highX, highY, highZ)]; - float v00 = interpolatorZ * v000 + (1.0 - interpolatorZ) * v001; - float v01 = interpolatorZ * v010 + (1.0 - interpolatorZ) * v011; - float v10 = interpolatorZ * v100 + (1.0 - interpolatorZ) * v101; - float v11 = interpolatorZ * v110 + (1.0 - interpolatorZ) * v111; + const float v00 = interpolatorZ * v000 + (1.f - interpolatorZ) * v001; + const float v01 = interpolatorZ * v010 + (1.f - interpolatorZ) * v011; + const float v10 = interpolatorZ * v100 + (1.f - interpolatorZ) * v101; + const float v11 = interpolatorZ * v110 + (1.f - interpolatorZ) * v111; - float v0 = interpolatorY * v00 + (1.0 - interpolatorY) * v01; - float v1 = interpolatorY * v10 + (1.0 - interpolatorY) * v11; + const float v0 = interpolatorY * v00 + (1.f - interpolatorY) * v01; + const float v1 = interpolatorY * v10 + (1.f - interpolatorY) * v11; - return interpolatorX * v0 + (1.0 - interpolatorX) * v1; + return interpolatorX * v0 + (1.f - interpolatorX) * v1; } -const Histogram* ErrorHistogramManager::getHistogram(unsigned int brickIndex) const { - unsigned int innerNodeIndex = brickToInnerNodeIndex(brickIndex); +const Histogram* ErrorHistogramManager::histogram(unsigned int brickIndex) const { + const unsigned int innerNodeIndex = brickToInnerNodeIndex(brickIndex); if (innerNodeIndex < _numInnerNodes) { return &(_histograms[innerNodeIndex]); } else { @@ -291,72 +298,98 @@ int ErrorHistogramManager::parentOffset(int offset, int base) const { if (offset == 0) { return -1; } - int depth = floor(log(((base - 1) * offset + 1.0)) / log(base)); - int firstInLevel = (pow(base, depth) - 1) / (base - 1); - int inLevelOffset = offset - firstInLevel; + const int depth = static_cast( + floor(log(((base - 1) * offset + 1.0)) / log(base)) + ); + const int firstInLevel = static_cast((pow(base, depth) - 1) / (base - 1)); + const int inLevelOffset = offset - firstInLevel; - int parentDepth = depth - 1; - int firstInParentLevel = (pow(base, parentDepth) - 1) / (base - 1); - int parentInLevelOffset = inLevelOffset / base; + const int parentDepth = depth - 1; + const int firstInParentLevel = static_cast( + (pow(base, parentDepth) - 1) / (base - 1) + ); + const int parentInLevelOffset = inLevelOffset / base; - int parentOffset = firstInParentLevel + parentInLevelOffset; + const int parentOffset = firstInParentLevel + parentInLevelOffset; return parentOffset; } std::vector ErrorHistogramManager::readValues(unsigned int brickIndex) const { - unsigned int paddedBrickDim = _tsp->paddedBrickDim(); - unsigned int numBrickVals = paddedBrickDim * paddedBrickDim * paddedBrickDim; + const unsigned int paddedBrickDim = _tsp->paddedBrickDim(); + const unsigned int numBrickVals = paddedBrickDim * paddedBrickDim * paddedBrickDim; std::vector voxelValues(numBrickVals); - std::streampos offset = _tsp->dataPosition() + static_cast(brickIndex*numBrickVals*sizeof(float)); + std::streampos offset = _tsp->dataPosition() + + static_cast(brickIndex*numBrickVals*sizeof(float)); _file->seekg(offset); - _file->read(reinterpret_cast(&voxelValues[0]), - static_cast(numBrickVals)*sizeof(float)); + _file->read( + reinterpret_cast(voxelValues.data()), + static_cast(numBrickVals)*sizeof(float) + ); return voxelValues; } unsigned int ErrorHistogramManager::brickToInnerNodeIndex(unsigned int brickIndex) const { - unsigned int numOtNodes = _tsp->numOTNodes(); - unsigned int numBstLevels = _tsp->numBSTLevels(); + const unsigned int numOtNodes = _tsp->numOTNodes(); + const unsigned int numBstLevels = _tsp->numBSTLevels(); - unsigned int numInnerBstNodes = (pow(2, numBstLevels - 1) - 1) * numOtNodes; - if (brickIndex < numInnerBstNodes) return brickIndex; + const unsigned int numInnerBstNodes = static_cast( + (pow(2, numBstLevels - 1) - 1) * numOtNodes + ); + if (brickIndex < numInnerBstNodes) { + return brickIndex; + } - unsigned int numOtLeaves = pow(8, _tsp->numOTLevels() - 1); - unsigned int numOtInnerNodes = (numOtNodes - numOtLeaves); + const unsigned int numOtLeaves = static_cast( + pow(8, _tsp->numOTLevels() - 1) + ); + const unsigned int numOtInnerNodes = (numOtNodes - numOtLeaves); - unsigned int innerBstOffset = brickIndex - numInnerBstNodes; - unsigned int rowIndex = innerBstOffset / numOtNodes; - unsigned int indexInRow = innerBstOffset % numOtNodes; + const unsigned int innerBstOffset = brickIndex - numInnerBstNodes; + const unsigned int rowIndex = innerBstOffset / numOtNodes; + const unsigned int indexInRow = innerBstOffset % numOtNodes; - if (indexInRow >= numOtInnerNodes) return -1; + if (indexInRow >= numOtInnerNodes) { + return std::numeric_limits::max(); + } - unsigned int offset = rowIndex * numOtInnerNodes; - unsigned int leavesOffset = offset + indexInRow; + const unsigned int offset = rowIndex * numOtInnerNodes; + const unsigned int leavesOffset = offset + indexInRow; return numInnerBstNodes + leavesOffset; } -unsigned int ErrorHistogramManager::innerNodeToBrickIndex(unsigned int innerNodeIndex) const { - if (innerNodeIndex < 0 || innerNodeIndex >= _numInnerNodes) return -1; // Not an inner node +unsigned int ErrorHistogramManager::innerNodeToBrickIndex( + unsigned int innerNodeIndex) const +{ + // @TODO(abock): innerNodeIndex is an unsigned int, so it will never be < 0 + if (innerNodeIndex < 0 || innerNodeIndex >= _numInnerNodes) { + return std::numeric_limits::max(); // Not an inner node + } - unsigned int numOtNodes = _tsp->numOTNodes(); - unsigned int numBstLevels = _tsp->numBSTLevels(); + const unsigned int numOtNodes = _tsp->numOTNodes(); + const unsigned int numBstLevels = _tsp->numBSTLevels(); - unsigned int numInnerBstNodes = (pow(2, numBstLevels - 1) - 1) * numOtNodes; - if (innerNodeIndex < numInnerBstNodes) return innerNodeIndex; + const unsigned int numInnerBstNodes = static_cast( + (pow(2, numBstLevels - 1) - 1) * numOtNodes + ); + if (innerNodeIndex < numInnerBstNodes) { + return innerNodeIndex; + } - unsigned int numOtLeaves = pow(8, _tsp->numOTLevels() - 1); - unsigned int numOtInnerNodes = (numOtNodes - numOtLeaves); + const unsigned int numOtLeaves = static_cast( + pow(8, _tsp->numOTLevels() - 1) + ); + const unsigned int numOtInnerNodes = (numOtNodes - numOtLeaves); - unsigned int innerBstOffset = innerNodeIndex - numInnerBstNodes; - unsigned int rowIndex = innerBstOffset / numOtInnerNodes; - unsigned int indexInRow = innerBstOffset % numOtInnerNodes; + const unsigned int innerBstOffset = innerNodeIndex - numInnerBstNodes; + const unsigned int rowIndex = innerBstOffset / numOtInnerNodes; + const unsigned int indexInRow = innerBstOffset % numOtInnerNodes; - unsigned int offset = rowIndex * numOtNodes; - unsigned int leavesOffset = offset + indexInRow; + const unsigned int offset = rowIndex * numOtNodes; + const unsigned int leavesOffset = offset + indexInRow; return numInnerBstNodes + leavesOffset; } diff --git a/modules/multiresvolume/rendering/errorhistogrammanager.h b/modules/multiresvolume/rendering/errorhistogrammanager.h index a9e1c0d82a..3ce4113996 100644 --- a/modules/multiresvolume/rendering/errorhistogrammanager.h +++ b/modules/multiresvolume/rendering/errorhistogrammanager.h @@ -25,22 +25,22 @@ #ifndef __OPENSPACE_MODULE_MULTIRESVOLUME___ERRORHISTOGRAMMANAGER___H__ #define __OPENSPACE_MODULE_MULTIRESVOLUME___ERRORHISTOGRAMMANAGER___H__ -#include -#include #include +#include +#include #include -#include - namespace openspace { +class TSP; + class ErrorHistogramManager { public: ErrorHistogramManager(TSP* tsp); - ~ErrorHistogramManager(); + ~ErrorHistogramManager() = default; bool buildHistograms(int numBins); - const Histogram* getHistogram(unsigned int brickIndex) const; + const Histogram* histogram(unsigned int brickIndex) const; bool loadFromFile(const std::string& filename); bool saveToFile(const std::string& filename); @@ -64,11 +64,12 @@ private: unsigned int brickToInnerNodeIndex(unsigned int brickIndex) const; unsigned int innerNodeToBrickIndex(unsigned int innerNodeIndex) const; - unsigned int linearCoords(glm::vec3 coords) const; + unsigned int linearCoords(const glm::vec3& coords) const; unsigned int linearCoords(int x, int y, int z) const; - unsigned int linearCoords(glm::ivec3 coords) const; + unsigned int linearCoords(const glm::ivec3& coords) const; - float interpolate(glm::vec3 samplePoint, const std::vector& voxels) const; + float interpolate(const glm::vec3& samplePoint, + const std::vector& voxels) const; }; } // namespace openspace diff --git a/modules/multiresvolume/rendering/histogrammanager.cpp b/modules/multiresvolume/rendering/histogrammanager.cpp index 14512c7ec4..1d6c382b8a 100644 --- a/modules/multiresvolume/rendering/histogrammanager.cpp +++ b/modules/multiresvolume/rendering/histogrammanager.cpp @@ -24,45 +24,36 @@ #include -#include -#include -#include -#include -#include +#include +#include namespace openspace { -HistogramManager::HistogramManager() {} - -HistogramManager::~HistogramManager() {} - bool HistogramManager::buildHistograms(TSP* tsp, int numBins) { - std::cout << "Build histograms with " << numBins << " bins each" << std::endl; _numBins = numBins; std::ifstream& file = tsp->file(); if (!file.is_open()) { return false; } - _minBin = 0.0; // Should be calculated from tsp file - _maxBin = 1.0; // Should be calculated from tsp file + _minBin = 0.f; // Should be calculated from tsp file + _maxBin = 1.f; // Should be calculated from tsp file - int numTotalNodes = tsp->numTotalNodes(); + const int numTotalNodes = tsp->numTotalNodes(); _histograms = std::vector(numTotalNodes); - bool success = buildHistogram(tsp, 0); - + const bool success = buildHistogram(tsp, 0); return success; } -Histogram* HistogramManager::getHistogram(unsigned int brickIndex) { +Histogram* HistogramManager::histogram(unsigned int brickIndex) { return &_histograms[brickIndex]; } bool HistogramManager::buildHistogram(TSP* tsp, unsigned int brickIndex) { Histogram histogram(_minBin, _maxBin, _numBins); - bool isBstLeaf = tsp->isBstLeaf(brickIndex); - bool isOctreeLeaf = tsp->isOctreeLeaf(brickIndex); + const bool isBstLeaf = tsp->isBstLeaf(brickIndex); + const bool isOctreeLeaf = tsp->isOctreeLeaf(brickIndex); if (isBstLeaf && isOctreeLeaf) { // TSP leaf, read from file and build histogram @@ -74,16 +65,16 @@ bool HistogramManager::buildHistogram(TSP* tsp, unsigned int brickIndex) { } } else { // Has children - auto children = std::vector(); + std::vector children; if (!isBstLeaf) { // Push BST children - children.push_back(tsp->getBstLeft(brickIndex)); - children.push_back(tsp->getBstRight(brickIndex)); + children.push_back(tsp->bstLeft(brickIndex)); + children.push_back(tsp->bstRight(brickIndex)); } if (!isOctreeLeaf) { // Push Octree children - unsigned int firstChild = tsp->getFirstOctreeChild(brickIndex); + const unsigned int firstChild = tsp->firstOctreeChild(brickIndex); for (int c = 0; c < 8; c++) { children.push_back(firstChild + c); } @@ -91,7 +82,7 @@ bool HistogramManager::buildHistogram(TSP* tsp, unsigned int brickIndex) { size_t numChildren = children.size(); for (size_t c = 0; c < numChildren; c++) { // Visit child - unsigned int childIndex = children[c]; + const unsigned int childIndex = children[c]; if (_histograms[childIndex].isValid() || buildHistogram(tsp, childIndex)) { if (numChildren <= 8 || c < 2) { // If node has both BST and Octree children, only add BST ones @@ -106,21 +97,23 @@ bool HistogramManager::buildHistogram(TSP* tsp, unsigned int brickIndex) { //histogram.normalize(); _histograms[brickIndex] = std::move(histogram); - return true; } std::vector HistogramManager::readValues(TSP* tsp, unsigned int brickIndex) { - unsigned int paddedBrickDim = tsp->paddedBrickDim(); - unsigned int numBrickVals = paddedBrickDim * paddedBrickDim * paddedBrickDim; + const unsigned int paddedBrickDim = tsp->paddedBrickDim(); + const unsigned int numBrickVals = paddedBrickDim * paddedBrickDim * paddedBrickDim; std::vector voxelValues(numBrickVals); - std::streampos offset = tsp->dataPosition() + static_cast(brickIndex*numBrickVals*sizeof(float)); + std::streampos offset = tsp->dataPosition() + + static_cast(brickIndex*numBrickVals*sizeof(float)); std::ifstream& file = tsp->file(); file.seekg(offset); - file.read(reinterpret_cast(&voxelValues[0]), - static_cast(numBrickVals)*sizeof(float)); + file.read( + reinterpret_cast(voxelValues.data()), + static_cast(numBrickVals)*sizeof(float) + ); return voxelValues; } @@ -128,7 +121,7 @@ std::vector HistogramManager::readValues(TSP* tsp, unsigned int brickInde bool HistogramManager::loadFromFile(const std::string& filename) { std::ifstream file(filename, std::ios::in | std::ios::binary); if (!file.is_open()) { - return false; + return false; } int numHistograms; @@ -138,29 +131,27 @@ bool HistogramManager::loadFromFile(const std::string& filename) { file.read(reinterpret_cast(&_maxBin), sizeof(float)); int nFloats = numHistograms * _numBins; - float* histogramData = new float[nFloats]; - file.read(reinterpret_cast(histogramData), sizeof(float) * nFloats); + std::vector histogramData(nFloats); + file.read(reinterpret_cast(histogramData.data()), sizeof(float) * nFloats); _histograms = std::vector(numHistograms); for (int i = 0; i < numHistograms; ++i) { - int offset = i*_numBins; - float* data = new float[_numBins]; - memcpy(data, &histogramData[offset], sizeof(float) * _numBins); - _histograms[i] = Histogram(_minBin, _maxBin, _numBins, data); + int offset = i * _numBins; + // No need to deallocate histogram data, since histograms take ownership. + float* data = new float[_numBins]; + memcpy(data, &histogramData[offset], sizeof(float) * _numBins); + _histograms[i] = Histogram(_minBin, _maxBin, _numBins, data); } - delete[] histogramData; - // No need to deallocate histogram data, since histograms take ownership. file.close(); return true; } - bool HistogramManager::saveToFile(const std::string& filename) { std::ofstream file(filename, std::ios::out | std::ios::binary); if (!file.is_open()) { - return false; + return false; } size_t numHistograms = _histograms.size(); @@ -170,15 +161,14 @@ bool HistogramManager::saveToFile(const std::string& filename) { file.write(reinterpret_cast(&_maxBin), sizeof(float)); size_t nFloats = numHistograms * _numBins; - float* histogramData = new float[nFloats]; + std::vector histogramData(nFloats); for (size_t i = 0; i < numHistograms; ++i) { size_t offset = i*_numBins; memcpy(&histogramData[offset], _histograms[i].data(), sizeof(float) * _numBins); } - file.write(reinterpret_cast(histogramData), sizeof(float) * nFloats); - delete[] histogramData; + file.write(reinterpret_cast(histogramData.data()), sizeof(float) * nFloats); file.close(); return true; diff --git a/modules/multiresvolume/rendering/histogrammanager.h b/modules/multiresvolume/rendering/histogrammanager.h index 16f74b46cc..1eb8f97373 100644 --- a/modules/multiresvolume/rendering/histogrammanager.h +++ b/modules/multiresvolume/rendering/histogrammanager.h @@ -25,29 +25,27 @@ #ifndef __OPENSPACE_MODULE_MULTIRESVOLUME___HISTOGRAMMANAGER___H__ #define __OPENSPACE_MODULE_MULTIRESVOLUME___HISTOGRAMMANAGER___H__ -#include -#include #include namespace openspace { +class TSP; + class HistogramManager { public: - HistogramManager(); - ~HistogramManager(); bool buildHistograms(TSP* tsp, int numBins); - Histogram* getHistogram(unsigned int brickIndex); + Histogram* histogram(unsigned int brickIndex); bool loadFromFile(const std::string& filename); bool saveToFile(const std::string& filename); private: - std::vector _histograms; - float _minBin; - float _maxBin; - int _numBins; - bool buildHistogram(TSP* tsp, unsigned int brickIndex); std::vector readValues(TSP* tsp, unsigned int brickIndex); + + std::vector _histograms; + float _minBin = 0.f; + float _maxBin = 0.f; + int _numBins = 0; }; } // namespace openspace diff --git a/modules/multiresvolume/rendering/localerrorhistogrammanager.cpp b/modules/multiresvolume/rendering/localerrorhistogrammanager.cpp index a00ee06670..3f2d89187c 100644 --- a/modules/multiresvolume/rendering/localerrorhistogrammanager.cpp +++ b/modules/multiresvolume/rendering/localerrorhistogrammanager.cpp @@ -22,16 +22,10 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include -#include -#include -#include - #include -#include +#include #include - #include #include @@ -43,8 +37,6 @@ namespace openspace { LocalErrorHistogramManager::LocalErrorHistogramManager(TSP* tsp) : _tsp(tsp) {} -LocalErrorHistogramManager::~LocalErrorHistogramManager() {} - bool LocalErrorHistogramManager::buildHistograms(int numBins) { LINFO(fmt::format("Build histograms with {} bins each", numBins)); _numBins = numBins; @@ -53,12 +45,14 @@ bool LocalErrorHistogramManager::buildHistograms(int numBins) { if (!_file->is_open()) { return false; } - _minBin = 0.0; // Should be calculated from tsp file - _maxBin = 1.0; // Should be calculated from tsp file as (maxValue - minValue) + _minBin = 0.f; // Should be calculated from tsp file + _maxBin = 1.f; // Should be calculated from tsp file as (maxValue - minValue) - unsigned int numOtLevels = _tsp->numOTLevels(); - unsigned int numOtLeaves = pow(8, numOtLevels - 1); - unsigned int numBstLeaves = pow(2, _tsp->numBSTLevels() - 1); + const unsigned int numOtLevels = _tsp->numOTLevels(); + const unsigned int numOtLeaves = static_cast(pow(8, numOtLevels - 1)); + const unsigned int numBstLeaves = static_cast( + pow(2, _tsp->numBSTLevels() - 1) + ); _numInnerNodes = _tsp->numTotalNodes() - numOtLeaves * numBstLeaves; @@ -70,13 +64,13 @@ bool LocalErrorHistogramManager::buildHistograms(int numBins) { } // All TSP Leaves - int numOtNodes = _tsp->numOTNodes(); - int otOffset = (pow(8, numOtLevels - 1) - 1) / 7; + const int numOtNodes = _tsp->numOTNodes(); + const int otOffset = static_cast((pow(8, numOtLevels - 1) - 1) / 7); - int numBstNodes = _tsp->numBSTNodes(); - int bstOffset = numBstNodes / 2; + const int numBstNodes = _tsp->numBSTNodes(); + const int bstOffset = numBstNodes / 2; - int numberOfLeaves = numOtLeaves * numBstLeaves; + const int numberOfLeaves = numOtLeaves * numBstLeaves; LINFO("Building spatial histograms"); ProgressBar pb1(numberOfLeaves); @@ -86,13 +80,15 @@ bool LocalErrorHistogramManager::buildHistograms(int numBins) { for (int bst = bstOffset; bst < numBstNodes; bst++) { for (int ot = otOffset; ot < numOtNodes; ot++) { success &= buildFromOctreeChild(bst, ot); - if (!success) LERROR("Failed in buildFromOctreeChild"); - if (!success) return false; + if (!success) { + LERROR("Failed in buildFromOctreeChild"); + } + if (!success) { + return false; + } pb1.print(processedLeaves++); } } - //pb1.stop(); - LINFO("Building temporal histograms"); ProgressBar pb2(numberOfLeaves); @@ -101,35 +97,40 @@ bool LocalErrorHistogramManager::buildHistograms(int numBins) { for (int ot = otOffset; ot < numOtNodes; ot++) { for (int bst = bstOffset; bst < numBstNodes; bst++) { success &= buildFromBstChild(bst, ot); - if (!success) LERROR("Failed in buildFromBstChild"); - if (!success) return false; + if (!success) { + LERROR("Failed in buildFromBstChild"); + } + if (!success) { + return false; + } pb2.print(processedLeaves++); } } - //pb2.stop(); return success; } -bool LocalErrorHistogramManager::buildFromOctreeChild(unsigned int bstOffset, unsigned int octreeOffset) { +bool LocalErrorHistogramManager::buildFromOctreeChild(unsigned int bstOffset, + unsigned int octreeOffset) +{ // Add errors to octree parent histogram - int numOtNodes = _tsp->numOTNodes(); - unsigned int childIndex = bstOffset * numOtNodes + octreeOffset; - bool isOctreeLeaf = _tsp->isOctreeLeaf(childIndex); + const int numOtNodes = _tsp->numOTNodes(); + const unsigned int childIndex = bstOffset * numOtNodes + octreeOffset; + const bool isOctreeLeaf = _tsp->isOctreeLeaf(childIndex); if (octreeOffset > 0) { // Not octree root std::vector childValues; std::vector parentValues; - int octreeParent = parentOffset(octreeOffset, 8); - unsigned int parentIndex = bstOffset * numOtNodes + octreeParent; - unsigned int parentInnerNodeIndex = brickToInnerNodeIndex(parentIndex); + const int octreeParent = parentOffset(octreeOffset, 8); + const unsigned int parentIndex = bstOffset * numOtNodes + octreeParent; + const unsigned int parentInnerNodeIndex = brickToInnerNodeIndex(parentIndex); if (isOctreeLeaf) { childValues = readValues(childIndex); } else { - unsigned int childInnerNodeIndex = brickToInnerNodeIndex(childIndex); + const unsigned int childInnerNodeIndex = brickToInnerNodeIndex(childIndex); auto it = _voxelCache.find(childInnerNodeIndex); if (it != _voxelCache.end()) { childValues = it->second; @@ -144,7 +145,7 @@ bool LocalErrorHistogramManager::buildFromOctreeChild(unsigned int bstOffset, un } } - int octreeChildIndex = (octreeOffset - 1) % 8; + const int octreeChildIndex = (octreeOffset - 1) % 8; if (octreeChildIndex == 0) { parentValues = readValues(parentIndex); _voxelCache[parentInnerNodeIndex] = parentValues; @@ -159,62 +160,74 @@ bool LocalErrorHistogramManager::buildFromOctreeChild(unsigned int bstOffset, un } // Compare values and add errors to parent histogram - unsigned int paddedBrickDim = _tsp->paddedBrickDim(); - unsigned int brickDim = _tsp->brickDim(); - unsigned int padding = (paddedBrickDim - brickDim) / 2; + const unsigned int paddedBrickDim = _tsp->paddedBrickDim(); + const int brickDim = static_cast(_tsp->brickDim()); + const unsigned int padding = (paddedBrickDim - brickDim) / 2; - glm::vec3 parentOffset = glm::vec3(octreeChildIndex % 2, (octreeChildIndex / 2) % 2, octreeChildIndex / 4) * float(brickDim) / 2.f; + glm::vec3 parentOffset = glm::vec3( + octreeChildIndex % 2, + (octreeChildIndex / 2) % 2, + octreeChildIndex / 4 + ) * (brickDim / 2.f); for (int z = 0; z < brickDim; z++) { for (int y = 0; y < brickDim; y++) { for (int x = 0; x < brickDim; x++) { - glm::vec3 childSamplePoint = glm::vec3(x, y, z) + glm::vec3(padding); - glm::vec3 parentSamplePoint = parentOffset + (glm::vec3(x, y, z) + glm::vec3(0.5)) * 0.5f; + glm::ivec3 childSamplePoint = glm::ivec3(x, y, z) + + glm::ivec3(padding); + glm::vec3 parentSamplePoint = parentOffset + + glm::vec3(x + 0.5f, y + 0.5f, z + 0.5f) * 0.5f; float childValue = childValues[linearCoords(childSamplePoint)]; float parentValue = interpolate(parentSamplePoint, parentValues); // Divide by number of child voxels that will be taken into account - float rectangleHeight = std::abs(childValue - parentValue) / 8.0; - _spatialHistograms[parentInnerNodeIndex].addRectangle(childValue, parentValue, rectangleHeight); + float rectangleHeight = std::abs(childValue - parentValue) / 8.f; + _spatialHistograms[parentInnerNodeIndex].addRectangle( + childValue, + parentValue, + rectangleHeight + ); } } } - bool isLastOctreeChild = octreeOffset > 0 && octreeChildIndex == 7; + const bool isLastOctreeChild = octreeOffset > 0 && octreeChildIndex == 7; if (isLastOctreeChild) { buildFromOctreeChild(bstOffset, octreeParent); } } if (!isOctreeLeaf) { - unsigned int childInnerNodeIndex = brickToInnerNodeIndex(childIndex); + const unsigned int childInnerNodeIndex = brickToInnerNodeIndex(childIndex); _voxelCache.erase(childInnerNodeIndex); } - int bstChildIndex = bstOffset % 2; - bool isLastBstChild = bstOffset > 0 && bstChildIndex == 0; + const int bstChildIndex = bstOffset % 2; + const bool isLastBstChild = bstOffset > 0 && bstChildIndex == 0; if (isOctreeLeaf && isLastBstChild) { - int bstParent = parentOffset(bstOffset, 2); + const int bstParent = parentOffset(bstOffset, 2); buildFromOctreeChild(bstParent, octreeOffset); } return true; } -bool LocalErrorHistogramManager::buildFromBstChild(unsigned int bstOffset, unsigned int octreeOffset) { +bool LocalErrorHistogramManager::buildFromBstChild(unsigned int bstOffset, + unsigned int octreeOffset) +{ // Add errors to bst parent histogram - int numOtNodes = _tsp->numOTNodes(); - unsigned int childIndex = bstOffset * numOtNodes + octreeOffset; - bool isBstLeaf = _tsp->isBstLeaf(childIndex); + const int numOtNodes = _tsp->numOTNodes(); + const unsigned int childIndex = bstOffset * numOtNodes + octreeOffset; + const bool isBstLeaf = _tsp->isBstLeaf(childIndex); if (bstOffset > 0) { // Not BST root std::vector childValues; std::vector parentValues; - int bstParent = parentOffset(bstOffset, 2); - unsigned int parentIndex = bstParent * numOtNodes + octreeOffset; - unsigned int parentInnerNodeIndex = brickToInnerNodeIndex(parentIndex); + const int bstParent = parentOffset(bstOffset, 2); + const unsigned int parentIndex = bstParent * numOtNodes + octreeOffset; + const unsigned int parentInnerNodeIndex = brickToInnerNodeIndex(parentIndex); if (isBstLeaf) { childValues = readValues(childIndex); @@ -229,7 +242,7 @@ bool LocalErrorHistogramManager::buildFromBstChild(unsigned int bstOffset, unsig } } - int bstChildIndex = bstOffset % 2; + const int bstChildIndex = bstOffset % 2; if (bstChildIndex == 1) { parentValues = readValues(parentIndex); _voxelCache[parentInnerNodeIndex] = parentValues; @@ -244,40 +257,44 @@ bool LocalErrorHistogramManager::buildFromBstChild(unsigned int bstOffset, unsig } // Compare values and add errors to parent histogram - unsigned int paddedBrickDim = _tsp->paddedBrickDim(); - unsigned int brickDim = _tsp->brickDim(); - unsigned int padding = (paddedBrickDim - brickDim) / 2; + const unsigned int paddedBrickDim = _tsp->paddedBrickDim(); + const int brickDim = static_cast(_tsp->brickDim()); + const unsigned int padding = (paddedBrickDim - brickDim) / 2; for (int z = 0; z < brickDim; z++) { for (int y = 0; y < brickDim; y++) { for (int x = 0; x < brickDim; x++) { - glm::vec3 samplePoint = glm::vec3(x, y, z) + glm::vec3(padding); + glm::ivec3 samplePoint = glm::ivec3(x, y, z) + glm::ivec3(padding); unsigned int linearSamplePoint = linearCoords(samplePoint); float childValue = childValues[linearSamplePoint]; float parentValue = parentValues[linearSamplePoint]; // Divide by number of child voxels that will be taken into account - float rectangleHeight = std::abs(childValue - parentValue) / 2.0; - _temporalHistograms[parentInnerNodeIndex].addRectangle(childValue, parentValue, rectangleHeight); + float rectangleHeight = std::abs(childValue - parentValue) / 2.f; + _temporalHistograms[parentInnerNodeIndex].addRectangle( + childValue, + parentValue, + rectangleHeight + ); } } } - bool isLastBstChild = bstOffset > 0 && bstChildIndex == 0; + const bool isLastBstChild = bstOffset > 0 && bstChildIndex == 0; if (isLastBstChild) { buildFromBstChild(bstParent, octreeOffset); } } if (!isBstLeaf) { - unsigned int childInnerNodeIndex = brickToInnerNodeIndex(childIndex); + const unsigned int childInnerNodeIndex = brickToInnerNodeIndex(childIndex); _voxelCache.erase(childInnerNodeIndex); } - int octreeChildIndex = (octreeOffset - 1) % 8; - bool isLastOctreeChild = octreeOffset > 0 && octreeChildIndex == 7; + const int octreeChildIndex = (octreeOffset - 1) % 8; + const bool isLastOctreeChild = octreeOffset > 0 && octreeChildIndex == 7; if (isBstLeaf && isLastOctreeChild) { - int octreeParent = parentOffset(octreeOffset, 8); + const int octreeParent = parentOffset(octreeOffset, 8); buildFromBstChild(bstOffset, octreeParent); } @@ -295,29 +312,29 @@ bool LocalErrorHistogramManager::loadFromFile(const std::string& filename) { file.read(reinterpret_cast(&_minBin), sizeof(float)); file.read(reinterpret_cast(&_maxBin), sizeof(float)); - int nFloats = _numInnerNodes * _numBins; - float* histogramData = new float[nFloats]; + const int nFloats = _numInnerNodes * _numBins; + std::vector histogramData(nFloats); - file.read(reinterpret_cast(histogramData), sizeof(float) * nFloats); + file.read(reinterpret_cast(histogramData.data()), sizeof(float) * nFloats); _spatialHistograms = std::vector(_numInnerNodes); - for (int i = 0; i < _numInnerNodes; ++i) { - int offset = i*_numBins; + for (unsigned int i = 0; i < _numInnerNodes; ++i) { + const int offset = i * _numBins; + // No need to deallocate histogram data, since histograms take ownership. float* data = new float[_numBins]; memcpy(data, &histogramData[offset], sizeof(float) * _numBins); _spatialHistograms[i] = Histogram(_minBin, _maxBin, _numBins, data); } - file.read(reinterpret_cast(histogramData), sizeof(float) * nFloats); + file.read(reinterpret_cast(histogramData.data()), sizeof(float) * nFloats); _temporalHistograms = std::vector(_numInnerNodes); - for (int i = 0; i < _numInnerNodes; ++i) { - int offset = i*_numBins; + for (unsigned int i = 0; i < _numInnerNodes; ++i) { + const int offset = i * _numBins; + // No need to deallocate histogram data, since histograms take ownership. float* data = new float[_numBins]; memcpy(data, &histogramData[offset], sizeof(float) * _numBins); _temporalHistograms[i] = Histogram(_minBin, _maxBin, _numBins, data); } - delete[] histogramData; - // No need to deallocate histogram data, since histograms take ownership. file.close(); return true; } @@ -334,22 +351,28 @@ bool LocalErrorHistogramManager::saveToFile(const std::string& filename) { file.write(reinterpret_cast(&_minBin), sizeof(float)); file.write(reinterpret_cast(&_maxBin), sizeof(float)); - int nFloats = _numInnerNodes * _numBins; - float* histogramData = new float[nFloats]; + const int nFloats = _numInnerNodes * _numBins; + std::vector histogramData(nFloats); - for (int i = 0; i < _numInnerNodes; ++i) { - int offset = i*_numBins; - memcpy(&histogramData[offset], _spatialHistograms[i].data(), sizeof(float) * _numBins); + for (unsigned int i = 0; i < _numInnerNodes; ++i) { + int offset = i * _numBins; + memcpy( + &histogramData[offset], + _spatialHistograms[i].data(), + sizeof(float) * _numBins + ); } - file.write(reinterpret_cast(histogramData), sizeof(float) * nFloats); + file.write(reinterpret_cast(histogramData.data()), sizeof(float) * nFloats); - for (int i = 0; i < _numInnerNodes; ++i) { - int offset = i*_numBins; - memcpy(&histogramData[offset], _temporalHistograms[i].data(), sizeof(float) * _numBins); + for (unsigned int i = 0; i < _numInnerNodes; ++i) { + int offset = i * _numBins; + memcpy( + &histogramData[offset], + _temporalHistograms[i].data(), + sizeof(float) * _numBins + ); } - file.write(reinterpret_cast(histogramData), sizeof(float) * nFloats); - - delete[] histogramData; + file.write(reinterpret_cast(histogramData.data()), sizeof(float) * nFloats); file.close(); return true; @@ -365,45 +388,49 @@ unsigned int LocalErrorHistogramManager::linearCoords(int x, int y, int z) const unsigned int LocalErrorHistogramManager::linearCoords(glm::ivec3 coords) const { unsigned int paddedBrickDim = _tsp->paddedBrickDim(); - return coords.z * paddedBrickDim * paddedBrickDim + coords.y * paddedBrickDim + coords.x; + return coords.z * paddedBrickDim * paddedBrickDim + coords.y * paddedBrickDim + + coords.x; } -float LocalErrorHistogramManager::interpolate(glm::vec3 samplePoint, const std::vector& voxels) const { - int lowX = samplePoint.x; - int lowY = samplePoint.y; - int lowZ = samplePoint.z; +float LocalErrorHistogramManager::interpolate(glm::vec3 samplePoint, + const std::vector& voxels) const +{ + const int lowX = static_cast(samplePoint.x); + const int lowY = static_cast(samplePoint.y); + const int lowZ = static_cast(samplePoint.z); - int highX = ceil(samplePoint.x); - int highY = ceil(samplePoint.y); - int highZ = ceil(samplePoint.z); + const int highX = static_cast(ceil(samplePoint.x)); + const int highY = static_cast(ceil(samplePoint.y)); + const int highZ = static_cast(ceil(samplePoint.z)); - float interpolatorX = 1.0 - (samplePoint.x - lowX); - float interpolatorY = 1.0 - (samplePoint.y - lowY); - float interpolatorZ = 1.0 - (samplePoint.z - lowZ); + const float interpolatorX = 1.f - (samplePoint.x - lowX); + const float interpolatorY = 1.f - (samplePoint.y - lowY); + const float interpolatorZ = 1.f - (samplePoint.z - lowZ); - float v000 = voxels[linearCoords(lowX, lowY, lowZ)]; - float v001 = voxels[linearCoords(lowX, lowY, highZ)]; - float v010 = voxels[linearCoords(lowX, highY, lowZ)]; - float v011 = voxels[linearCoords(lowX, highY, highZ)]; - float v100 = voxels[linearCoords(highX, lowY, lowZ)]; - float v101 = voxels[linearCoords(highX, lowY, highZ)]; - float v110 = voxels[linearCoords(highX, highY, lowZ)]; - float v111 = voxels[linearCoords(highX, highY, highZ)]; + const float v000 = voxels[linearCoords(lowX, lowY, lowZ)]; + const float v001 = voxels[linearCoords(lowX, lowY, highZ)]; + const float v010 = voxels[linearCoords(lowX, highY, lowZ)]; + const float v011 = voxels[linearCoords(lowX, highY, highZ)]; + const float v100 = voxels[linearCoords(highX, lowY, lowZ)]; + const float v101 = voxels[linearCoords(highX, lowY, highZ)]; + const float v110 = voxels[linearCoords(highX, highY, lowZ)]; + const float v111 = voxels[linearCoords(highX, highY, highZ)]; - float v00 = interpolatorZ * v000 + (1.0 - interpolatorZ) * v001; - float v01 = interpolatorZ * v010 + (1.0 - interpolatorZ) * v011; - float v10 = interpolatorZ * v100 + (1.0 - interpolatorZ) * v101; - float v11 = interpolatorZ * v110 + (1.0 - interpolatorZ) * v111; + const float v00 = interpolatorZ * v000 + (1.f - interpolatorZ) * v001; + const float v01 = interpolatorZ * v010 + (1.f - interpolatorZ) * v011; + const float v10 = interpolatorZ * v100 + (1.f - interpolatorZ) * v101; + const float v11 = interpolatorZ * v110 + (1.f - interpolatorZ) * v111; - float v0 = interpolatorY * v00 + (1.0 - interpolatorY) * v01; - float v1 = interpolatorY * v10 + (1.0 - interpolatorY) * v11; - - return interpolatorX * v0 + (1.0 - interpolatorX) * v1; + const float v0 = interpolatorY * v00 + (1.f - interpolatorY) * v01; + const float v1 = interpolatorY * v10 + (1.f - interpolatorY) * v11; + return interpolatorX * v0 + (1.f - interpolatorX) * v1; } -const Histogram* LocalErrorHistogramManager::getSpatialHistogram(unsigned int brickIndex) const { - unsigned int innerNodeIndex = brickToInnerNodeIndex(brickIndex); +const Histogram* LocalErrorHistogramManager::spatialHistogram( + unsigned int brickIndex) const +{ + const unsigned int innerNodeIndex = brickToInnerNodeIndex(brickIndex); if (innerNodeIndex < _numInnerNodes) { return &(_spatialHistograms[innerNodeIndex]); } else { @@ -411,8 +438,10 @@ const Histogram* LocalErrorHistogramManager::getSpatialHistogram(unsigned int br } } -const Histogram* LocalErrorHistogramManager::getTemporalHistogram(unsigned int brickIndex) const { - unsigned int innerNodeIndex = brickToInnerNodeIndex(brickIndex); +const Histogram* LocalErrorHistogramManager::temporalHistogram( + unsigned int brickIndex) const +{ + const unsigned int innerNodeIndex = brickToInnerNodeIndex(brickIndex); if (innerNodeIndex < _numInnerNodes) { return &(_temporalHistograms[innerNodeIndex]); } else { @@ -424,70 +453,93 @@ int LocalErrorHistogramManager::parentOffset(int offset, int base) const { if (offset == 0) { return -1; } - int depth = floor(log(((base - 1) * offset + 1.0)) / log(base)); - int firstInLevel = (pow(base, depth) - 1) / (base - 1); - int inLevelOffset = offset - firstInLevel; + const int depth = static_cast( + floor(log(((base - 1) * offset + 1.0)) / log(base)) + ); + const int firstInLevel = static_cast((pow(base, depth) - 1) / (base - 1)); + const int inLevelOffset = offset - firstInLevel; - int parentDepth = depth - 1; - int firstInParentLevel = (pow(base, parentDepth) - 1) / (base - 1); - int parentInLevelOffset = inLevelOffset / base; + const int parentDepth = depth - 1; + const int firstInParentLevel = static_cast( + (pow(base, parentDepth) - 1) / (base - 1) + ); + const int parentInLevelOffset = inLevelOffset / base; - int parentOffset = firstInParentLevel + parentInLevelOffset; + const int parentOffset = firstInParentLevel + parentInLevelOffset; return parentOffset; } std::vector LocalErrorHistogramManager::readValues(unsigned int brickIndex) const { - unsigned int paddedBrickDim = _tsp->paddedBrickDim(); - unsigned int numBrickVals = paddedBrickDim * paddedBrickDim * paddedBrickDim; + const unsigned int paddedBrickDim = _tsp->paddedBrickDim(); + const unsigned int numBrickVals = paddedBrickDim * paddedBrickDim * paddedBrickDim; std::vector voxelValues(numBrickVals); - std::streampos offset = _tsp->dataPosition() + static_cast(brickIndex*numBrickVals*sizeof(float)); + std::streampos offset = _tsp->dataPosition() + + static_cast(brickIndex*numBrickVals*sizeof(float)); _file->seekg(offset); - _file->read(reinterpret_cast(&voxelValues[0]), - static_cast(numBrickVals)*sizeof(float)); + _file->read( + reinterpret_cast(voxelValues.data()), + static_cast(numBrickVals)*sizeof(float) + ); return voxelValues; } -unsigned int LocalErrorHistogramManager::brickToInnerNodeIndex(unsigned int brickIndex) const { - unsigned int numOtNodes = _tsp->numOTNodes(); - unsigned int numBstLevels = _tsp->numBSTLevels(); +unsigned int LocalErrorHistogramManager::brickToInnerNodeIndex( + unsigned int brickIndex) const +{ + const unsigned int numOtNodes = _tsp->numOTNodes(); + const unsigned int numBstLevels = _tsp->numBSTLevels(); + const unsigned int numInnerBstNodes = static_cast( + (pow(2, numBstLevels - 1) - 1) * numOtNodes + ); + if (brickIndex < numInnerBstNodes) { + return brickIndex; + } - unsigned int numInnerBstNodes = (pow(2, numBstLevels - 1) - 1) * numOtNodes; - if (brickIndex < numInnerBstNodes) return brickIndex; + const unsigned int numOtLeaves = static_cast( + pow(8, _tsp->numOTLevels() - 1) + ); + const unsigned int numOtInnerNodes = (numOtNodes - numOtLeaves); - unsigned int numOtLeaves = pow(8, _tsp->numOTLevels() - 1); - unsigned int numOtInnerNodes = (numOtNodes - numOtLeaves); + const unsigned int innerBstOffset = brickIndex - numInnerBstNodes; + const unsigned int rowIndex = innerBstOffset / numOtNodes; + const unsigned int indexInRow = innerBstOffset % numOtNodes; - unsigned int innerBstOffset = brickIndex - numInnerBstNodes; - unsigned int rowIndex = innerBstOffset / numOtNodes; - unsigned int indexInRow = innerBstOffset % numOtNodes; + if (indexInRow >= numOtInnerNodes) { + return _numInnerNodes; + } - if (indexInRow >= numOtInnerNodes) return _numInnerNodes; - - unsigned int offset = rowIndex * numOtInnerNodes; - unsigned int leavesOffset = offset + indexInRow; + const unsigned int offset = rowIndex * numOtInnerNodes; + const unsigned int leavesOffset = offset + indexInRow; return numInnerBstNodes + leavesOffset; } -unsigned int LocalErrorHistogramManager::innerNodeToBrickIndex(unsigned int innerNodeIndex) const { - unsigned int numOtNodes = _tsp->numOTNodes(); - unsigned int numBstLevels = _tsp->numBSTLevels(); +unsigned int LocalErrorHistogramManager::innerNodeToBrickIndex( + unsigned int innerNodeIndex) const +{ + const unsigned int numOtNodes = _tsp->numOTNodes(); + const unsigned int numBstLevels = _tsp->numBSTLevels(); + const unsigned int numInnerBstNodes = static_cast( + (pow(2, numBstLevels - 1) - 1) * numOtNodes + ); + if (innerNodeIndex < numInnerBstNodes) { + return innerNodeIndex; + } - unsigned int numInnerBstNodes = (pow(2, numBstLevels - 1) - 1) * numOtNodes; - if (innerNodeIndex < numInnerBstNodes) return innerNodeIndex; + const unsigned int numOtLeaves = static_cast( + pow(8, _tsp->numOTLevels() - 1) + ); + const unsigned int numOtInnerNodes = (numOtNodes - numOtLeaves); - unsigned int numOtLeaves = pow(8, _tsp->numOTLevels() - 1); - unsigned int numOtInnerNodes = (numOtNodes - numOtLeaves); + const unsigned int innerBstOffset = innerNodeIndex - numInnerBstNodes; + const unsigned int rowIndex = innerBstOffset / numOtInnerNodes; + const unsigned int indexInRow = innerBstOffset % numOtInnerNodes; - unsigned int innerBstOffset = innerNodeIndex - numInnerBstNodes; - unsigned int rowIndex = innerBstOffset / numOtInnerNodes; - unsigned int indexInRow = innerBstOffset % numOtInnerNodes; - - unsigned int offset = rowIndex * numOtNodes; - unsigned int leavesOffset = offset + indexInRow; + const unsigned int offset = rowIndex * numOtNodes; + const unsigned int leavesOffset = offset + indexInRow; return numInnerBstNodes + leavesOffset; } diff --git a/modules/multiresvolume/rendering/localerrorhistogrammanager.h b/modules/multiresvolume/rendering/localerrorhistogrammanager.h index 68651821cf..8f360cc6c5 100644 --- a/modules/multiresvolume/rendering/localerrorhistogrammanager.h +++ b/modules/multiresvolume/rendering/localerrorhistogrammanager.h @@ -25,37 +25,36 @@ #ifndef __OPENSPACE_MODULE_MULTIRESVOLUME___LOCALERRORHISTOGRAMMANAGER___H__ #define __OPENSPACE_MODULE_MULTIRESVOLUME___LOCALERRORHISTOGRAMMANAGER___H__ -#include -#include #include +#include +#include #include -#include - namespace openspace { +class TSP; + class LocalErrorHistogramManager { public: LocalErrorHistogramManager(TSP* tsp); - ~LocalErrorHistogramManager(); bool buildHistograms(int numBins); - const Histogram* getSpatialHistogram(unsigned int brickIndex) const; - const Histogram* getTemporalHistogram(unsigned int brickIndex) const; + const Histogram* spatialHistogram(unsigned int brickIndex) const; + const Histogram* temporalHistogram(unsigned int brickIndex) const; bool loadFromFile(const std::string& filename); bool saveToFile(const std::string& filename); private: - TSP* _tsp; + TSP* _tsp = nullptr; std::ifstream* _file; std::vector _spatialHistograms; std::vector _temporalHistograms; - unsigned int _numInnerNodes; - float _minBin; - float _maxBin; - int _numBins; + unsigned int _numInnerNodes = 0; + float _minBin = 0.f; + float _maxBin = 0.f; + int _numBins = 0; std::map> _voxelCache; diff --git a/modules/multiresvolume/rendering/localtfbrickselector.cpp b/modules/multiresvolume/rendering/localtfbrickselector.cpp index e5cdb645d6..f75a8ee92f 100644 --- a/modules/multiresvolume/rendering/localtfbrickselector.cpp +++ b/modules/multiresvolume/rendering/localtfbrickselector.cpp @@ -22,14 +22,20 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include #include + +#include #include -#include #include #include -#include -#include + +namespace { + bool compareSplitPoints(const openspace::BrickSelection& a, + const openspace::BrickSelection& b) + { + return a.splitPoints < b.splitPoints; + } +} // namespace namespace openspace { @@ -40,9 +46,8 @@ LocalTfBrickSelector::LocalTfBrickSelector(TSP* tsp, LocalErrorHistogramManager* , _histogramManager(hm) , _transferFunction(tf) , _memoryBudget(memoryBudget) - , _streamingBudget(streamingBudget) {} - -LocalTfBrickSelector::~LocalTfBrickSelector() {} + , _streamingBudget(streamingBudget) +{} bool LocalTfBrickSelector::initialize() { return calculateBrickErrors(); @@ -57,12 +62,12 @@ void LocalTfBrickSelector::setStreamingBudget(int streamingBudget) { } void LocalTfBrickSelector::selectBricks(int timestep, std::vector& bricks) { - int numTimeSteps = _tsp->header().numTimesteps_; - int numBricksPerDim = _tsp->header().xNumBricks_; + const int numTimeSteps = _tsp->header().numTimesteps; + const int numBricksPerDim = _tsp->header().xNumBricks; unsigned int rootNode = 0; BrickSelection::SplitType splitType; - float rootSplitPoints = splitPoints(rootNode, splitType); + const float rootSplitPoints = splitPoints(rootNode, splitType); BrickSelection brickSelection = BrickSelection( numBricksPerDim, numTimeSteps, @@ -81,31 +86,27 @@ void LocalTfBrickSelector::selectBricks(int timestep, std::vector& bricks) leafSelections.push_back(brickSelection); } - int memoryBudget = _memoryBudget; int totalStreamingBudget = _streamingBudget * numTimeSteps; int nBricksInMemory = 1; int nStreamedBricks = 1; - while (nBricksInMemory <= memoryBudget - 7 && priorityQueue.size() > 0) { - std::pop_heap( - priorityQueue.begin(), - priorityQueue.end(), - BrickSelection::compareSplitPoints - ); + while (nBricksInMemory <= _memoryBudget - 7 && priorityQueue.size() > 0) { + std::pop_heap(priorityQueue.begin(), priorityQueue.end(), compareSplitPoints); BrickSelection bs = priorityQueue.back(); - // TODO: handle edge case when we can only afford temporal splits or no split (only 1 spot left) + // TODO: handle edge case when we can only afford temporal splits or + // no split (only 1 spot left) unsigned int brickIndex = bs.brickIndex; priorityQueue.pop_back(); if (bs.splitType == BrickSelection::SplitType::Temporal) { // int timeSpanCenter = bs.centerT(); - unsigned int childBrickIndex; bool pickRightTimeChild = bs.timestepInRightChild(timestep); - // On average on the whole time period, splitting this spatial brick in two time steps - // would generate twice as much streaming. Current number of streams of this spatial brick - // is 2^nTemporalSplits over the whole time period. + // On average on the whole time period, splitting this spatial brick in two + // time steps would generate twice as much streaming. Current number of + // streams of this spatial brick is 2^nTemporalSplits over the whole time + // period. int newStreams = static_cast(std::pow(2, bs.nTemporalSplits)); if (nStreamedBricks + newStreams > totalStreamingBudget) { // Reached dead end (streaming budget would be exceeded) @@ -114,11 +115,9 @@ void LocalTfBrickSelector::selectBricks(int timestep, std::vector& bricks) } nStreamedBricks += newStreams; - if (pickRightTimeChild) { - childBrickIndex = _tsp->getBstRight(brickIndex); - } else { - childBrickIndex = _tsp->getBstLeft(brickIndex); - } + const unsigned int childBrickIndex = pickRightTimeChild ? + _tsp->bstRight(brickIndex) : + _tsp->bstLeft(brickIndex); BrickSelection::SplitType childSplitType; float childSplitPoints = splitPoints(childBrickIndex, childSplitType); @@ -134,19 +133,20 @@ void LocalTfBrickSelector::selectBricks(int timestep, std::vector& bricks) std::push_heap( priorityQueue.begin(), priorityQueue.end(), - BrickSelection::compareSplitPoints + compareSplitPoints ); } else { leafSelections.push_back(childSelection); } } else if (bs.splitType == BrickSelection::SplitType::Spatial) { nBricksInMemory += 7; // Remove one and add eight. - unsigned int firstChild = _tsp->getFirstOctreeChild(brickIndex); + const unsigned int firstChild = _tsp->firstOctreeChild(brickIndex); - // On average on the whole time period, splitting this spatial brick into eight spatial bricks - // would generate eight times as much streaming. Current number of streams of this spatial brick - // is 2^nTemporalStreams over the whole time period. - int newStreams = 7 * static_cast(std::pow(2, bs.nTemporalSplits)); + // On average on the whole time period, splitting this spatial brick into + // eight spatial bricks would generate eight times as much streaming. Current + // number of streams of this spatial brick is 2^nTemporalStreams over the + // whole time period. + const int newStreams = 7 * static_cast(std::pow(2, bs.nTemporalSplits)); if (nStreamedBricks + newStreams > totalStreamingBudget) { // Reached dead end (streaming budget would be exceeded) // However, temporal split might be possible @@ -164,10 +164,13 @@ void LocalTfBrickSelector::selectBricks(int timestep, std::vector& bricks) nStreamedBricks += newStreams; for (unsigned int i = 0; i < 8; i++) { - unsigned int childBrickIndex = firstChild + i; + const unsigned int childBrickIndex = firstChild + i; BrickSelection::SplitType childSplitType; - float childSplitPoints = splitPoints(childBrickIndex, childSplitType); + const float childSplitPoints = splitPoints( + childBrickIndex, + childSplitType + ); BrickSelection childSelection = bs.splitSpatially( i % 2, (i/2) % 2, @@ -182,7 +185,7 @@ void LocalTfBrickSelector::selectBricks(int timestep, std::vector& bricks) std::push_heap( priorityQueue.begin(), priorityQueue.end(), - BrickSelection::compareSplitPoints + compareSplitPoints ); } else { leafSelections.push_back(childSelection); @@ -205,26 +208,29 @@ void LocalTfBrickSelector::selectBricks(int timestep, std::vector& bricks) std::push_heap( temporalSplitQueue.begin(), temporalSplitQueue.end(), - BrickSelection::compareSplitPoints + compareSplitPoints ); } else { deadEnds.push_back(bs); } } - while (nStreamedBricks < totalStreamingBudget - 1 && temporalSplitQueue.size() > 0) { + while (nStreamedBricks < totalStreamingBudget - 1 && + temporalSplitQueue.size() > 0) + { std::pop_heap( temporalSplitQueue.begin(), temporalSplitQueue.end(), - BrickSelection::compareSplitPoints + compareSplitPoints ); BrickSelection bs = temporalSplitQueue.back(); temporalSplitQueue.pop_back(); - unsigned int brickIndex = bs.brickIndex; - int newStreams = static_cast(std::pow(2, bs.nTemporalSplits)); + const unsigned int brickIndex = bs.brickIndex; + const int newStreams = static_cast(std::pow(2, bs.nTemporalSplits)); if (nStreamedBricks + newStreams > totalStreamingBudget) { - // The current best choice would make us exceed the streaming budget, try next instead. + // The current best choice would make us exceed the streaming budget, try + // next instead. deadEnds.push_back(bs); continue; } @@ -234,15 +240,15 @@ void LocalTfBrickSelector::selectBricks(int timestep, std::vector& bricks) bool pickRightTimeChild = bs.timestepInRightChild(timestep); if (pickRightTimeChild) { - childBrickIndex = _tsp->getBstRight(brickIndex); + childBrickIndex = _tsp->bstRight(brickIndex); } else { - childBrickIndex = _tsp->getBstLeft(brickIndex); + childBrickIndex = _tsp->bstLeft(brickIndex); } float childSplitPoints = temporalSplitPoints(childBrickIndex); if (childSplitPoints > -1) { - BrickSelection childSelection = bs.splitTemporally( + const BrickSelection childSelection = bs.splitTemporally( pickRightTimeChild, childBrickIndex, BrickSelection::SplitType::Temporal, @@ -252,7 +258,7 @@ void LocalTfBrickSelector::selectBricks(int timestep, std::vector& bricks) std::push_heap( temporalSplitQueue.begin(), temporalSplitQueue.end(), - BrickSelection::compareSplitPoints + compareSplitPoints ); } else { BrickSelection childSelection = bs.splitTemporally( @@ -268,7 +274,7 @@ void LocalTfBrickSelector::selectBricks(int timestep, std::vector& bricks) // Write selected inner nodes to brickSelection vector for (const BrickSelection& bs : priorityQueue) { writeSelection(bs, bricks); - } + } } // Write selected inner nodes to brickSelection vector @@ -283,19 +289,16 @@ void LocalTfBrickSelector::selectBricks(int timestep, std::vector& bricks) for (const BrickSelection& bs : leafSelections) { writeSelection(bs, bricks); } - - //std::cout << "Bricks in memory: " << nBricksInMemory << "/" << _memoryBudget << "___\t\t" - // << "Streamed bricks: " << nStreamedBricks << "/" << totalStreamingBudget << std::flush << "___\r"; } -float LocalTfBrickSelector::temporalSplitPoints(unsigned int brickIndex) { +float LocalTfBrickSelector::temporalSplitPoints(unsigned int brickIndex) const { if (_tsp->isBstLeaf(brickIndex)) { return -1; } return _brickErrors[brickIndex].temporal * 0.5f; } -float LocalTfBrickSelector::spatialSplitPoints(unsigned int brickIndex) { +float LocalTfBrickSelector::spatialSplitPoints(unsigned int brickIndex) const { if (_tsp->isOctreeLeaf(brickIndex)) { return -1; } @@ -305,8 +308,8 @@ float LocalTfBrickSelector::spatialSplitPoints(unsigned int brickIndex) { float LocalTfBrickSelector::splitPoints(unsigned int brickIndex, BrickSelection::SplitType& splitType) { - float temporalPoints = temporalSplitPoints(brickIndex); - float spatialPoints = spatialSplitPoints(brickIndex); + const float temporalPoints = temporalSplitPoints(brickIndex); + const float spatialPoints = spatialSplitPoints(brickIndex); float splitPoints; @@ -324,31 +327,35 @@ float LocalTfBrickSelector::splitPoints(unsigned int brickIndex, } bool LocalTfBrickSelector::calculateBrickErrors() { - TransferFunction *tf = _transferFunction; - if (!tf) return false; + TransferFunction* tf = _transferFunction; + if (!tf) { + return false; + } size_t tfWidth = tf->width(); - if (tfWidth <= 0) return false; + if (tfWidth <= 0) { + return false; + } std::vector gradients(tfWidth - 1); for (size_t offset = 0; offset < tfWidth - 1; offset++) { - glm::vec4 prevRgba = tf->sample(offset); - glm::vec4 nextRgba = tf->sample(offset + 1); + const glm::vec4 prevRgba = tf->sample(offset); + const glm::vec4 nextRgba = tf->sample(offset + 1); - float colorDifference = glm::distance(prevRgba, nextRgba); - float alpha = (prevRgba.w + nextRgba.w) * 0.5f; + const float colorDifference = glm::distance(prevRgba, nextRgba); + const float alpha = (prevRgba.w + nextRgba.w) * 0.5f; gradients[offset] = colorDifference*alpha; } - unsigned int nHistograms = _tsp->numTotalNodes(); + const unsigned int nHistograms = _tsp->numTotalNodes(); _brickErrors = std::vector(nHistograms); for (unsigned int brickIndex = 0; brickIndex < nHistograms; brickIndex++) { if (_tsp->isOctreeLeaf(brickIndex)) { _brickErrors[brickIndex].spatial = 0.0; } else { - const Histogram* histogram = _histogramManager->getSpatialHistogram( + const Histogram* histogram = _histogramManager->spatialHistogram( brickIndex ); float error = 0; @@ -365,7 +372,7 @@ bool LocalTfBrickSelector::calculateBrickErrors() { if (_tsp->isBstLeaf(brickIndex)) { _brickErrors[brickIndex].temporal = 0.0; } else { - const Histogram* histogram = _histogramManager->getTemporalHistogram( + const Histogram* histogram = _histogramManager->temporalHistogram( brickIndex ); float error = 0; @@ -383,9 +390,9 @@ bool LocalTfBrickSelector::calculateBrickErrors() { return true; } -int LocalTfBrickSelector::linearCoords(int x, int y, int z) { +int LocalTfBrickSelector::linearCoordinates(int x, int y, int z) const { const TSP::Header &header = _tsp->header(); - return x + (header.xNumBricks_ * y) + (header.xNumBricks_ * header.yNumBricks_ * z); + return x + (header.xNumBricks * y) + (header.xNumBricks * header.yNumBricks * z); } void LocalTfBrickSelector::writeSelection(BrickSelection brickSelection, @@ -395,11 +402,10 @@ void LocalTfBrickSelector::writeSelection(BrickSelection brickSelection, for (int z = coveredBricks.lowZ; z < coveredBricks.highZ; z++) { for (int y = coveredBricks.lowY; y < coveredBricks.highY; y++) { for (int x = coveredBricks.lowX; x < coveredBricks.highX; x++) { - bricks[linearCoords(x, y, z)] = brickSelection.brickIndex; + bricks[linearCoordinates(x, y, z)] = brickSelection.brickIndex; } } } } - } // namespace openspace diff --git a/modules/multiresvolume/rendering/localtfbrickselector.h b/modules/multiresvolume/rendering/localtfbrickselector.h index 94362b37f2..632f045c8a 100644 --- a/modules/multiresvolume/rendering/localtfbrickselector.h +++ b/modules/multiresvolume/rendering/localtfbrickselector.h @@ -25,10 +25,10 @@ #ifndef __OPENSPACE_MODULE_MULTIRESVOLUME___LOCALTFBRICKSELECTOR___H__ #define __OPENSPACE_MODULE_MULTIRESVOLUME___LOCALTFBRICKSELECTOR___H__ -#include -#include #include -#include + +#include +#include namespace openspace { @@ -45,7 +45,7 @@ public: LocalTfBrickSelector(TSP* tsp, LocalErrorHistogramManager* hm, TransferFunction* tf, int memoryBudget, int streamingBudget); - ~LocalTfBrickSelector(); + ~LocalTfBrickSelector() = default; bool initialize() override; @@ -60,11 +60,11 @@ private: TransferFunction* _transferFunction; std::vector _brickErrors; - float spatialSplitPoints(unsigned int brickIndex); - float temporalSplitPoints(unsigned int brickIndex); + float spatialSplitPoints(unsigned int brickIndex) const; + float temporalSplitPoints(unsigned int brickIndex) const; float splitPoints(unsigned int brickIndex, BrickSelection::SplitType& splitType); - int linearCoords(int x, int y, int z); + int linearCoordinates(int x, int y, int z) const; void writeSelection(BrickSelection coveredBricks, std::vector& bricks); int _memoryBudget; diff --git a/modules/multiresvolume/rendering/multiresvolumeraycaster.cpp b/modules/multiresvolume/rendering/multiresvolumeraycaster.cpp index 1480291584..8eddda4f16 100644 --- a/modules/multiresvolume/rendering/multiresvolumeraycaster.cpp +++ b/modules/multiresvolume/rendering/multiresvolumeraycaster.cpp @@ -22,25 +22,25 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include -#include - #include -#include -#include -#include -#include -#include -#include +#include +#include #include +#include +#include +#include #include namespace { - const char* GlslRaycastPath = "${MODULES}/multiresvolume/shaders/raycast.glsl"; - const char* GlslHelperPath = "${MODULES}/multiresvolume/shaders/helper.glsl"; - const char* GlslBoundsVsPath = "${MODULES}/multiresvolume/shaders/boundsVs.glsl"; - const char* GlslBoundsFsPath = "${MODULES}/multiresvolume/shaders/boundsFs.glsl"; + constexpr const char* GlslRaycastPath = + "${MODULES}/multiresvolume/shaders/raycast.glsl"; + constexpr const char* GlslHelperPath = + "${MODULES}/multiresvolume/shaders/helper.glsl"; + constexpr const char* GlslBoundsVsPath = + "${MODULES}/multiresvolume/shaders/boundsVs.glsl"; + constexpr const char* GlslBoundsFsPath = + "${MODULES}/multiresvolume/shaders/boundsFs.glsl"; } // namespace namespace openspace { @@ -48,7 +48,7 @@ namespace openspace { MultiresVolumeRaycaster::MultiresVolumeRaycaster(std::shared_ptr tsp, std::shared_ptr atlasManager, std::shared_ptr transferFunction) - : _boundingBox(glm::vec3(1.0)) + : _boundingBox(glm::vec3(1.f)) , _tsp(tsp) , _atlasManager(atlasManager) , _transferFunction(transferFunction) @@ -69,39 +69,30 @@ void MultiresVolumeRaycaster::renderEntryPoints(const RenderData& data, program.setUniform("viewProjection", data.camera.viewProjectionMatrix()); Renderable::setPscUniforms(program, data.camera, data.position); - // Cull back face glEnable(GL_CULL_FACE); glCullFace(GL_BACK); - // Render bounding geometry _boundingBox.render(); } void MultiresVolumeRaycaster::renderExitPoints(const RenderData& data, ghoul::opengl::ProgramObject& program) { - // Uniforms program.setUniform("modelTransform", _modelTransform); program.setUniform("viewProjection", data.camera.viewProjectionMatrix()); Renderable::setPscUniforms(program, data.camera, data.position); - // Cull front face glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); - // Render bounding geometry _boundingBox.render(); - // Restore defaults glCullFace(GL_BACK); } void MultiresVolumeRaycaster::preRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) { - std::string timestepUniformName = "timestep" + std::to_string(data.id); - std::string stepSizeUniformName = "maxStepSize" + std::to_string(data.id); - std::string id = std::to_string(data.id); //program.setUniform("opacity_" + std::to_string(id), visible ? 1.0f : 0.0f); program.setUniform("stepSizeCoefficient_" + id, _stepSizeCoefficient); @@ -126,10 +117,10 @@ void MultiresVolumeRaycaster::preRaycast(const RaycastData& data, ); program.setSsboBinding("atlasMapBlock_" + id, _atlasMapBinding->bindingNumber()); - program.setUniform("gridType_" + id, static_cast(_tsp->header().gridType_)); + program.setUniform("gridType_" + id, static_cast(_tsp->header().gridType)); program.setUniform( "maxNumBricksPerAxis_" + id, - static_cast(_tsp->header().xNumBricks_) + static_cast(_tsp->header().xNumBricks) ); program.setUniform("paddedBrickDim_" + id, _tsp->paddedBrickDim()); @@ -164,7 +155,7 @@ bool MultiresVolumeRaycaster::isCameraInside(const RenderData& data, localPosition = (glm::vec3(modelPos) + glm::vec3(0.5)); return (localPosition.x > 0 && localPosition.y > 0 && localPosition.z > 0 && - localPosition.x < 1 && localPosition.y < 1 && localPosition.z < 1); + localPosition.x < 1 && localPosition.y < 1 && localPosition.z < 1); } void MultiresVolumeRaycaster::postRaycast(const RaycastData&, diff --git a/modules/multiresvolume/rendering/multiresvolumeraycaster.h b/modules/multiresvolume/rendering/multiresvolumeraycaster.h index b7e6da15dc..5a05d879fe 100644 --- a/modules/multiresvolume/rendering/multiresvolumeraycaster.h +++ b/modules/multiresvolume/rendering/multiresvolumeraycaster.h @@ -25,32 +25,29 @@ #ifndef __OPENSPACE_MODULE_MULTIRESVOLUME___MULTIRESVOLUMERAYCASTER___H__ #define __OPENSPACE_MODULE_MULTIRESVOLUME___MULTIRESVOLUMERAYCASTER___H__ -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include namespace ghoul::opengl { class Texture; class ProgramObject; -} +} // namespace ghoul::opengl namespace openspace { +class AtlasManager; struct RenderData; struct RaycastData; +class TSP; +class TransferFunction; class MultiresVolumeRaycaster : public VolumeRaycaster { public: - MultiresVolumeRaycaster(std::shared_ptr tsp, std::shared_ptr atlasManager, std::shared_ptr transferFunction); diff --git a/modules/multiresvolume/rendering/renderablemultiresvolume.cpp b/modules/multiresvolume/rendering/renderablemultiresvolume.cpp index 82c9950f3d..e43e53d2c7 100644 --- a/modules/multiresvolume/rendering/renderablemultiresvolume.cpp +++ b/modules/multiresvolume/rendering/renderablemultiresvolume.cpp @@ -29,8 +29,11 @@ #include #include #include +#include #include +#include +#include #include #include @@ -61,6 +64,8 @@ #include #include +#include + namespace { constexpr const char* _loggerCat = "RenderableMultiresVolume"; constexpr const char* KeyDataSource = "Source"; @@ -160,7 +165,7 @@ namespace { namespace openspace { -RenderableMultiresVolume::RenderableMultiresVolume (const ghoul::Dictionary& dictionary) +RenderableMultiresVolume::RenderableMultiresVolume(const ghoul::Dictionary& dictionary) : Renderable(dictionary) , _useGlobalTime(UseGlobalTimeInfo, false) , _loop(LoopInfo, false) @@ -168,7 +173,7 @@ RenderableMultiresVolume::RenderableMultiresVolume (const ghoul::Dictionary& dic , _memoryBudget(MemoryBudgetInfo, 0, 0, 0) , _streamingBudget(StreamingBudgetInfo, 0, 0, 0) , _stepSizeCoefficient(StepSizeCoefficientInfo, 1.f, 0.01f, 10.f) - , _selectorName(SelectorNameInfo) + , _selectorName(SelectorNameInfo, "tf") , _statsToFile(StatsToFileInfo, false) , _statsToFileName(StatsToFileNameInfo) , _scalingExponent(ScalingExponentInfo, 1, -10, 20) @@ -176,83 +181,65 @@ RenderableMultiresVolume::RenderableMultiresVolume (const ghoul::Dictionary& dic , _rotation(RotationInfo, glm::vec3(0.f, 0.f, 0.f), glm::vec3(0.f), glm::vec3(6.28f)) , _scaling(ScalingInfo, glm::vec3(1.f), glm::vec3(0.f), glm::vec3(10.f)) { - std::string name; - - _filename = ""; - bool success = dictionary.getValue(KeyDataSource, _filename); - if (!success) { - LERROR(fmt::format( - "Node '{}' did not contain a valid '{}'", - name, - KeyDataSource - )); - return; + if (dictionary.hasKeyAndValue(KeyDataSource)) { + _filename = absPath(dictionary.value(KeyDataSource)); } - _filename = absPath(_filename); - if (_filename == "") { + else { + LERROR(fmt::format("Node did not contain a valid '{}'", KeyDataSource)); return; } - _errorHistogramsPath = ""; - if (dictionary.getValue(KeyErrorHistogramsSource, _errorHistogramsPath)) { - _errorHistogramsPath = absPath(_errorHistogramsPath); + if (dictionary.hasKeyAndValue(KeyErrorHistogramsSource)) { + _errorHistogramsPath = absPath( + dictionary.value(KeyErrorHistogramsSource) + ); } - - - float scalingExponent, stepSizeCoefficient; - glm::vec3 scaling, translation, rotation; - - if (dictionary.getValue("ScalingExponent", scalingExponent)) { - _scalingExponent = static_cast(scalingExponent); - } - if (dictionary.getValue("Scaling", scaling)) { - _scaling = scaling; - } - if (dictionary.getValue("Translation", translation)) { - _translation = translation; - } - if (dictionary.getValue("Rotation", rotation)) { - _rotation = rotation; - } - if (dictionary.getValue("StepSizeCoefficient", stepSizeCoefficient)) { - _stepSizeCoefficient = stepSizeCoefficient; + if (dictionary.hasKeyAndValue("ScalingExponent")) { + _scalingExponent = static_cast(dictionary.value("ScalingExponent")); } + if (dictionary.hasKeyAndValue("StepSizeCoefficient")) { + _stepSizeCoefficient = static_cast( + dictionary.value("StepSizeCoefficient") + ); + } + + if (dictionary.hasKeyAndValue("Scaling")) { + _scaling = dictionary.value("Scaling"); + } + + if (dictionary.hasKeyAndValue("Translation")) { + _translation = dictionary.value("Translation"); + } + + if (dictionary.hasKeyAndValue("Rotation")) { + _rotation = dictionary.value("Rotation"); + } std::string startTimeString, endTimeString; - bool hasTimeData = true; - hasTimeData &= dictionary.getValue(KeyStartTime, startTimeString); - hasTimeData &= dictionary.getValue(KeyEndTime, endTimeString); + + bool hasTimeData = dictionary.getValue(KeyStartTime, startTimeString) && + dictionary.getValue(KeyEndTime, endTimeString); if (hasTimeData) { _startTime = SpiceManager::ref().ephemerisTimeFromDate(startTimeString); _endTime = SpiceManager::ref().ephemerisTimeFromDate(endTimeString); - } - if (hasTimeData) { _loop = false; } else { - _loop = true; - LWARNING(fmt::format( - "Node '{}' does not provide valid time information. Viewing one image per " - "frame.", - name - )); + _loop = true; + LWARNING("Node does not provide time information. Viewing one image / frame"); } - - _transferFunction = nullptr; - _transferFunctionPath = ""; - success = dictionary.getValue(KeyTransferFunction, _transferFunctionPath); - if (!success) { - LERROR(fmt::format( - "Node '{}' did not contain a valid '{}'", - name, - KeyTransferFunction - )); + if (dictionary.hasKeyAndValue(KeyTransferFunction)) { + _transferFunctionPath = absPath( + dictionary.value(KeyTransferFunction) + ); + _transferFunction = std::make_shared(_transferFunctionPath); + } + else { + LERROR(fmt::format("Node did not contain a valid '{}'", KeyTransferFunction)); return; } - _transferFunctionPath = absPath(_transferFunctionPath); - _transferFunction = std::make_shared(_transferFunctionPath); //_pscOffset = psc(glm::vec4(0.0)); //_boxScaling = glm::vec3(1.0); @@ -275,18 +262,11 @@ RenderableMultiresVolume::RenderableMultiresVolume (const ghoul::Dictionary& dic } }*/ - //setBoundingSphere(PowerScaledScalar::CreatePSS(glm::length(_boxScaling)*pow(10,_w))); - _tsp = std::make_shared(_filename); _atlasManager = std::make_shared(_tsp.get()); - _selectorName = "tf"; - std::string brickSelectorType; - if (dictionary.hasKey(KeyBrickSelector)) { - success = dictionary.getValue(KeyBrickSelector, brickSelectorType); - if (success) { - _selectorName = brickSelectorType; - } + if (dictionary.hasKeyAndValue(KeyBrickSelector)) { + _selectorName = dictionary.value(KeyBrickSelector); } std::string selectorName = _selectorName; @@ -323,110 +303,94 @@ RenderableMultiresVolume::RenderableMultiresVolume (const ghoul::Dictionary& dic addProperty(_scalingExponent); addProperty(_translation); addProperty(_rotation); - - //_brickSelector = new ShenBrickSelector(_tsp, -1, -1); } -RenderableMultiresVolume::~RenderableMultiresVolume() { - //OsEng.renderEngine()->aBuffer()->removeVolume(this); +RenderableMultiresVolume::~RenderableMultiresVolume() {} - if (_tfBrickSelector) - delete _tfBrickSelector; - if (_simpleTfBrickSelector) - delete _simpleTfBrickSelector; - if (_localTfBrickSelector) - delete _localTfBrickSelector; - - if (_errorHistogramManager) - delete _errorHistogramManager; - if (_histogramManager) - delete _histogramManager; - if (_localErrorHistogramManager) - delete _localErrorHistogramManager; -} - -bool RenderableMultiresVolume::setSelectorType(Selector selector) { +void RenderableMultiresVolume::setSelectorType(Selector selector) { + // @TODO(abock): Can these if statements be simplified by checking if + // selector == _selector before and bailing out early? _selector = selector; switch (_selector) { case Selector::TF: if (!_tfBrickSelector) { - TfBrickSelector* tbs; - _errorHistogramManager = new ErrorHistogramManager(_tsp.get()); - _tfBrickSelector = tbs = new TfBrickSelector( + _errorHistogramManager = std::make_unique( + _tsp.get() + ); + _tfBrickSelector = std::make_unique( _tsp.get(), - _errorHistogramManager, + _errorHistogramManager.get(), _transferFunction.get(), _memoryBudget, _streamingBudget ); - _transferFunction->setCallback([tbs](const TransferFunction& /*tf*/) { - tbs->calculateBrickErrors(); + _transferFunction->setCallback([this](const TransferFunction&) { + _tfBrickSelector->calculateBrickErrors(); }); if (initializeSelector()) { - tbs->calculateBrickErrors(); - return true; + _tfBrickSelector->calculateBrickErrors(); + return; } } break; case Selector::SIMPLE: if (!_simpleTfBrickSelector) { - SimpleTfBrickSelector *stbs; - _histogramManager = new HistogramManager(); - _simpleTfBrickSelector = stbs = new SimpleTfBrickSelector( + _histogramManager = std::make_unique(); + _simpleTfBrickSelector = std::make_unique( _tsp.get(), - _histogramManager, + _histogramManager.get(), _transferFunction.get(), _memoryBudget, _streamingBudget ); - _transferFunction->setCallback([stbs](const TransferFunction& /*tf*/) { - stbs->calculateBrickImportances(); + _transferFunction->setCallback([this](const TransferFunction&) { + _simpleTfBrickSelector->calculateBrickImportances(); }); if (initializeSelector()) { - stbs->calculateBrickImportances(); - return true; + _simpleTfBrickSelector->calculateBrickImportances(); + return; } } break; case Selector::LOCAL: if (!_localTfBrickSelector) { - LocalTfBrickSelector* ltbs; - _localErrorHistogramManager = new LocalErrorHistogramManager(_tsp.get()); - _localTfBrickSelector = ltbs = new LocalTfBrickSelector( + _localErrorHistogramManager = + std::make_unique(_tsp.get()); + _localTfBrickSelector = std::make_unique( _tsp.get(), - _localErrorHistogramManager, + _localErrorHistogramManager.get(), _transferFunction.get(), _memoryBudget, _streamingBudget ); - _transferFunction->setCallback([ltbs](const TransferFunction& /*tf*/) { - ltbs->calculateBrickErrors(); + _transferFunction->setCallback([this](const TransferFunction&) { + _localTfBrickSelector->calculateBrickErrors(); }); if (initializeSelector()) { - ltbs->calculateBrickErrors(); - return true; + _localTfBrickSelector->calculateBrickErrors(); + return; } } break; } - return false; } void RenderableMultiresVolume::initializeGL() { bool success = _tsp && _tsp->load(); - unsigned int maxNumBricks = _tsp->header().xNumBricks_ * _tsp->header().yNumBricks_ * _tsp->header().zNumBricks_; + unsigned int maxNumBricks = _tsp->header().xNumBricks * _tsp->header().yNumBricks * + _tsp->header().zNumBricks; - unsigned int maxInitialBudget = 2048; - int initialBudget = std::min(maxInitialBudget, maxNumBricks); + constexpr unsigned int MaxInitialBudget = 2048; + int initialBudget = std::min(MaxInitialBudget, maxNumBricks); _currentTime = properties::IntProperty( CurrentTimeInfo, 0, 0, - _tsp->header().numTimesteps_ - 1 + _tsp->header().numTimesteps - 1 ); _memoryBudget = properties::IntProperty( MemoryBudgetInfo, @@ -446,7 +410,7 @@ void RenderableMultiresVolume::initializeGL() { if (success) { _brickIndices.resize(maxNumBricks, 0); - success &= setSelectorType(_selector); + setSelectorType(_selector); } success &= _atlasManager && _atlasManager->initialize(); @@ -455,17 +419,21 @@ void RenderableMultiresVolume::initializeGL() { success &= isReady(); - _raycaster = std::make_unique(_tsp, _atlasManager, _transferFunction); + _raycaster = std::make_unique( + _tsp, + _atlasManager, + _transferFunction + ); _raycaster->initialize(); - OsEng.renderEngine().raycasterManager().attachRaycaster(*_raycaster.get()); + OsEng.renderEngine().raycasterManager().attachRaycaster(*_raycaster); - std::function onChange = [&](bool enabled) { + auto onChange = [&](bool enabled) { if (enabled) { - OsEng.renderEngine().raycasterManager().attachRaycaster(*_raycaster.get()); + OsEng.renderEngine().raycasterManager().attachRaycaster(*_raycaster); } else { - OsEng.renderEngine().raycasterManager().detachRaycaster(*_raycaster.get()); + OsEng.renderEngine().raycasterManager().detachRaycaster(*_raycaster); } }; @@ -497,22 +465,23 @@ bool RenderableMultiresVolume::initializeSelector() { cacheName << f.baseName() << "_" << nHistograms << "_errorHistograms"; std::string cacheFilename; cacheFilename = FileSys.cacheManager()->cachedFilename( - cacheName.str(), "", ghoul::filesystem::CacheManager::Persistent::Yes); + cacheName.str(), + "", + ghoul::filesystem::CacheManager::Persistent::Yes + ); std::ifstream cacheFile(cacheFilename, std::ios::in | std::ios::binary); std::string errorHistogramsPath = _errorHistogramsPath; if (cacheFile.is_open()) { // Read histograms from cache. cacheFile.close(); - LINFO(fmt::format( - "Loading histograms from cache: {}", - cacheFilename - )); + LINFO( + fmt::format("Loading histograms from cache: {}", cacheFilename) + ); success &= _errorHistogramManager->loadFromFile(cacheFilename); } else if (_errorHistogramsPath != "") { // Read histograms from scene data. LINFO(fmt::format( - "Loading histograms from scene data: {}", - _errorHistogramsPath + "Loading histograms from scene data: {}", _errorHistogramsPath )); success &= _errorHistogramManager->loadFromFile(_errorHistogramsPath); } else { @@ -535,7 +504,10 @@ bool RenderableMultiresVolume::initializeSelector() { cacheName << f.baseName() << "_" << nHistograms << "_histograms"; std::string cacheFilename; cacheFilename = FileSys.cacheManager()->cachedFilename( - cacheName.str(), "", ghoul::filesystem::CacheManager::Persistent::Yes); + cacheName.str(), + "", + ghoul::filesystem::CacheManager::Persistent::Yes + ); std::ifstream cacheFile(cacheFilename, std::ios::in | std::ios::binary); if (cacheFile.is_open()) { // Read histograms from cache. @@ -560,12 +532,13 @@ bool RenderableMultiresVolume::initializeSelector() { case Selector::LOCAL: if (_localErrorHistogramManager) { - std::stringstream cacheName; ghoul::filesystem::File f = _filename; - cacheName << f.baseName() << "_" << nHistograms << "_localErrorHistograms"; std::string cacheFilename; cacheFilename = FileSys.cacheManager()->cachedFilename( - cacheName.str(), "", ghoul::filesystem::CacheManager::Persistent::Yes); + fmt::format("{}_{}_localErrorHistograms", f.baseName(), nHistograms), + "", + ghoul::filesystem::CacheManager::Persistent::Yes + ); std::ifstream cacheFile(cacheFilename, std::ios::in | std::ios::binary); if (cacheFile.is_open()) { // Read histograms from cache. @@ -614,12 +587,12 @@ void RenderableMultiresVolume::preResolve(ghoul::opengl::ProgramObject* program) program->setSsboBinding(ss.str(), getSsboBinding(_atlasManager->atlasMapBuffer())); ss.str(std::string()); - ss << "gridType_" << getId(); - program->setUniform(ss.str(), static_cast(_tsp->header().gridType_)); + ss << "gridType" << getId(); + program->setUniform(ss.str(), static_cast(_tsp->header().gridType)); ss.str(std::string()); ss << "maxNumBricksPerAxis_" << getId(); - program->setUniform(ss.str(), static_cast(_tsp->header().xNumBricks_)); + program->setUniform(ss.str(), static_cast(_tsp->header().xNumBricks)); ss.str(std::string()); ss << "paddedBrickDim_" << getId(); @@ -636,7 +609,10 @@ void RenderableMultiresVolume::preResolve(ghoul::opengl::ProgramObject* program) */ /* std::vector RenderableMultiresVolume::getTextures() { - std::vector textures{_transferFunction->texture(), _atlasManager->textureAtlas()}; + std::vector textures{ + _transferFunction->texture(), + _atlasManager->textureAtlas() + }; return textures; } @@ -680,8 +656,7 @@ void RenderableMultiresVolume::update(const UpdateData& data) { _statsToFile = false; } - - int numTimesteps = _tsp->header().numTimesteps_; + int numTimesteps = _tsp->header().numTimesteps; int currentTimestep; bool visible = true; if (_loop) { @@ -697,39 +672,39 @@ void RenderableMultiresVolume::update(const UpdateData& data) { } if (visible) { - std::chrono::system_clock::time_point selectionStart; if (_gatheringStats) { selectionStart = std::chrono::system_clock::now(); } switch (_selector) { - case Selector::TF: - if (_tfBrickSelector) { - _tfBrickSelector->setMemoryBudget(_memoryBudget); - _tfBrickSelector->setStreamingBudget(_streamingBudget); - _tfBrickSelector->selectBricks(currentTimestep, _brickIndices); - } - break; - case Selector::SIMPLE: - if (_simpleTfBrickSelector) { - _simpleTfBrickSelector->setMemoryBudget(_memoryBudget); - _simpleTfBrickSelector->setStreamingBudget(_streamingBudget); - _simpleTfBrickSelector->selectBricks(currentTimestep, _brickIndices); - } - break; - case Selector::LOCAL: - if (_localTfBrickSelector) { - _localTfBrickSelector->setMemoryBudget(_memoryBudget); - _localTfBrickSelector->setStreamingBudget(_streamingBudget); - _localTfBrickSelector->selectBricks(currentTimestep, _brickIndices); - } - break; + case Selector::TF: + if (_tfBrickSelector) { + _tfBrickSelector->setMemoryBudget(_memoryBudget); + _tfBrickSelector->setStreamingBudget(_streamingBudget); + _tfBrickSelector->selectBricks(currentTimestep, _brickIndices); + } + break; + case Selector::SIMPLE: + if (_simpleTfBrickSelector) { + _simpleTfBrickSelector->setMemoryBudget(_memoryBudget); + _simpleTfBrickSelector->setStreamingBudget(_streamingBudget); + _simpleTfBrickSelector->selectBricks(currentTimestep, _brickIndices); + } + break; + case Selector::LOCAL: + if (_localTfBrickSelector) { + _localTfBrickSelector->setMemoryBudget(_memoryBudget); + _localTfBrickSelector->setStreamingBudget(_streamingBudget); + _localTfBrickSelector->selectBricks(currentTimestep, _brickIndices); + } + break; } std::chrono::system_clock::time_point uploadStart; if (_gatheringStats) { - std::chrono::system_clock::time_point selectionEnd = std::chrono::system_clock::now(); + std::chrono::system_clock::time_point selectionEnd = + std::chrono::system_clock::now(); _selectionDuration = selectionEnd - selectionStart; uploadStart = selectionEnd; } @@ -737,32 +712,39 @@ void RenderableMultiresVolume::update(const UpdateData& data) { _atlasManager->updateAtlas(AtlasManager::EVEN, _brickIndices); if (_gatheringStats) { - std::chrono::system_clock::time_point uploadEnd = std::chrono::system_clock::now(); + std::chrono::system_clock::time_point uploadEnd = + std::chrono::system_clock::now(); _uploadDuration = uploadEnd - uploadStart; - _nDiskReads = _atlasManager->getNumDiskReads(); - _nUsedBricks = _atlasManager->getNumUsedBricks(); - _nStreamedBricks = _atlasManager->getNumStreamedBricks(); + _nDiskReads = _atlasManager->numDiskReads(); + _nUsedBricks = _atlasManager->numUsedBricks(); + _nStreamedBricks = _atlasManager->numStreamedBricks(); } } if (_raycaster) { - - glm::mat4 transform = glm::translate(glm::mat4(1.0), static_cast(_translation) * std::pow(10.0f, static_cast(_scalingExponent))); + glm::mat4 transform = glm::translate( + glm::mat4(1.0), + static_cast(_translation) * + std::pow(10.f, static_cast(_scalingExponent)) + ); glm::vec3 eulerRotation = static_cast(_rotation); - transform = glm::rotate(transform, eulerRotation.x, glm::vec3(1, 0, 0)); - transform = glm::rotate(transform, eulerRotation.y, glm::vec3(0, 1, 0)); - transform = glm::rotate(transform, eulerRotation.z, glm::vec3(0, 0, 1)); - transform = glm::scale(transform, static_cast(_scaling) * std::pow(10.0f, static_cast(_scalingExponent))); + transform = glm::rotate(transform, eulerRotation.x, glm::vec3(1.f, 0.f, 0.f)); + transform = glm::rotate(transform, eulerRotation.y, glm::vec3(0.f, 1.f, 0.f)); + transform = glm::rotate(transform, eulerRotation.z, glm::vec3(0.f, 0.f, 1.f)); + transform = glm::scale( + transform, + static_cast(_scaling) * + std::pow(10.f, static_cast(_scalingExponent)) + ); _raycaster->setStepSizeCoefficient(_stepSizeCoefficient); _raycaster->setModelTransform(transform); //_raycaster->setTime(data.time); } - } void RenderableMultiresVolume::render(const RenderData& data, RendererTasks& tasks) { - RaycasterTask task{ _raycaster.get(), data }; + RaycasterTask task { _raycaster.get(), data }; tasks.raycasterTasks.push_back(task); } diff --git a/modules/multiresvolume/rendering/renderablemultiresvolume.h b/modules/multiresvolume/rendering/renderablemultiresvolume.h index 0a4f51571a..6a3d432404 100644 --- a/modules/multiresvolume/rendering/renderablemultiresvolume.h +++ b/modules/multiresvolume/rendering/renderablemultiresvolume.h @@ -25,23 +25,17 @@ #ifndef __OPENSPACE_MODULE_MULTIRESVOLUME___RENDERABLEMULTIRESVOLUME___H__ #define __OPENSPACE_MODULE_MULTIRESVOLUME___RENDERABLEMULTIRESVOLUME___H__ -#include -#include -#include #include -#include -#include -#include + #include #include #include #include #include -#include +#include -// Forward declare to minimize dependencies +namespace ghoul { class Dictionary; } namespace ghoul::filesystem { class File; } - namespace ghoul::opengl { class ProgramObject; class Texture; @@ -49,25 +43,30 @@ namespace ghoul::opengl { namespace openspace { -class TSP; class AtlasManager; class BrickSelector; -class TfBrickSelector; -class SimpleTfBrickSelector; -class LocalTfBrickSelector; -class HistogramManager; class ErrorHistogramManager; +class HistogramManager; class LocalErrorHistogramManager; - +class LocalTfBrickSelector; +class MultiresVolumeRaycaster; +class SimpleTfBrickSelector; +class TfBrickSelector; +class TransferFunction; +class TSP; class RenderableMultiresVolume : public Renderable { public: RenderableMultiresVolume(const ghoul::Dictionary& dictionary); ~RenderableMultiresVolume(); - enum Selector {TF, SIMPLE, LOCAL}; + enum Selector { + TF, + SIMPLE, + LOCAL + }; - bool setSelectorType(Selector selector); + void setSelectorType(Selector selector); bool initializeSelector(); void initializeGL() override; @@ -85,10 +84,6 @@ public: //virtual std::vector getBuffers() override; private: - double _time; - double _startTime; - double _endTime; - properties::BoolProperty _useGlobalTime; properties::BoolProperty _loop; // used to vary time, if not using global time nor looping @@ -99,6 +94,15 @@ private: properties::StringProperty _selectorName; properties::BoolProperty _statsToFile; properties::StringProperty _statsToFileName; + properties::IntProperty _scalingExponent; + properties::Vec3Property _translation; + properties::Vec3Property _rotation; + properties::Vec3Property _scaling; + + double _time; + double _startTime; + double _endTime; + // Stats timers std::string _statsFileName; @@ -133,24 +137,15 @@ private: std::unique_ptr _raycaster; - TfBrickSelector* _tfBrickSelector = nullptr; - SimpleTfBrickSelector* _simpleTfBrickSelector = nullptr; - LocalTfBrickSelector* _localTfBrickSelector = nullptr; + std::unique_ptr _tfBrickSelector; + std::unique_ptr _simpleTfBrickSelector; + std::unique_ptr _localTfBrickSelector; Selector _selector; - HistogramManager* _histogramManager = nullptr; - ErrorHistogramManager* _errorHistogramManager = nullptr; - LocalErrorHistogramManager* _localErrorHistogramManager = nullptr; - - float _w; - PowerScaledCoordinate _pscOffset; - - properties::IntProperty _scalingExponent; - properties::Vec3Property _translation; - properties::Vec3Property _rotation; - properties::Vec3Property _scaling; - + std::unique_ptr _histogramManager; + std::unique_ptr _errorHistogramManager; + std::unique_ptr _localErrorHistogramManager; }; } // namespace openspace diff --git a/modules/multiresvolume/rendering/shenbrickselector.cpp b/modules/multiresvolume/rendering/shenbrickselector.cpp index 366409b9e2..ce7f341e05 100644 --- a/modules/multiresvolume/rendering/shenbrickselector.cpp +++ b/modules/multiresvolume/rendering/shenbrickselector.cpp @@ -24,16 +24,16 @@ #include +#include + namespace openspace { -ShenBrickSelector::ShenBrickSelector(TSP* tsp, float spatialTolerance, float temporalTolerance) +ShenBrickSelector::ShenBrickSelector(TSP* tsp, float spatialTolerance, + float temporalTolerance) : _tsp(tsp) , _spatialTolerance(spatialTolerance) - , _temporalTolerance(temporalTolerance) {} - -ShenBrickSelector::~ShenBrickSelector() { - -} + , _temporalTolerance(temporalTolerance) +{} void ShenBrickSelector::setSpatialTolerance(float spatialTolerance) { _spatialTolerance = spatialTolerance; @@ -44,17 +44,19 @@ void ShenBrickSelector::setTemporalTolerance(float temporalTolerance) { } void ShenBrickSelector::selectBricks(int timestep, std::vector& bricks) { - int numTimeSteps = _tsp->header().numTimesteps_; - BrickCover coveredBricks(_tsp->header().xNumBricks_); + int numTimeSteps = _tsp->header().numTimesteps; + BrickCover coveredBricks(_tsp->header().xNumBricks); selectBricks(timestep, 0, 0, 0, numTimeSteps, coveredBricks, bricks); } /** * Traverse the Octree in the BST root */ -void ShenBrickSelector::traverseOT(int timestep, unsigned int brickIndex, BrickCover coveredBricks, std::vector& bricks) { - unsigned int firstChild = _tsp->getFirstOctreeChild(brickIndex); - int numTimeSteps = _tsp->header().numTimesteps_; +void ShenBrickSelector::traverseOT(int timestep, unsigned int brickIndex, + BrickCover coveredBricks, std::vector& bricks) +{ + unsigned int firstChild = _tsp->firstOctreeChild(brickIndex); + int numTimeSteps = _tsp->header().numTimesteps; for (unsigned int i = 0; i < 8; i++) { unsigned int child = firstChild + i; BrickCover cover = coveredBricks.split(i % 2, (i/2) % 2, (i/4)); @@ -62,44 +64,53 @@ void ShenBrickSelector::traverseOT(int timestep, unsigned int brickIndex, BrickC } } -void ShenBrickSelector::traverseBST(int timestep, - unsigned int brickIndex, - unsigned int bstRootBrickIndex, - int timeSpanStart, - int timeSpanEnd, - BrickCover coveredBricks, - std::vector& bricks) { - - +void ShenBrickSelector::traverseBST(int timestep, unsigned int brickIndex, + unsigned int bstRootBrickIndex, int timeSpanStart, + int timeSpanEnd, BrickCover coveredBricks, + std::vector& bricks) +{ int timeSpanCenter = timeSpanStart + (timeSpanEnd - timeSpanStart) / 2; unsigned int bstChild; if (timestep <= timeSpanCenter) { - bstChild = _tsp->getBstLeft(brickIndex); + bstChild = _tsp->bstLeft(brickIndex); timeSpanEnd = timeSpanCenter; } else { - bstChild = _tsp->getBstRight(brickIndex); + bstChild = _tsp->bstRight(brickIndex); timeSpanStart = timeSpanCenter; } - selectBricks(timestep, bstChild, bstRootBrickIndex, timeSpanStart, timeSpanEnd, coveredBricks, bricks); + selectBricks( + timestep, + bstChild, + bstRootBrickIndex, + timeSpanStart, + timeSpanEnd, + coveredBricks, + bricks + ); } -void ShenBrickSelector::selectBricks(int timestep, - unsigned int brickIndex, - unsigned int bstRootBrickIndex, - int timeSpanStart, - int timeSpanEnd, - BrickCover coveredBricks, - std::vector& bricks) { - - if (_tsp->getTemporalError(brickIndex) <= _temporalTolerance) { +void ShenBrickSelector::selectBricks(int timestep, unsigned int brickIndex, + unsigned int bstRootBrickIndex, int timeSpanStart, + int timeSpanEnd, BrickCover coveredBricks, + std::vector& bricks) +{ + if (_tsp->temporalError(brickIndex) <= _temporalTolerance) { if (_tsp->isOctreeLeaf(bstRootBrickIndex)) { selectCover(coveredBricks, brickIndex, bricks); - } else if (_tsp->getSpatialError(brickIndex) <= _spatialTolerance) { + } else if (_tsp->spatialError(brickIndex) <= _spatialTolerance) { selectCover(coveredBricks, brickIndex, bricks); } else if (_tsp->isBstLeaf(brickIndex)) { traverseOT(timestep, bstRootBrickIndex, coveredBricks, bricks); } else { - traverseBST(timestep, brickIndex, bstRootBrickIndex, timeSpanStart, timeSpanEnd, coveredBricks, bricks); + traverseBST( + timestep, + brickIndex, + bstRootBrickIndex, + timeSpanStart, + timeSpanEnd, + coveredBricks, + bricks + ); } } else if (_tsp->isBstLeaf(brickIndex)) { if (_tsp->isOctreeLeaf(bstRootBrickIndex)) { @@ -108,16 +119,26 @@ void ShenBrickSelector::selectBricks(int timestep, traverseOT(timestep, bstRootBrickIndex, coveredBricks, bricks); } } else { - traverseBST(timestep, brickIndex, bstRootBrickIndex, timeSpanStart, timeSpanEnd, coveredBricks, bricks); + traverseBST( + timestep, + brickIndex, + bstRootBrickIndex, + timeSpanStart, + timeSpanEnd, + coveredBricks, + bricks + ); } } -int ShenBrickSelector::linearCoords(int x, int y, int z) { - const TSP::Header &header = _tsp->header(); - return x + (header.xNumBricks_ * y) + (header.xNumBricks_ * header.yNumBricks_ * z); +int ShenBrickSelector::linearCoords(int x, int y, int z) const { + const TSP::Header& header = _tsp->header(); + return x + (header.xNumBricks * y) + (header.xNumBricks * header.yNumBricks * z); } -void ShenBrickSelector::selectCover(BrickCover coveredBricks, unsigned int brickIndex, std::vector& bricks) { +void ShenBrickSelector::selectCover(BrickCover coveredBricks, unsigned int brickIndex, + std::vector& bricks) const +{ for (int z = coveredBricks.lowZ; z < coveredBricks.highZ; z++) { for (int y = coveredBricks.lowY; y < coveredBricks.highY; y++) { for (int x = coveredBricks.lowX; x < coveredBricks.highX; x++) { diff --git a/modules/multiresvolume/rendering/shenbrickselector.h b/modules/multiresvolume/rendering/shenbrickselector.h index 14c4c4817a..ee47ca545f 100644 --- a/modules/multiresvolume/rendering/shenbrickselector.h +++ b/modules/multiresvolume/rendering/shenbrickselector.h @@ -26,17 +26,18 @@ #define __OPENSPACE_MODULE_MULTIRESVOLUME___SHENBRICKSELECTOR___H__ #include -#include -#include +#include #include namespace openspace { +class TSP; + class ShenBrickSelector : public BrickSelector { public: ShenBrickSelector(TSP* tsp, float spatialTolerance, float temporalTolerance); - ~ShenBrickSelector(); + ~ShenBrickSelector() = default; void setSpatialTolerance(float spatialTolerance); void setTemporalTolerance(float temporalTolerance); void selectBricks(int timestep, std::vector& bricks) override; @@ -46,31 +47,21 @@ private: float _spatialTolerance; float _temporalTolerance; - void traverseOT(int timestep, - unsigned int brickIndex, - BrickCover coveredBricks, - std::vector& bricks); + void traverseOT(int timestep, unsigned int brickIndex, BrickCover coveredBricks, + std::vector& bricks); - void traverseBST(int timestep, - unsigned int brickIndex, - unsigned int bstRootBrickIndex, - int timeSpanStart, - int timeSpanEnd, - BrickCover coveredBricks, - std::vector& bricks); + void traverseBST(int timestep, unsigned int brickIndex, + unsigned int bstRootBrickIndex, int timeSpanStart, int timeSpanEnd, + BrickCover coveredBricks, std::vector& bricks); - void selectBricks(int timestep, - unsigned int brickIndex, - unsigned int bstRootBrickIndex, - int timeSpanStart, - int timeSpanEnd, - BrickCover coveredBricks, - std::vector& bricks); + void selectBricks(int timestep, unsigned int brickIndex, + unsigned int bstRootBrickIndex, int timeSpanStart, int timeSpanEnd, + BrickCover coveredBricks, std::vector& bricks); - int linearCoords(int x, int y, int z); + int linearCoords(int x, int y, int z) const; void selectCover(BrickCover coveredBricks, unsigned int brickIndex, - std::vector& bricks); + std::vector& bricks) const; }; } // namespace openspace diff --git a/modules/multiresvolume/rendering/simpletfbrickselector.cpp b/modules/multiresvolume/rendering/simpletfbrickselector.cpp index e1a64d0810..807f220508 100644 --- a/modules/multiresvolume/rendering/simpletfbrickselector.cpp +++ b/modules/multiresvolume/rendering/simpletfbrickselector.cpp @@ -22,17 +22,22 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include #include + +#include #include -#include #include -#include -#include #include namespace { constexpr const char* _loggerCat = "SimpleTfBrickSelector"; + + bool compareSplitPoints(const openspace::BrickSelection& a, + const openspace::BrickSelection& b) + { + return a.splitPoints < b.splitPoints; + } + } // namespace namespace openspace { @@ -44,13 +49,8 @@ SimpleTfBrickSelector::SimpleTfBrickSelector(TSP* tsp, HistogramManager* hm, , _histogramManager(hm) , _transferFunction(tf) , _memoryBudget(memoryBudget) - , _streamingBudget(streamingBudget) {} - -SimpleTfBrickSelector::~SimpleTfBrickSelector() {} - -bool SimpleTfBrickSelector::initialize() { - return true; -} + , _streamingBudget(streamingBudget) +{} void SimpleTfBrickSelector::setMemoryBudget(int memoryBudget) { _memoryBudget = memoryBudget; @@ -61,14 +61,19 @@ void SimpleTfBrickSelector::setStreamingBudget(int streamingBudget) { } void SimpleTfBrickSelector::selectBricks(int timestep, std::vector& bricks) { - int numTimeSteps = _tsp->header().numTimesteps_; - int numBricksPerDim = _tsp->header().xNumBricks_; + const int numTimeSteps = _tsp->header().numTimesteps; + const int numBricksPerDim = _tsp->header().xNumBricks; - unsigned int rootNode = 0; + const unsigned int rootNode = 0; BrickSelection::SplitType splitType; - float rootSplitPoints = splitPoints(rootNode, splitType); + const float rootSplitPoints = splitPoints(rootNode, splitType); - BrickSelection brickSelection = BrickSelection(numBricksPerDim, numTimeSteps, splitType, rootSplitPoints); + BrickSelection brickSelection = BrickSelection( + numBricksPerDim, + numTimeSteps, + splitType, + rootSplitPoints + ); std::vector priorityQueue; std::vector leafSelections; @@ -81,26 +86,26 @@ void SimpleTfBrickSelector::selectBricks(int timestep, std::vector& bricks) leafSelections.push_back(brickSelection); } - int memoryBudget = _memoryBudget; - int totalStreamingBudget = _streamingBudget * numTimeSteps; + const int totalStreamingBudget = _streamingBudget * numTimeSteps; int nBricksInMemory = 1; int nStreamedBricks = 1; - while (nBricksInMemory <= memoryBudget - 7 && priorityQueue.size() > 0) { - std::pop_heap(priorityQueue.begin(), priorityQueue.end(), BrickSelection::compareSplitPoints); + while (nBricksInMemory <= _memoryBudget - 7 && priorityQueue.size() > 0) { + std::pop_heap(priorityQueue.begin(), priorityQueue.end(), compareSplitPoints); BrickSelection bs = priorityQueue.back(); - // TODO: handle edge case when we can only afford temporal splits or no split (only 1 spot left) + // TODO: handle edge case when we can only afford temporal splits or no split + // (only 1 spot left) unsigned int brickIndex = bs.brickIndex; priorityQueue.pop_back(); if (bs.splitType == BrickSelection::SplitType::Temporal) { - unsigned int childBrickIndex; bool pickRightTimeChild = bs.timestepInRightChild(timestep); - // On average on the whole time period, splitting this spatial brick in two time steps - // would generate twice as much streaming. Current number of streams of this spatial brick - // is 2^nTemporalSplits over the whole time period. + // On average on the whole time period, splitting this spatial brick in two + // time steps would generate twice as much streaming. Current number of + // streams of this spatial brick is 2^nTemporalSplits over the whole time + // period. int newStreams = static_cast(std::pow(2, bs.nTemporalSplits)); // Refining this one more step would require the double amount of streams @@ -111,29 +116,37 @@ void SimpleTfBrickSelector::selectBricks(int timestep, std::vector& bricks) } nStreamedBricks += newStreams; - if (pickRightTimeChild) { - childBrickIndex = _tsp->getBstRight(brickIndex); - } else { - childBrickIndex = _tsp->getBstLeft(brickIndex); - } + unsigned int childBrickIndex = pickRightTimeChild ? + _tsp->bstRight(brickIndex) : + _tsp->bstLeft(brickIndex); BrickSelection::SplitType childSplitType; float childSplitPoints = splitPoints(childBrickIndex, childSplitType); - BrickSelection childSelection = bs.splitTemporally(pickRightTimeChild, childBrickIndex, childSplitType, childSplitPoints); + BrickSelection childSelection = bs.splitTemporally( + pickRightTimeChild, + childBrickIndex, + childSplitType, + childSplitPoints + ); if (childSplitType != BrickSelection::SplitType::None) { priorityQueue.push_back(childSelection); - std::push_heap(priorityQueue.begin(), priorityQueue.end(), BrickSelection::compareSplitPoints); + std::push_heap( + priorityQueue.begin(), + priorityQueue.end(), + compareSplitPoints + ); } else { leafSelections.push_back(childSelection); } } else if (bs.splitType == BrickSelection::SplitType::Spatial) { nBricksInMemory += 7; // Remove one and add eight. - unsigned int firstChild = _tsp->getFirstOctreeChild(brickIndex); + unsigned int firstChild = _tsp->firstOctreeChild(brickIndex); - // On average on the whole time period, splitting this spatial brick into eight spatial bricks - // would generate eight times as much streaming. Current number of streams of this spatial brick - // is 2^nTemporalStreams over the whole time period. + // On average on the whole time period, splitting this spatial brick into + // eight spatial bricks would generate eight times as much streaming. Current + // number of streams of this spatial brick is 2^nTemporalStreams over the + // whole time period. int newStreams = 7 * static_cast(std::pow(2, bs.nTemporalSplits)); if (nStreamedBricks + newStreams > totalStreamingBudget) { // Reached dead end (streaming budget would be exceeded) @@ -156,11 +169,22 @@ void SimpleTfBrickSelector::selectBricks(int timestep, std::vector& bricks) BrickSelection::SplitType childSplitType; float childSplitPoints = splitPoints(childBrickIndex, childSplitType); - BrickSelection childSelection = bs.splitSpatially(i % 2, (i/2) % 2, i/4, childBrickIndex, childSplitType, childSplitPoints); + BrickSelection childSelection = bs.splitSpatially( + i % 2, + (i / 2) % 2, // abock: this is always 0? + i / 4, + childBrickIndex, + childSplitType, + childSplitPoints + ); if (childSplitType != BrickSelection::SplitType::None) { priorityQueue.push_back(childSelection); - std::push_heap(priorityQueue.begin(), priorityQueue.end(), BrickSelection::compareSplitPoints); + std::push_heap( + priorityQueue.begin(), + priorityQueue.end(), + compareSplitPoints + ); } else { leafSelections.push_back(childSelection); } @@ -178,44 +202,65 @@ void SimpleTfBrickSelector::selectBricks(int timestep, std::vector& bricks) priorityQueue.pop_back(); if (bs.splitPoints > -1) { temporalSplitQueue.push_back(bs); - std::push_heap(temporalSplitQueue.begin(), temporalSplitQueue.end(), BrickSelection::compareSplitPoints); + std::push_heap( + temporalSplitQueue.begin(), + temporalSplitQueue.end(), + compareSplitPoints + ); } else { deadEnds.push_back(bs); } } // Keep splitting until it's not possible anymore - while (nStreamedBricks < totalStreamingBudget - 1 && temporalSplitQueue.size() > 0) { - std::pop_heap(temporalSplitQueue.begin(), temporalSplitQueue.end(), BrickSelection::compareSplitPoints); + while (nStreamedBricks < totalStreamingBudget - 1 && + temporalSplitQueue.size() > 0) + { + std::pop_heap( + temporalSplitQueue.begin(), + temporalSplitQueue.end(), + compareSplitPoints + ); BrickSelection bs = temporalSplitQueue.back(); temporalSplitQueue.pop_back(); unsigned int brickIndex = bs.brickIndex; int newStreams = static_cast(std::pow(2, bs.nTemporalSplits)); if (nStreamedBricks + newStreams > totalStreamingBudget) { - // The current best choice would make us exceed the streaming budget, try next instead. + // The current best choice would make us exceed the streaming budget, try + // next instead. deadEnds.push_back(bs); continue; } nStreamedBricks += newStreams; - unsigned int childBrickIndex; bool pickRightTimeChild = bs.timestepInRightChild(timestep); - if (pickRightTimeChild) { - childBrickIndex = _tsp->getBstRight(brickIndex); - } else { - childBrickIndex = _tsp->getBstLeft(brickIndex); - } + unsigned int childBrickIndex = pickRightTimeChild ? + _tsp->bstRight(brickIndex) : + _tsp->bstLeft(brickIndex); float childSplitPoints = temporalSplitPoints(childBrickIndex); if (childSplitPoints > -1) { - BrickSelection childSelection = bs.splitTemporally(pickRightTimeChild, childBrickIndex, BrickSelection::SplitType::Temporal, childSplitPoints); + BrickSelection childSelection = bs.splitTemporally( + pickRightTimeChild, + childBrickIndex, + BrickSelection::SplitType::Temporal, + childSplitPoints + ); temporalSplitQueue.push_back(childSelection); - std::push_heap(temporalSplitQueue.begin(), temporalSplitQueue.end(), BrickSelection::compareSplitPoints); + std::push_heap( + temporalSplitQueue.begin(), + temporalSplitQueue.end(), + compareSplitPoints + ); } else { - BrickSelection childSelection = bs.splitTemporally(pickRightTimeChild, childBrickIndex, BrickSelection::SplitType::None, -1); + BrickSelection childSelection = bs.splitTemporally( + pickRightTimeChild, + childBrickIndex, + BrickSelection::SplitType::None, -1 + ); deadEnds.push_back(childSelection); } } @@ -223,7 +268,7 @@ void SimpleTfBrickSelector::selectBricks(int timestep, std::vector& bricks) // Write selected inner nodes to brickSelection vector for (const BrickSelection& bs : priorityQueue) { writeSelection(bs, bricks); - } + } } // Write selected inner nodes to brickSelection vector @@ -237,26 +282,25 @@ void SimpleTfBrickSelector::selectBricks(int timestep, std::vector& bricks) for (const BrickSelection& bs : leafSelections) { writeSelection(bs, bricks); } - - //std::cout << "Bricks in memory: " << nBricksInMemory << "/" << _memoryBudget << "___\t\t" - // << "Streamed bricks: " << nStreamedBricks << "/" << totalStreamingBudget << std::flush << "___\r"; } -float SimpleTfBrickSelector::temporalSplitPoints(unsigned int brickIndex) { - if (_tsp->isBstLeaf(brickIndex)) { - return -1; - } - return _brickImportances[brickIndex] * 0.5f; -} - -float SimpleTfBrickSelector::spatialSplitPoints(unsigned int brickIndex) { +float SimpleTfBrickSelector::spatialSplitPoints(unsigned int brickIndex) const { if (_tsp->isOctreeLeaf(brickIndex)) { - return -1; + return -1.f; } return _brickImportances[brickIndex] * 0.125f; } -float SimpleTfBrickSelector::splitPoints(unsigned int brickIndex, BrickSelection::SplitType& splitType) { +float SimpleTfBrickSelector::temporalSplitPoints(unsigned int brickIndex) const { + if (_tsp->isBstLeaf(brickIndex)) { + return -1.f; + } + return _brickImportances[brickIndex] * 0.5f; +} + +float SimpleTfBrickSelector::splitPoints(unsigned int brickIndex, + BrickSelection::SplitType& splitType) +{ float temporalPoints = temporalSplitPoints(brickIndex); float spatialPoints = spatialSplitPoints(brickIndex); float splitPoints; @@ -275,12 +319,12 @@ float SimpleTfBrickSelector::splitPoints(unsigned int brickIndex, BrickSelection return splitPoints; } - bool SimpleTfBrickSelector::calculateBrickImportances() { - TransferFunction *tf = _transferFunction; - if (!tf) return false; + if (!_transferFunction) { + return false; + } - size_t tfWidth = tf->width(); + size_t tfWidth = _transferFunction->width(); // By changing tfWidth to the correct type size_t, this check is no longer valid since // size_t is unsigned ---abock @@ -301,18 +345,18 @@ bool SimpleTfBrickSelector::calculateBrickImportances() { _brickImportances = std::vector(nHistograms); for (unsigned int brickIndex = 0; brickIndex < nHistograms; brickIndex++) { - const Histogram* histogram = _histogramManager->getHistogram(brickIndex); + const Histogram* histogram = _histogramManager->histogram(brickIndex); if (!histogram->isValid()) { return false; } float dotProduct = 0; - for (size_t i = 0; i < tf->width(); i++) { + for (size_t i = 0; i < _transferFunction->width(); i++) { float x = static_cast(i) / static_cast(tfWidth); float sample = histogram->interpolate(x); ghoul_assert(sample >= 0, "@MISSING"); - dotProduct += sample * tf->sample(i).w; + dotProduct += sample * _transferFunction->sample(i).w; } _brickImportances[brickIndex] = dotProduct; } @@ -322,12 +366,14 @@ bool SimpleTfBrickSelector::calculateBrickImportances() { return true; } -int SimpleTfBrickSelector::linearCoords(int x, int y, int z) { - const TSP::Header &header = _tsp->header(); - return x + (header.xNumBricks_ * y) + (header.xNumBricks_ * header.yNumBricks_ * z); +int SimpleTfBrickSelector::linearCoords(int x, int y, int z) const { + const TSP::Header& header = _tsp->header(); + return x + (header.xNumBricks * y) + (header.xNumBricks * header.yNumBricks * z); } -void SimpleTfBrickSelector::writeSelection(BrickSelection brickSelection, std::vector& bricks) { +void SimpleTfBrickSelector::writeSelection(BrickSelection brickSelection, + std::vector& bricks) +{ BrickCover coveredBricks = brickSelection.cover; for (int z = coveredBricks.lowZ; z < coveredBricks.highZ; z++) { for (int y = coveredBricks.lowY; y < coveredBricks.highY; y++) { @@ -338,5 +384,4 @@ void SimpleTfBrickSelector::writeSelection(BrickSelection brickSelection, std::v } } - } // namespace openspace diff --git a/modules/multiresvolume/rendering/simpletfbrickselector.h b/modules/multiresvolume/rendering/simpletfbrickselector.h index 52d9af79c4..209122a9e7 100644 --- a/modules/multiresvolume/rendering/simpletfbrickselector.h +++ b/modules/multiresvolume/rendering/simpletfbrickselector.h @@ -25,10 +25,9 @@ #ifndef __OPENSPACE_MODULE_MULTIRESVOLUME___SIMPLETFBRICKSELECTOR___H__ #define __OPENSPACE_MODULE_MULTIRESVOLUME___SIMPLETFBRICKSELECTOR___H__ -#include #include -#include +#include #include namespace openspace { @@ -41,9 +40,7 @@ class SimpleTfBrickSelector : public BrickSelector { public: SimpleTfBrickSelector(TSP* tsp, HistogramManager* hm, TransferFunction* tf, int memoryBudget, int streamingBudget); - ~SimpleTfBrickSelector(); - - bool initialize() override; + ~SimpleTfBrickSelector() = default; void selectBricks(int timestep, std::vector& bricks) override; void setMemoryBudget(int memoryBudget); @@ -51,16 +48,17 @@ public: bool calculateBrickImportances(); private: + float spatialSplitPoints(unsigned int brickIndex) const; + float temporalSplitPoints(unsigned int brickIndex) const; + float splitPoints(unsigned int brickIndex, BrickSelection::SplitType& splitType); + + int linearCoords(int x, int y, int z) const; + void writeSelection(BrickSelection coveredBricks, std::vector& bricks); + TSP* _tsp; HistogramManager* _histogramManager; TransferFunction* _transferFunction; std::vector _brickImportances; - float spatialSplitPoints(unsigned int brickIndex); - float temporalSplitPoints(unsigned int brickIndex); - float splitPoints(unsigned int brickIndex, BrickSelection::SplitType& splitType); - - int linearCoords(int x, int y, int z); - void writeSelection(BrickSelection coveredBricks, std::vector& bricks); int _memoryBudget; int _streamingBudget; diff --git a/modules/multiresvolume/rendering/tfbrickselector.cpp b/modules/multiresvolume/rendering/tfbrickselector.cpp index c44dc22e9c..060ddfc67e 100644 --- a/modules/multiresvolume/rendering/tfbrickselector.cpp +++ b/modules/multiresvolume/rendering/tfbrickselector.cpp @@ -22,14 +22,21 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include #include + #include -#include +#include #include +#include #include -#include -#include + +namespace { + bool compareSplitPoints(const openspace::BrickSelection& a, + const openspace::BrickSelection& b) + { + return a.splitPoints < b.splitPoints; + } +} // namespace namespace openspace { @@ -43,8 +50,6 @@ TfBrickSelector::TfBrickSelector(TSP* tsp, ErrorHistogramManager* hm, , _streamingBudget(streamingBudget) {} -TfBrickSelector::~TfBrickSelector() {} - bool TfBrickSelector::initialize() { return calculateBrickErrors(); } @@ -58,15 +63,19 @@ void TfBrickSelector::setStreamingBudget(int streamingBudget) { } void TfBrickSelector::selectBricks(int timestep, std::vector& bricks) { - int numTimeSteps = _tsp->header().numTimesteps_; - int numBricksPerDim = _tsp->header().xNumBricks_; + int numTimeSteps = _tsp->header().numTimesteps; + int numBricksPerDim = _tsp->header().xNumBricks; unsigned int rootNode = 0; BrickSelection::SplitType splitType; float rootSplitPoints = splitPoints(rootNode, splitType); - - BrickSelection brickSelection = BrickSelection(numBricksPerDim, numTimeSteps, splitType, rootSplitPoints); + BrickSelection brickSelection = BrickSelection( + numBricksPerDim, + numTimeSteps, + splitType, + rootSplitPoints + ); std::vector priorityQueue; std::vector leafSelections; @@ -79,7 +88,6 @@ void TfBrickSelector::selectBricks(int timestep, std::vector& bricks) { leafSelections.push_back(brickSelection); } - int memoryBudget = _memoryBudget; int totalStreamingBudget = _streamingBudget * numTimeSteps; int nBricksInMemory = 1; int nStreamedBricks = 1; @@ -87,30 +95,29 @@ void TfBrickSelector::selectBricks(int timestep, std::vector& bricks) { // First loop: While neither the memory nor the streaming budget is reached, // try to optimize for visual quality vs memory. - while (nBricksInMemory <= memoryBudget - 7 && priorityQueue.size() > 0) { - - std::pop_heap(priorityQueue.begin(), priorityQueue.end(), BrickSelection::compareSplitPoints); + while (nBricksInMemory <= _memoryBudget - 7 && priorityQueue.size() > 0) { + std::pop_heap(priorityQueue.begin(), priorityQueue.end(), compareSplitPoints); BrickSelection bs = priorityQueue.back(); unsigned int brickIndex = bs.brickIndex; priorityQueue.pop_back(); - // TODO: handle edge case when we can only afford temporal splits or no split (only 1 spot left) + // TODO: handle edge case when we can only afford temporal splits or no split + // (only 1 spot left) if (bs.splitType == BrickSelection::SplitType::Temporal) { unsigned int childBrickIndex; bool pickRightTimeChild = bs.timestepInRightChild(timestep); - // assert(!pickRightTimeChild && "picked right child"); - // On average on the whole time period, splitting this spatial brick in two time steps - // would generate twice as much streaming. Current number of streams of this spatial brick - // is 2^nTemporalSplits over the whole time period. + // On average on the whole time period, splitting this spatial brick in two + // time steps would generate twice as much streaming. Current number of + // streams of this spatial brick is 2^nTemporalSplits over the whole time + // period. int newStreams = static_cast(std::pow(2, bs.nTemporalSplits)); //std::cout << "preparing for " << newStreams << " new streams" << std::endl; // Refining this one more step would require the double amount of streams if (nStreamedBricks + newStreams > totalStreamingBudget) { - //std::cout << "Reached streaming budget when splitting temporally! Breaking" << std::endl; // Reached dead end (streaming budget would be exceeded) deadEnds.push_back(bs); break; @@ -118,33 +125,42 @@ void TfBrickSelector::selectBricks(int timestep, std::vector& bricks) { nStreamedBricks += newStreams; if (pickRightTimeChild) { - childBrickIndex = _tsp->getBstRight(brickIndex); + childBrickIndex = _tsp->bstRight(brickIndex); } else { - childBrickIndex = _tsp->getBstLeft(brickIndex); + childBrickIndex = _tsp->bstLeft(brickIndex); } BrickSelection::SplitType childSplitType; float childSplitPoints = splitPoints(childBrickIndex, childSplitType); - BrickSelection childSelection = bs.splitTemporally(pickRightTimeChild, childBrickIndex, childSplitType, childSplitPoints); + BrickSelection childSelection = bs.splitTemporally( + pickRightTimeChild, + childBrickIndex, + childSplitType, + childSplitPoints + ); if (childSplitType != BrickSelection::SplitType::None) { priorityQueue.push_back(childSelection); - std::push_heap(priorityQueue.begin(), priorityQueue.end(), BrickSelection::compareSplitPoints); + std::push_heap( + priorityQueue.begin(), + priorityQueue.end(), + compareSplitPoints + ); } else { leafSelections.push_back(childSelection); } } else if (bs.splitType == BrickSelection::SplitType::Spatial) { nBricksInMemory += 7; // Remove one and add eight. - unsigned int firstChild = _tsp->getFirstOctreeChild(brickIndex); + unsigned int firstChild = _tsp->firstOctreeChild(brickIndex); - // On average on the whole time period, splitting this spatial brick into eight spatial bricks - // would generate eight times as much streaming. Current number of streams of this spatial brick - // is 2^nTemporalStreams over the whole time period. + // On average on the whole time period, splitting this spatial brick into + // eight spatial bricks would generate eight times as much streaming. Current + // number of streams of this spatial brick is 2^nTemporalStreams over the + // whole time period. int newStreams = 7 * static_cast(std::pow(2, bs.nTemporalSplits)); if (nStreamedBricks + newStreams > totalStreamingBudget) { // Reached dead end (streaming budget would be exceeded) // However, temporal split might be possible - //std::cout << "Reached streaming budget when splitting spatially! Breaking" << std::endl; if (bs.splitType != BrickSelection::SplitType::Temporal) { bs.splitType = BrickSelection::SplitType::Temporal; bs.splitPoints = temporalSplitPoints(bs.brickIndex); @@ -164,11 +180,22 @@ void TfBrickSelector::selectBricks(int timestep, std::vector& bricks) { BrickSelection::SplitType childSplitType; float childSplitPoints = splitPoints(childBrickIndex, childSplitType); //std::cout << "Splitting spatially." << std::endl; - BrickSelection childSelection = bs.splitSpatially(i % 2, (i/2) % 2, i/4, childBrickIndex, childSplitType, childSplitPoints); + BrickSelection childSelection = bs.splitSpatially( + i % 2, + (i / 2) % 2, // abock: isn't this always 0? + i / 4, + childBrickIndex, + childSplitType, + childSplitPoints + ); if (childSplitType != BrickSelection::SplitType::None) { priorityQueue.push_back(childSelection); - std::push_heap(priorityQueue.begin(), priorityQueue.end(), BrickSelection::compareSplitPoints); + std::push_heap( + priorityQueue.begin(), + priorityQueue.end(), + compareSplitPoints + ); } else { leafSelections.push_back(childSelection); } @@ -176,15 +203,13 @@ void TfBrickSelector::selectBricks(int timestep, std::vector& bricks) { } } - if (nBricksInMemory <= memoryBudget - 7) { - //std::cout << "memory budget not reached. " << nBricksInMemory << " out of " << memoryBudget << std::endl; + if (nBricksInMemory <= _memoryBudget - 7) { + // std::cout << "memory budget not reached. " << nBricksInMemory << " out of " << + // memoryBudget << std::endl; } // Is it possible that we may stream more bricks? if (nStreamedBricks < totalStreamingBudget - 1) { - //std::cout << "streaming budget not reached. " << nStreamedBricks << " out of " << totalStreamingBudget << std::endl; - //std::cout << "there are " << priorityQueue.size() << " elements left in priority queue." << std::endl; - while (priorityQueue.size() > 0) { BrickSelection bs = priorityQueue.back(); if (bs.splitType != BrickSelection::SplitType::Temporal) { @@ -194,45 +219,67 @@ void TfBrickSelector::selectBricks(int timestep, std::vector& bricks) { priorityQueue.pop_back(); if (bs.splitPoints > -1) { temporalSplitQueue.push_back(bs); - std::push_heap(temporalSplitQueue.begin(), temporalSplitQueue.end(), BrickSelection::compareSplitPoints); + std::push_heap( + temporalSplitQueue.begin(), + temporalSplitQueue.end(), + compareSplitPoints + ); } else { deadEnds.push_back(bs); } } // Keep splitting until it's not possible anymore - while (nStreamedBricks < totalStreamingBudget - 1 && temporalSplitQueue.size() > 0) { - std::pop_heap(temporalSplitQueue.begin(), temporalSplitQueue.end(), BrickSelection::compareSplitPoints); + while (nStreamedBricks < totalStreamingBudget - 1 && + temporalSplitQueue.size() > 0) + { + std::pop_heap( + temporalSplitQueue.begin(), + temporalSplitQueue.end(), + compareSplitPoints + ); BrickSelection bs = temporalSplitQueue.back(); temporalSplitQueue.pop_back(); unsigned int brickIndex = bs.brickIndex; int newStreams = static_cast(std::pow(2, bs.nTemporalSplits)); if (nStreamedBricks + newStreams > totalStreamingBudget) { - // The current best choice would make us exceed the streaming budget, try next instead. + // The current best choice would make us exceed the streaming budget, + // try next instead. deadEnds.push_back(bs); - //std::cout << "Dead end trying to split " << brickIndex << ". Streamed would be " << (nStreamedBricks + newStreams) << std::endl; continue; } nStreamedBricks += newStreams; - unsigned int childBrickIndex; + ; bool pickRightTimeChild = bs.timestepInRightChild(timestep); - if (pickRightTimeChild) { - childBrickIndex = _tsp->getBstRight(brickIndex); - } else { - childBrickIndex = _tsp->getBstLeft(brickIndex); - } + unsigned int childBrickIndex = pickRightTimeChild ? + _tsp->bstRight(brickIndex) : + _tsp->bstLeft(brickIndex); float childSplitPoints = temporalSplitPoints(childBrickIndex); if (childSplitPoints > -1) { - BrickSelection childSelection = bs.splitTemporally(pickRightTimeChild, childBrickIndex, BrickSelection::SplitType::Temporal, childSplitPoints); + BrickSelection childSelection = bs.splitTemporally( + pickRightTimeChild, + childBrickIndex, + BrickSelection::SplitType::Temporal, + childSplitPoints + ); temporalSplitQueue.push_back(childSelection); - std::push_heap(temporalSplitQueue.begin(), temporalSplitQueue.end(), BrickSelection::compareSplitPoints); + std::push_heap( + temporalSplitQueue.begin(), + temporalSplitQueue.end(), + compareSplitPoints + ); } else { - BrickSelection childSelection = bs.splitTemporally(pickRightTimeChild, childBrickIndex, BrickSelection::SplitType::None, -1); + BrickSelection childSelection = bs.splitTemporally( + pickRightTimeChild, + childBrickIndex, + BrickSelection::SplitType::None, + -1 + ); deadEnds.push_back(childSelection); } } @@ -258,64 +305,53 @@ void TfBrickSelector::selectBricks(int timestep, std::vector& bricks) { for (const BrickSelection& bs : leafSelections) { writeSelection(bs, bricks); } - - //std::cout << "Bricks in memory: " << nBricksInMemory << "/" << _memoryBudget << "___\t\t" - // << "Streamed bricks: " << nStreamedBricks << "/" << totalStreamingBudget << std::flush << "___\r"; } float TfBrickSelector::temporalSplitPoints(unsigned int brickIndex) { if (_tsp->isBstLeaf(brickIndex)) { - return -1; + return -1.f; } - unsigned int leftChild = _tsp->getBstLeft(brickIndex); - unsigned int rightChild = _tsp->getBstRight(brickIndex); + const unsigned int leftChild = _tsp->bstLeft(brickIndex); + const unsigned int rightChild = _tsp->bstRight(brickIndex); - float currentError = _brickErrors[brickIndex]; - float splitError = _brickErrors[leftChild] + _brickErrors[rightChild]; + const float currentError = _brickErrors[brickIndex]; + const float splitError = _brickErrors[leftChild] + _brickErrors[rightChild]; - /*if (currentError + 0.001 < splitError) { - std::cout << "Warning! (TEMPORAL SPLIT) Current error " << currentError << " is smaller than split error " << splitError << "." << std::endl; - }*/ float diff = currentError - splitError; - if (diff < 0.0) { - //std::cout << "local temporal split minimum for brick " << brickIndex << std::endl; - diff = -diff; + if (diff < 0.f) { + diff = -diff; } return diff * 0.5f; } float TfBrickSelector::spatialSplitPoints(unsigned int brickIndex) { if (_tsp->isOctreeLeaf(brickIndex)) { - return -1; + return -1.f; } - float currentError = _brickErrors[brickIndex]; float splitError = 0; - unsigned int firstChild = _tsp->getFirstOctreeChild(brickIndex); + unsigned int firstChild = _tsp->firstOctreeChild(brickIndex); for (unsigned int i = 0; i < 8; i++) { unsigned int child = firstChild + i; splitError += _brickErrors[child]; } - /*if (currentError + 0.001 < splitError) { - std::cout << "Warning! (SPATIAL SPLIT) Current error " << currentError << " is smaller than split error " << splitError << "." << std::endl; - }*/ - float diff = currentError - splitError; if (diff < 0.0) { - //std::cout << "local spatial split minimum for brick " << brickIndex << std::endl; - diff = -diff; + diff = -diff; } return diff * 0.125f; } -float TfBrickSelector::splitPoints(unsigned int brickIndex, BrickSelection::SplitType& splitType) { - float temporalPoints = temporalSplitPoints(brickIndex); - float spatialPoints = spatialSplitPoints(brickIndex); +float TfBrickSelector::splitPoints(unsigned int brickIndex, + BrickSelection::SplitType& splitType) +{ + const float temporalPoints = temporalSplitPoints(brickIndex); + const float spatialPoints = spatialSplitPoints(brickIndex); float splitPoints; if (spatialPoints > 0 && spatialPoints > temporalPoints) { @@ -334,10 +370,14 @@ float TfBrickSelector::splitPoints(unsigned int brickIndex, BrickSelection::Spli bool TfBrickSelector::calculateBrickErrors() { TransferFunction *tf = _transferFunction; - if (!tf) return false; + if (!tf) { + return false; + } size_t tfWidth = tf->width(); - if (tfWidth <= 0) return false; + if (tfWidth <= 0) { + return false; + } std::vector gradients(tfWidth - 1); for (size_t offset = 0; offset < tfWidth - 1; offset++) { @@ -350,8 +390,6 @@ bool TfBrickSelector::calculateBrickErrors() { gradients[offset] = colorDifference*alpha; } - - unsigned int nHistograms = _tsp->numTotalNodes(); _brickErrors = std::vector(nHistograms); @@ -359,7 +397,7 @@ bool TfBrickSelector::calculateBrickErrors() { if (_tsp->isBstLeaf(brickIndex) && _tsp->isOctreeLeaf(brickIndex)) { _brickErrors[brickIndex] = 0; } else { - const Histogram* histogram = _histogramManager->getHistogram(brickIndex); + const Histogram* histogram = _histogramManager->histogram(brickIndex); float error = 0; for (size_t i = 0; i < gradients.size(); i++) { float x = (i + 0.5f) / tfWidth; @@ -375,12 +413,14 @@ bool TfBrickSelector::calculateBrickErrors() { return true; } -int TfBrickSelector::linearCoords(int x, int y, int z) { +int TfBrickSelector::linearCoords(int x, int y, int z) const { const TSP::Header &header = _tsp->header(); - return x + (header.xNumBricks_ * y) + (header.xNumBricks_ * header.yNumBricks_ * z); + return x + (header.xNumBricks * y) + (header.xNumBricks * header.yNumBricks * z); } -void TfBrickSelector::writeSelection(BrickSelection brickSelection, std::vector& bricks) { +void TfBrickSelector::writeSelection(BrickSelection brickSelection, + std::vector& bricks) const +{ BrickCover coveredBricks = brickSelection.cover; for (int z = coveredBricks.lowZ; z < coveredBricks.highZ; z++) { for (int y = coveredBricks.lowY; y < coveredBricks.highY; y++) { @@ -391,5 +431,4 @@ void TfBrickSelector::writeSelection(BrickSelection brickSelection, std::vector< } } - } // namespace openspace diff --git a/modules/multiresvolume/rendering/tfbrickselector.h b/modules/multiresvolume/rendering/tfbrickselector.h index 2a810c7c6b..9a1299bad6 100644 --- a/modules/multiresvolume/rendering/tfbrickselector.h +++ b/modules/multiresvolume/rendering/tfbrickselector.h @@ -25,10 +25,9 @@ #ifndef __OPENSPACE_MODULE_MULTIRESVOLUME___TFBRICKSELECTOR___H__ #define __OPENSPACE_MODULE_MULTIRESVOLUME___TFBRICKSELECTOR___H__ -#include #include -#include +#include #include namespace openspace { @@ -41,8 +40,7 @@ class TfBrickSelector : public BrickSelector { public: TfBrickSelector(TSP* tsp, ErrorHistogramManager* hm, TransferFunction* tf, int memoryBudget, int streamingBudget); - - ~TfBrickSelector(); + ~TfBrickSelector() = default; bool initialize() override; @@ -56,12 +54,13 @@ private: ErrorHistogramManager* _histogramManager; TransferFunction* _transferFunction; std::vector _brickErrors; + float spatialSplitPoints(unsigned int brickIndex); float temporalSplitPoints(unsigned int brickIndex); float splitPoints(unsigned int brickIndex, BrickSelection::SplitType& splitType); - int linearCoords(int x, int y, int z); - void writeSelection(BrickSelection coveredBricks, std::vector& bricks); + int linearCoords(int x, int y, int z) const; + void writeSelection(BrickSelection coveredBricks, std::vector& bricks) const; int _memoryBudget; int _streamingBudget; diff --git a/modules/multiresvolume/rendering/tsp.cpp b/modules/multiresvolume/rendering/tsp.cpp index 8a20109230..bee20b7219 100644 --- a/modules/multiresvolume/rendering/tsp.cpp +++ b/modules/multiresvolume/rendering/tsp.cpp @@ -24,15 +24,13 @@ #include +#include +#include #include #include #include #include -#include - -#include -#include -#include +#include #include namespace { @@ -43,26 +41,14 @@ namespace openspace { TSP::TSP(const std::string& filename) : _filename(filename) - , _dataSSBO(0) - , paddedBrickDim_(0) - , numTotalNodes_(0) - , numBSTLevels_(0) - , numBSTNodes_(0) - , numOTLevels_(0) - , numOTNodes_(0) - , minSpatialError_(0.0f) - , maxSpatialError_(0.0f) - , medianSpatialError_(0.0f) - , minTemporalError_(0.0f) - , maxTemporalError_(0.0f) - , medianTemporalError_(0.0f) { _file.open(_filename, std::ios::in | std::ios::binary); } TSP::~TSP() { - if (_file.is_open()) + if (_file.is_open()) { _file.close(); + } } bool TSP::load() { @@ -72,7 +58,6 @@ bool TSP::load() { } if (readCache()) { - //if (false) { LINFO("Using cache"); } else { @@ -109,49 +94,38 @@ bool TSP::readHeader() { _file.seekg(_file.beg); _file.read(reinterpret_cast(&_header), sizeof(Header)); - /* - file.read(reinterpret_cast(&gridType_), sizeof(unsigned int)); - file.read(reinterpret_cast(&numOrigTimesteps_), sizeof(unsigned int)); - file.read(reinterpret_cast(&numTimesteps_), sizeof(unsigned int)); - file.read(reinterpret_cast(&xBrickDim_), sizeof(unsigned int)); - file.read(reinterpret_cast(&yBrickDim_), sizeof(unsigned int)); - file.read(reinterpret_cast(&zBrickDim_), sizeof(unsigned int)); - file.read(reinterpret_cast(&xNumBricks_), sizeof(unsigned int)); - file.read(reinterpret_cast(&yNumBricks_), sizeof(unsigned int)); - file.read(reinterpret_cast(&zNumBricks_), sizeof(unsigned int)); - */ - LDEBUG(fmt::format("Grid type: {}", _header.gridType_)); + LDEBUG(fmt::format("Grid type: {}", _header.gridType)); LDEBUG(fmt::format( "Brick dimensions: {} {} {}", - _header.xBrickDim_, - _header.yBrickDim_, - _header.zBrickDim_ + _header.xBrickDim, _header.yBrickDim, _header.zBrickDim )); LDEBUG(fmt::format( "Num bricks: {} {} {}", - _header.xNumBricks_, - _header.yNumBricks_, - _header.zNumBricks_ + _header.xNumBricks, _header.yNumBricks, _header.zNumBricks )); - paddedBrickDim_ = _header.xBrickDim_ + 2 * paddingWidth_; + _paddedBrickDim = _header.xBrickDim + 2 * _paddingWidth; // TODO support dimensions of different size - numOTLevels_ = static_cast(log(static_cast(_header.xNumBricks_)) / log(2) + 1); - numOTNodes_ = static_cast((pow(8, numOTLevels_) - 1) / 7); - numBSTLevels_ = static_cast(log(static_cast(_header.numTimesteps_)) / log(2) + 1); - numBSTNodes_ = _header.numTimesteps_ * 2 - 1; - numTotalNodes_ = numOTNodes_ * numBSTNodes_; + _numOTLevels = static_cast( + log(static_cast(_header.xNumBricks)) / log(2) + 1 + ); + _numOTNodes = static_cast((pow(8, _numOTLevels) - 1) / 7); + _numBSTLevels = static_cast( + log(static_cast(_header.numTimesteps)) / log(2) + 1 + ); + _numBSTNodes = _header.numTimesteps * 2 - 1; + _numTotalNodes = _numOTNodes * _numBSTNodes; - LDEBUG(fmt::format("Num OT levels: {}", numOTLevels_)); - LDEBUG(fmt::format("Num OT nodes: {}", numOTNodes_)); - LDEBUG(fmt::format("Num BST levels: {}", numBSTLevels_)); - LDEBUG(fmt::format("Num BST nodes: {}", numBSTNodes_)); - LDEBUG(fmt::format("Num total nodes: {}", numTotalNodes_)); + LDEBUG(fmt::format("Num OT levels: {}", _numOTLevels)); + LDEBUG(fmt::format("Num OT nodes: {}", _numOTNodes)); + LDEBUG(fmt::format("Num BST levels: {}", _numBSTLevels)); + LDEBUG(fmt::format("Num BST nodes: {}", _numBSTNodes)); + LDEBUG(fmt::format("Num total nodes: {}", _numTotalNodes)); // Allocate space for TSP structure - data_.resize(numTotalNodes_*NUM_DATA); - LDEBUG(fmt::format("Data size: {}", data_.size())); + _data.resize(_numTotalNodes*NUM_DATA); + LDEBUG(fmt::format("Data size: {}", _data.size())); return true; } @@ -160,10 +134,9 @@ bool TSP::construct() { LDEBUG("Constructing TSP tree"); // Loop over the OTs (one per BST node) - for (unsigned int OT = 0; OT < numBSTNodes_; ++OT) { - + for (unsigned int OT = 0; OT < _numBSTNodes; ++OT) { // Start at the root of each OT - unsigned int OTNode = OT * numOTNodes_; + unsigned int OTNode = OT * _numOTNodes; // Calculate BST level (first level is level 0) unsigned int BSTLevel = static_cast(log(OT + 1) / log(2)); @@ -171,50 +144,53 @@ bool TSP::construct() { // Traverse OT unsigned int OTChild = 1; unsigned int OTLevel = 0; - while (OTLevel < numOTLevels_) { - + while (OTLevel < _numOTLevels) { unsigned int OTNodesInLevel = static_cast(pow(8, OTLevel)); for (unsigned int i = 0; i(OTNode); + _data[OTNode*NUM_DATA + BRICK_INDEX] = static_cast(OTNode); // Error metrics - //int localOTNode = (OTNode - OT*numOTNodes_); - data_[OTNode*NUM_DATA + TEMPORAL_ERR] = static_cast(numBSTLevels_ - 1 - BSTLevel); - data_[OTNode*NUM_DATA + SPATIAL_ERR] = static_cast(numOTLevels_ - 1 - OTLevel); + _data[OTNode*NUM_DATA + TEMPORAL_ERR] = static_cast( + _numBSTLevels - 1 - BSTLevel + ); + _data[OTNode*NUM_DATA + SPATIAL_ERR] = static_cast( + _numOTLevels - 1 - OTLevel + ); if (BSTLevel == 0) { // Calculate OT child index (-1 if node is leaf) - int OTChildIndex = - (OTChild < numOTNodes_) ? static_cast(OT*numOTNodes_ + OTChild) : -1; - data_[OTNode*NUM_DATA + CHILD_INDEX] = OTChildIndex; + int OTChildIndex = (OTChild < _numOTNodes) ? + static_cast(OT*_numOTNodes + OTChild) : + -1; + _data[OTNode*NUM_DATA + CHILD_INDEX] = OTChildIndex; } else { // Calculate BST child index (-1 if node is BST leaf) // First BST node of current level - int firstNode = - static_cast((2 * pow(2, BSTLevel - 1) - 1)*numOTNodes_); + int firstNode = static_cast( + (2 * pow(2, BSTLevel - 1) - 1) * _numOTNodes + ); // First BST node of next level - int firstChild = - static_cast((2 * pow(2, BSTLevel) - 1)*numOTNodes_); + int firstChild = static_cast( + (2 * pow(2, BSTLevel) - 1) * _numOTNodes + ); // Difference between first nodes between levels int levelGap = firstChild - firstNode; // How many nodes away from the first node are we? - int offset = (OTNode - firstNode) / numOTNodes_; + int offset = (OTNode - firstNode) / _numOTNodes; // Use level gap and offset to calculate child index - int BSTChildIndex = - (BSTLevel < numBSTLevels_ - 1) ? - static_cast(OTNode + levelGap + (offset*numOTNodes_)) : -1; + int BSTChildIndex = (BSTLevel < _numBSTLevels - 1) ? + static_cast(OTNode + levelGap + (offset*_numOTNodes)) : + -1; - data_[OTNode*NUM_DATA + CHILD_INDEX] = BSTChildIndex; + _data[OTNode*NUM_DATA + CHILD_INDEX] = BSTChildIndex; } OTNode++; OTChild += 8; - } OTLevel++; @@ -224,14 +200,14 @@ bool TSP::construct() { } bool TSP::initalizeSSO() { - - if (!_dataSSBO) + if (!_dataSSBO) { glGenBuffers(1, &_dataSSBO); + } - const size_t size = sizeof(GLint)*data_.size(); + const size_t size = sizeof(GLint)*_data.size(); glBindBuffer(GL_SHADER_STORAGE_BUFFER, _dataSSBO); - //glBufferData(GL_SHADER_STORAGE_BUFFER, size, data_.data(), GL_DYNAMIC_READ); - glBufferData(GL_SHADER_STORAGE_BUFFER, size, data_.data(), GL_STATIC_DRAW); + //glBufferData(GL_SHADER_STORAGE_BUFFER, size, _data.data(), GL_DYNAMIC_READ); + glBufferData(GL_SHADER_STORAGE_BUFFER, size, _data.data(), GL_STATIC_DRAW); glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); glFinish(); return true; @@ -249,40 +225,40 @@ std::ifstream& TSP::file() { return _file; } -unsigned int TSP::numTotalNodes() const { - return numTotalNodes_; +unsigned int TSP::numTotalNodes() const { + return _numTotalNodes; } -unsigned int TSP::numValuesPerNode() const { - return NUM_DATA; +unsigned int TSP::numValuesPerNode() const { + return NUM_DATA; } -unsigned int TSP::numBSTNodes() const { - return numBSTNodes_; +unsigned int TSP::numBSTNodes() const { + return _numBSTNodes; } unsigned int TSP::numBSTLevels() const { - return numBSTLevels_; + return _numBSTLevels; } -unsigned int TSP::numOTNodes() const { - return numOTNodes_; +unsigned int TSP::numOTNodes() const { + return _numOTNodes; } -unsigned int TSP::numOTLevels() const { - return numOTLevels_; +unsigned int TSP::numOTLevels() const { + return _numOTLevels; } unsigned int TSP::brickDim() const { - return _header.xBrickDim_; + return _header.xBrickDim; } unsigned int TSP::paddedBrickDim() const { - return paddedBrickDim_; + return _paddedBrickDim; } unsigned int TSP::numBricksPerAxis() const { - return _header.xNumBricks_; + return _header.xNumBricks; } GLuint TSP::ssbo() const { @@ -290,68 +266,70 @@ GLuint TSP::ssbo() const { } bool TSP::calculateSpatialError() { - unsigned int numBrickVals = paddedBrickDim_*paddedBrickDim_*paddedBrickDim_; + unsigned int numBrickVals = _paddedBrickDim*_paddedBrickDim*_paddedBrickDim; - if (!_file.is_open()) + if (!_file.is_open()) { return false; + } std::vector buffer(numBrickVals); - std::vector averages(numTotalNodes_); - std::vector stdDevs(numTotalNodes_); + std::vector averages(_numTotalNodes); + std::vector stdDevs(_numTotalNodes); // First pass: Calculate average color for each brick LDEBUG("Calculating spatial error, first pass"); - for (unsigned int brick = 0; brick(brick*numBrickVals*sizeof(float)); + std::streampos offset = dataPosition() + + static_cast(brick*numBrickVals*sizeof(float)); _file.seekg(offset); - _file.read(reinterpret_cast(&buffer[0]), - static_cast(numBrickVals)*sizeof(float)); - - double average = 0.0; - for (auto it = buffer.begin(); it != buffer.end(); ++it) { - average += *it; - } + _file.read( + reinterpret_cast(&buffer[0]), + static_cast(numBrickVals) * sizeof(float) + ); + double average = std::accumulate( + buffer.begin(), + buffer.end(), + 0.0, + [](double a, float b) { return a + static_cast(b); } + ); averages[brick] = static_cast(average / static_cast(numBrickVals)); } // Spatial SNR stats float minError = 1e20f; float maxError = 0.f; - std::vector medianArray(numTotalNodes_); + std::vector medianArray(_numTotalNodes); // Second pass: For each brick, compare the covered leaf voxels with // the brick average LDEBUG("Calculating spatial error, second pass"); - for (unsigned int brick = 0; brick coveredLeafBricks = - CoveredLeafBricks(brick); + std::list leafBricksCovered = coveredLeafBricks(brick); // If the brick is already a leaf, assign a negative error. // Ad hoc "hack" to distinguish leafs from other nodes that happens // to get a zero error due to rounding errors or other reasons. - if (coveredLeafBricks.size() == 1) { + if (leafBricksCovered.size() == 1) { stdDev = -0.1f; } else { // Calculate "standard deviation" corresponding to leaves - for (auto lb = coveredLeafBricks.begin(); - lb != coveredLeafBricks.end(); ++lb) { - + for (auto lb = leafBricksCovered.begin(); lb != leafBricksCovered.end(); ++lb) + { // Read brick - std::streampos offset = dataPosition() + static_cast((*lb)*numBrickVals*sizeof(float)); + std::streampos offset = dataPosition() + + static_cast((*lb)*numBrickVals*sizeof(float)); _file.seekg(offset); _file.read(reinterpret_cast(&buffer[0]), @@ -361,19 +339,10 @@ bool TSP::calculateSpatialError() { for (auto v = buffer.begin(); v != buffer.end(); ++v) { stdDev += pow(*v - brickAvg, 2.f); } - - } - // Finish calculation - if (sizeof(float) != sizeof(int)) { - LERROR("Float and int sizes don't match, can't reintepret"); - return false; - } - - stdDev /= static_cast(coveredLeafBricks.size()*numBrickVals); + stdDev /= static_cast(leafBricksCovered.size()*numBrickVals); stdDev = sqrt(stdDev); - } // if not leaf if (stdDev < minError) { @@ -385,29 +354,21 @@ bool TSP::calculateSpatialError() { stdDevs[brick] = stdDev; medianArray[brick] = stdDev; - } std::sort(medianArray.begin(), medianArray.end()); //float medError = medianArray[medianArray.size()/2]; - /* - LDEBUG("\nMin spatial std dev: " << minError); - LDEBUG("Max spatial std dev: " << maxError); - LDEBUG("Median spatial std dev: " << medError); - LDEBUG(""); - */ - // "Normalize" errors float minNorm = 1e20f; float maxNorm = 0.f; - for (unsigned int i = 0; i 0.f) { stdDevs[i] = pow(stdDevs[i], 0.5f); } - //data_[i*NUM_DATA + SPATIAL_ERR] = *reinterpret_cast(&stdDevs[i]); - data_[i*NUM_DATA + SPATIAL_ERR] = glm::floatBitsToInt(stdDevs[i]); + //_data[i*NUM_DATA + SPATIAL_ERR] = *reinterpret_cast(&stdDevs[i]); + _data[i*NUM_DATA + SPATIAL_ERR] = glm::floatBitsToInt(stdDevs[i]); if (stdDevs[i] < minNorm) { minNorm = stdDevs[i]; } @@ -419,9 +380,9 @@ bool TSP::calculateSpatialError() { std::sort(stdDevs.begin(), stdDevs.end()); float medNorm = stdDevs[stdDevs.size() / 2]; - minSpatialError_ = minNorm; - maxSpatialError_ = maxNorm; - medianSpatialError_ = medNorm; + _minSpatialError = minNorm; + _maxSpatialError = maxNorm; + _medianSpatialError = medNorm; LDEBUG(fmt::format("Min normalized spatial std dev: {}", minNorm)); LDEBUG(fmt::format("Max normalized spatial std dev: {}", maxNorm)); @@ -431,25 +392,23 @@ bool TSP::calculateSpatialError() { } bool TSP::calculateTemporalError() { - - if (!_file.is_open()) + if (!_file.is_open()) { return false; + } LDEBUG("Calculating temporal error"); // Statistics //float minErr = 1e20f; //float maxErr = 0.f; - std::vector meanArray(numTotalNodes_); + std::vector meanArray(_numTotalNodes); // Save errors - std::vector errors(numTotalNodes_); + std::vector errors(_numTotalNodes); // Calculate temporal error for one brick at a time - for (unsigned int brick = 0; brick voxelStdDevs(numBrickVals); // Read the whole brick to fill the averages - std::streampos offset = dataPosition() + static_cast(brick*numBrickVals*sizeof(float)); + std::streampos offset = dataPosition() + + static_cast(brick*numBrickVals*sizeof(float)); _file.seekg(offset); - _file.read(reinterpret_cast(&voxelAverages[0]), - static_cast(numBrickVals)*sizeof(float)); + _file.read( + reinterpret_cast(voxelAverages.data()), + static_cast(numBrickVals)*sizeof(float) + ); // Build a list of the BST leaf bricks (within the same octree level) that // this brick covers - std::list coveredBricks = CoveredBSTLeafBricks(brick); + std::list coveredBricks = coveredBSTLeafBricks(brick); - // If the brick is at the lowest BST level, automatically set the error + // If the brick is at the lowest BST level, automatically set the error // to -0.1 (enables using -1 as a marker for "no error accepted"); // Somewhat ad hoc to get around the fact that the error could be // 0.0 higher up in the tree @@ -478,15 +440,16 @@ bool TSP::calculateTemporalError() { // Calculate standard deviation per voxel, average over brick float avgStdDev = 0.f; for (unsigned int voxel = 0; voxel((*leaf*numBrickVals + voxel)*sizeof(float)); - _file.seekg(offset); + _file.seekg(dataPosition() + + static_cast( + (*leaf * numBrickVals + voxel) * sizeof(float) + ) + ); float sample; _file.read(reinterpret_cast(&sample), sizeof(float)); @@ -502,37 +465,20 @@ bool TSP::calculateTemporalError() { avgStdDev /= static_cast(numBrickVals); meanArray[brick] = avgStdDev; errors[brick] = avgStdDev; - } - - /* - if (avgStdDev < minErr) { - minErr = avgStdDev; - } else if (avgStdDev > maxErr) { - maxErr = avgStdDev; - } - */ - } // for all bricks std::sort(meanArray.begin(), meanArray.end()); //float medErr = meanArray[meanArray.size()/2]; - /* - LDEBUG("\nMin temporal error: " << minErr); - LDEBUG("Max temporal error: " << maxErr); - LDEBUG("Median temporal error: " << medErr); - */ - // Adjust errors using user-provided exponents float minNorm = 1e20f; float maxNorm = 0.f; - for (unsigned int i = 0; i 0.f) { errors[i] = pow(errors[i], 0.25f); } - //data_[i*NUM_DATA + TEMPORAL_ERR] = *reinterpret_cast(&errors[i]); - data_[i*NUM_DATA + TEMPORAL_ERR] = glm::floatBitsToInt(errors[i]); + _data[i * NUM_DATA + TEMPORAL_ERR] = glm::floatBitsToInt(errors[i]); if (errors[i] < minNorm) { minNorm = errors[i]; } @@ -544,9 +490,9 @@ bool TSP::calculateTemporalError() { std::sort(errors.begin(), errors.end()); float medNorm = errors[errors.size() / 2]; - minTemporalError_ = minNorm; - maxTemporalError_ = maxNorm; - medianTemporalError_ = medNorm; + _minTemporalError = minNorm; + _maxTemporalError = maxNorm; + _medianTemporalError = medNorm; LDEBUG(fmt::format("Min normalized temporal std dev: {}", minNorm)); LDEBUG(fmt::format("Max normalized temporal std dev: {}", maxNorm)); @@ -561,7 +507,10 @@ bool TSP::readCache() { ghoul::filesystem::File f = _filename; std::string cacheFilename = FileSys.cacheManager()->cachedFilename( - f.baseName(), "", ghoul::filesystem::CacheManager::Persistent::Yes); + f.baseName(), + "", + ghoul::filesystem::CacheManager::Persistent::Yes + ); std::ifstream file(cacheFilename, std::ios::in | std::ios::binary); if (!file.is_open()) { @@ -570,34 +519,38 @@ bool TSP::readCache() { } - file.read(reinterpret_cast(&minSpatialError_), sizeof(float)); - file.read(reinterpret_cast(&maxSpatialError_), sizeof(float)); - file.read(reinterpret_cast(&medianSpatialError_), sizeof(float)); - file.read(reinterpret_cast(&minTemporalError_), sizeof(float)); - file.read(reinterpret_cast(&maxTemporalError_), sizeof(float)); - file.read(reinterpret_cast(&medianTemporalError_), sizeof(float)); - size_t dataSize = static_cast(numTotalNodes_*NUM_DATA)*sizeof(int); - file.read(reinterpret_cast(&data_[0]), dataSize); + file.read(reinterpret_cast(&_minSpatialError), sizeof(float)); + file.read(reinterpret_cast(&_maxSpatialError), sizeof(float)); + file.read(reinterpret_cast(&_medianSpatialError), sizeof(float)); + file.read(reinterpret_cast(&_minTemporalError), sizeof(float)); + file.read(reinterpret_cast(&_maxTemporalError), sizeof(float)); + file.read(reinterpret_cast(&_medianTemporalError), sizeof(float)); + size_t dataSize = static_cast(_numTotalNodes * NUM_DATA) * sizeof(int); + file.read(reinterpret_cast(_data.data()), dataSize); file.close(); LDEBUG("Cached errors:"); - LDEBUG(fmt::format("Min spatial error: {}", minSpatialError_)); - LDEBUG(fmt::format("Max spatial error: {}", maxSpatialError_)); - LDEBUG(fmt::format("Median spatial error: {}", medianSpatialError_)); - LDEBUG(fmt::format("Min temporal error: {}", minTemporalError_)); - LDEBUG(fmt::format("Max temporal error: {}", maxTemporalError_)); - LDEBUG(fmt::format("Median temporal error: {}", medianTemporalError_)); + LDEBUG(fmt::format("Min spatial error: {}", _minSpatialError)); + LDEBUG(fmt::format("Max spatial error: {}", _maxSpatialError)); + LDEBUG(fmt::format("Median spatial error: {}", _medianSpatialError)); + LDEBUG(fmt::format("Min temporal error: {}", _minTemporalError)); + LDEBUG(fmt::format("Max temporal error: {}", _maxTemporalError)); + LDEBUG(fmt::format("Median temporal error: {}", _medianTemporalError)); return true; } bool TSP::writeCache() { - if (!FileSys.cacheManager()) + if (!FileSys.cacheManager()) { return false; + } ghoul::filesystem::File f = _filename; std::string cacheFilename = FileSys.cacheManager()->cachedFilename( - f.baseName(), "", ghoul::filesystem::CacheManager::Persistent::Yes); + f.baseName(), + "", + ghoul::filesystem::CacheManager::Persistent::Yes + ); std::ofstream file(cacheFilename, std::ios::out | std::ios::binary); if (!file.is_open()) { @@ -606,102 +559,92 @@ bool TSP::writeCache() { } LINFO(fmt::format("Writing cache to {}", cacheFilename)); - - file.write(reinterpret_cast(&minSpatialError_), sizeof(float)); - file.write(reinterpret_cast(&maxSpatialError_), sizeof(float)); - file.write(reinterpret_cast(&medianSpatialError_), sizeof(float)); - file.write(reinterpret_cast(&minTemporalError_), sizeof(float)); - file.write(reinterpret_cast(&maxTemporalError_), sizeof(float)); - file.write(reinterpret_cast(&medianTemporalError_), sizeof(float)); - file.write(reinterpret_cast(&data_[0]), data_.size()*sizeof(float)); + file.write(reinterpret_cast(&_minSpatialError), sizeof(float)); + file.write(reinterpret_cast(&_maxSpatialError), sizeof(float)); + file.write(reinterpret_cast(&_medianSpatialError), sizeof(float)); + file.write(reinterpret_cast(&_minTemporalError), sizeof(float)); + file.write(reinterpret_cast(&_maxTemporalError), sizeof(float)); + file.write(reinterpret_cast(&_medianTemporalError), sizeof(float)); + file.write(reinterpret_cast(_data.data()), _data.size() * sizeof(float)); file.close(); - /* - LDEBUG("\nData:"); - for (unsigned i=0; i(&data_[i*NUM_DATA + SPATIAL_ERR])); - LDEBUG("Temporal err " << *reinterpret_cast(&data_[i*NUM_DATA + TEMPORAL_ERR])); - } - */ - return true; } -float TSP::getSpatialError(unsigned int _brickIndex) { - return reinterpret_cast(data_[_brickIndex*NUM_DATA + SPATIAL_ERR]); +float TSP::spatialError(unsigned int brickIndex) const { + return reinterpret_cast(_data[brickIndex*NUM_DATA + SPATIAL_ERR]); } -float TSP::getTemporalError(unsigned int _brickIndex) { - return reinterpret_cast(data_[_brickIndex*NUM_DATA + TEMPORAL_ERR]); +float TSP::temporalError(unsigned int brickIndex) const { + return reinterpret_cast(_data[brickIndex*NUM_DATA + TEMPORAL_ERR]); } -unsigned int TSP::getFirstOctreeChild(unsigned int _brickIndex) { - unsigned int otNode = _brickIndex % numOTNodes_; - unsigned int bstOffset = _brickIndex - otNode; +unsigned int TSP::firstOctreeChild(unsigned int brickIndex) const { + const unsigned int otNode = brickIndex % _numOTNodes; + const unsigned int bstOffset = brickIndex - otNode; - unsigned int depth = log(7 * otNode + 1) / log(8); - unsigned int firstInLevel = (pow(8, depth) - 1) / 7; - unsigned int levelOffset = otNode - firstInLevel; - unsigned int firstInChildLevel = (pow(8, depth + 1) - 1) / 7; - unsigned int childIndex = firstInChildLevel + 8*levelOffset; + const unsigned int depth = static_cast(log(7 * otNode + 1) / log(8)); + const unsigned int firstInLevel = static_cast((pow(8, depth) - 1) / 7); + const unsigned int levelOffset = otNode - firstInLevel; + const unsigned int firstInChildLevel = static_cast( + (pow(8, depth + 1) - 1) / 7 + ); + const unsigned int childIndex = firstInChildLevel + 8 * levelOffset; return bstOffset + childIndex; } -unsigned int TSP::getBstLeft(unsigned int _brickIndex) { - unsigned int bstNode = _brickIndex / numOTNodes_; - unsigned int otOffset = _brickIndex % numOTNodes_; - unsigned int depth = log(bstNode + 1) / log(2); - unsigned int firstInLevel = pow(2, depth) - 1; - unsigned int levelOffset = bstNode - firstInLevel; - unsigned int firstInChildLevel = pow(2, depth + 1) - 1; - unsigned int childIndex = firstInChildLevel + 2*levelOffset; - return otOffset + childIndex * numOTNodes_; +unsigned int TSP::bstLeft(unsigned int brickIndex) const { + const unsigned int bstNode = brickIndex / _numOTNodes; + const unsigned int otOffset = brickIndex % _numOTNodes; + const unsigned int depth = static_cast(log(bstNode + 1) / log(2)); + const unsigned int firstInLevel = static_cast(pow(2, depth) - 1); + const unsigned int levelOffset = bstNode - firstInLevel; + const unsigned int firstInChildLevel = static_cast( + pow(2, depth + 1) - 1 + ); + const unsigned int childIndex = firstInChildLevel + 2 * levelOffset; + return otOffset + childIndex * _numOTNodes; } -unsigned int TSP::getBstRight(unsigned int _brickIndex) { - return getBstLeft(_brickIndex) + numOTNodes_; +unsigned int TSP::bstRight(unsigned int brickIndex) const { + return bstLeft(brickIndex) + _numOTNodes; } -bool TSP::isBstLeaf(unsigned int _brickIndex) { - unsigned int bstNode = _brickIndex / numOTNodes_; - return bstNode >= numBSTNodes_ / 2; +bool TSP::isBstLeaf(unsigned int brickIndex) const { + const unsigned int bstNode = brickIndex / _numOTNodes; + return bstNode >= _numBSTNodes / 2; } -bool TSP::isOctreeLeaf(unsigned int _brickIndex) { - unsigned int otNode = _brickIndex % numOTNodes_; - unsigned int depth = log(7 * otNode + 1) / log(8); - return depth == numOTLevels_ - 1; +bool TSP::isOctreeLeaf(unsigned int brickIndex) const { + const unsigned int otNode = brickIndex % _numOTNodes; + const unsigned int depth = static_cast(log(7 * otNode + 1) / log(8)); + return depth == _numOTLevels - 1; } - -std::list TSP::CoveredLeafBricks(unsigned int _brickIndex) { +std::list TSP::coveredLeafBricks(unsigned int brickIndex) const { std::list out; // Find what octree skeleton node the index belongs to - unsigned int OTNode = _brickIndex % numOTNodes_; + const unsigned int OTNode = brickIndex % _numOTNodes; // Find what BST node the index corresponds to using int division - unsigned int BSTNode = _brickIndex / numOTNodes_; + const unsigned int BSTNode = brickIndex / _numOTNodes; // Calculate BST offset (to translate to root octree) - unsigned int BSTOffset = BSTNode * numOTNodes_; + const unsigned int BSTOffset = BSTNode * _numOTNodes; // Traverse root octree structure to leaves // When visiting the leaves, translate back to correct BST level and save std::queue queue; queue.push(OTNode); do { - // Get front of queue and pop it - unsigned int toVisit = queue.front(); + const unsigned int toVisit = queue.front(); queue.pop(); // See if the node has children - int child = data_[toVisit*NUM_DATA + CHILD_INDEX]; + int child = _data[toVisit*NUM_DATA + CHILD_INDEX]; if (child == -1) { // Translate back and save out.push_back(toVisit + BSTOffset); @@ -712,35 +655,33 @@ std::list TSP::CoveredLeafBricks(unsigned int _brickIndex) { queue.push(child + i); } } - } while (!queue.empty()); return out; } -std::list TSP::CoveredBSTLeafBricks(unsigned int _brickIndex) { +std::list TSP::coveredBSTLeafBricks(unsigned int brickIndex) const { std::list out; // Traverse the BST children until we are at root std::queue queue; - queue.push(_brickIndex); + queue.push(brickIndex); do { - - unsigned int toVisit = queue.front(); + const unsigned int toVisit = queue.front(); queue.pop(); - bool BSTRoot = toVisit < numOTNodes_; + bool BSTRoot = toVisit < _numOTNodes; if (BSTRoot) { - if (numBSTLevels_ == 1) { + if (_numBSTLevels == 1) { out.push_back(toVisit); } else { - queue.push(toVisit + numOTNodes_); - queue.push(toVisit + numOTNodes_ * 2); + queue.push(toVisit + _numOTNodes); + queue.push(toVisit + _numOTNodes * 2); } } else { - int child = data_[toVisit*NUM_DATA + CHILD_INDEX]; + int child = _data[toVisit*NUM_DATA + CHILD_INDEX]; if (child == -1) { // Save leaf brick to list out.push_back(toVisit); @@ -748,7 +689,7 @@ std::list TSP::CoveredBSTLeafBricks(unsigned int _brickIndex) { else { // Queue children queue.push(child); - queue.push(child + numOTNodes_); + queue.push(child + _numOTNodes); } } @@ -757,4 +698,4 @@ std::list TSP::CoveredBSTLeafBricks(unsigned int _brickIndex) { return out; } -} +} // namespace openspace diff --git a/modules/multiresvolume/rendering/tsp.h b/modules/multiresvolume/rendering/tsp.h index a1b519ba16..8ab3691dff 100644 --- a/modules/multiresvolume/rendering/tsp.h +++ b/modules/multiresvolume/rendering/tsp.h @@ -25,27 +25,26 @@ #ifndef __OPENSPACE_MODULE_MULTIRESVOLUME___TSP___H__ #define __OPENSPACE_MODULE_MULTIRESVOLUME___TSP___H__ +#include +#include +#include #include #include -#include -#include -#include - -#include namespace openspace { + class TSP { public: struct Header { - unsigned int gridType_; - unsigned int numOrigTimesteps_; - unsigned int numTimesteps_; - unsigned int xBrickDim_; - unsigned int yBrickDim_; - unsigned int zBrickDim_; - unsigned int xNumBricks_; - unsigned int yNumBricks_; - unsigned int zNumBricks_; + unsigned int gridType; + unsigned int numOrigTimesteps; + unsigned int numTimesteps; + unsigned int xBrickDim; + unsigned int yBrickDim; + unsigned int zBrickDim; + unsigned int xNumBricks; + unsigned int yNumBricks; + unsigned int zNumBricks; }; enum NodeData { @@ -86,59 +85,58 @@ public: bool calculateSpatialError(); bool calculateTemporalError(); - float getSpatialError(unsigned int _brickIndex); - float getTemporalError(unsigned int _brickIndex); - unsigned int getFirstOctreeChild(unsigned int _brickIndex); + float spatialError(unsigned int brickIndex) const; + float temporalError(unsigned int brickIndex) const; + unsigned int firstOctreeChild(unsigned int brickIndex) const; - unsigned int getBstLeft(unsigned int _brickIndex); - unsigned int getBstRight(unsigned int _brickIndex); + unsigned int bstLeft(unsigned int brickIndex) const; + unsigned int bstRight(unsigned int brickIndex) const; - bool isBstLeaf(unsigned int _brickIndex); - bool isOctreeLeaf(unsigned int _brickIndex); + bool isBstLeaf(unsigned int brickIndex) const; + bool isOctreeLeaf(unsigned int brickIndex) const; private: // Returns a list of the octree leaf nodes that a given input // brick covers. If the input is already a leaf, the list will // only contain that one index. - std::list CoveredLeafBricks(unsigned int _brickIndex); + std::list coveredLeafBricks(unsigned int brickIndex) const; // Returns a list of the BST leaf nodes that a given input brick // covers (at the same spatial subdivision level). - std::list CoveredBSTLeafBricks(unsigned int _brickIndex); + std::list coveredBSTLeafBricks(unsigned int brickIndex) const; // Return a list of eight children brick incices given a brick index - std::list ChildBricks(unsigned int _brickIndex); + std::list childBricks(unsigned int brickIndex); std::string _filename; std::ifstream _file; std::streampos _dataOffset; // Holds the actual structure - std::vector data_; - GLuint _dataSSBO; + std::vector _data; + GLuint _dataSSBO = 0; // Data from file Header _header; // Additional metadata - unsigned int paddedBrickDim_; - unsigned int numTotalNodes_; - unsigned int numBSTLevels_; - unsigned int numBSTNodes_; - unsigned int numOTLevels_; - unsigned int numOTNodes_; + unsigned int _paddedBrickDim = 0; + unsigned int _numTotalNodes = 0; + unsigned int _numBSTLevels = 0; + unsigned int _numBSTNodes = 0; + unsigned int _numOTLevels = 0; + unsigned int _numOTNodes = 0; - const unsigned int paddingWidth_ = 1; + const unsigned int _paddingWidth = 1; // Error stats - float minSpatialError_; - float maxSpatialError_; - float medianSpatialError_; - float minTemporalError_; - float maxTemporalError_; - float medianTemporalError_; - -}; // class TSP + float _minSpatialError = 0.f; + float _maxSpatialError = 0.f; + float _medianSpatialError = 0.f; + float _minTemporalError = 0.f; + float _maxTemporalError = 0.f; + float _medianTemporalError = 0.f; +}; } // namespace openspace diff --git a/modules/spacecraftinstruments/rendering/renderablefov.cpp b/modules/spacecraftinstruments/rendering/renderablefov.cpp index 0a21ebf15e..409bc6f761 100644 --- a/modules/spacecraftinstruments/rendering/renderablefov.cpp +++ b/modules/spacecraftinstruments/rendering/renderablefov.cpp @@ -900,15 +900,15 @@ void RenderableFov::update(const UpdateData& data) { // TODO: figure out if time has changed if (_drawFOV /* && time changed */) { - const std::pair& t = determineTarget(data.time.j2000Seconds()); + const std::pair& t = determineTarget(data.time.j2000Seconds()); computeIntercepts(data, t.first, t.second); updateGPU(); - const double t2 = (ImageSequencer::ref().nextCaptureTime(data.time.j2000Seconds())); + const double t2 = ImageSequencer::ref().nextCaptureTime(data.time.j2000Seconds()); const double diff = (t2 - data.time.j2000Seconds()); _interpolationTime = 0.f; - const float interpolationStart = 7.f; //seconds before + const float interpolationStart = 7.f; // seconds before if (diff <= interpolationStart) { _interpolationTime = static_cast(1.f - (diff / interpolationStart)); } @@ -921,7 +921,6 @@ void RenderableFov::update(const UpdateData& data) { if (_programObject->isDirty()) { _programObject->rebuildFromFile(); - _uniformCache.modelViewProjection = _programObject->uniformLocation( "modelViewProjectionTransform" ); diff --git a/modules/spacecraftinstruments/rendering/renderablemodelprojection.cpp b/modules/spacecraftinstruments/rendering/renderablemodelprojection.cpp index 437b9e79f1..c504c7393c 100644 --- a/modules/spacecraftinstruments/rendering/renderablemodelprojection.cpp +++ b/modules/spacecraftinstruments/rendering/renderablemodelprojection.cpp @@ -395,7 +395,7 @@ void RenderableModelProjection::update(const UpdateData& data) { _imageTimes, _projectionComponent.projecteeId(), _projectionComponent.instrumentId(), - time, + time, integrateFromTime ); } diff --git a/modules/spacecraftinstruments/rendering/renderableplanetprojection.cpp b/modules/spacecraftinstruments/rendering/renderableplanetprojection.cpp index da052ebb9f..ddd0dace19 100644 --- a/modules/spacecraftinstruments/rendering/renderableplanetprojection.cpp +++ b/modules/spacecraftinstruments/rendering/renderableplanetprojection.cpp @@ -606,7 +606,6 @@ void RenderablePlanetProjection::render(const RenderData& data, RendererTasks&) _camScaling = glm::vec2(1.f, 0.f); // Unit scaling _up = data.camera.lookUpVectorCameraSpace(); - if (_projectionComponent.doesPerformProjection()) { int nPerformedProjections = 0; for (const Image& img : _imageTimes) { diff --git a/modules/spacecraftinstruments/util/imagesequencer.cpp b/modules/spacecraftinstruments/util/imagesequencer.cpp index 004650d727..92936d8eae 100644 --- a/modules/spacecraftinstruments/util/imagesequencer.cpp +++ b/modules/spacecraftinstruments/util/imagesequencer.cpp @@ -200,7 +200,9 @@ bool ImageSequencer::isInstrumentActive(double time, const std::string& instrume return false; } -float ImageSequencer::instrumentActiveTime(double time, const std::string& instrumentID) const { +float ImageSequencer::instrumentActiveTime(double time, + const std::string& instrumentID) const +{ for (const std::pair& i : _instrumentTimes) { //check if this instrument is in range if (i.second.includes(time)){ diff --git a/modules/touch/src/touchinteraction.cpp b/modules/touch/src/touchinteraction.cpp index 3b74f2790f..4168af4628 100644 --- a/modules/touch/src/touchinteraction.cpp +++ b/modules/touch/src/touchinteraction.cpp @@ -370,8 +370,12 @@ void TouchInteraction::updateStateFromInput(const std::vector& list, list.at(0).getScreenY(res.y) ); const float bottomCornerSizeForZoomTap_fraction = 0.08f; - int zoomTapThresholdX = static_cast(res.x * (1.0f - bottomCornerSizeForZoomTap_fraction)); - int zoomTapThresholdY = static_cast(res.y * (1.0f - bottomCornerSizeForZoomTap_fraction)); + int zoomTapThresholdX = static_cast( + res.x * (1.0f - bottomCornerSizeForZoomTap_fraction) + ); + int zoomTapThresholdY = static_cast( + res.y * (1.0f - bottomCornerSizeForZoomTap_fraction) + ); bool isTapInLowerCorner = std::abs(pos.x) > zoomTapThresholdX && std::abs(pos.y) > zoomTapThresholdY; diff --git a/src/scene/timeframe.cpp b/src/scene/timeframe.cpp index b1e8f30c66..4efed887bc 100644 --- a/src/scene/timeframe.cpp +++ b/src/scene/timeframe.cpp @@ -58,7 +58,9 @@ documentation::Documentation TimeFrame::Documentation() { }; } -std::unique_ptr TimeFrame::createFromDictionary(const ghoul::Dictionary& dictionary) { +std::unique_ptr TimeFrame::createFromDictionary( + const ghoul::Dictionary& dictionary) +{ documentation::testSpecificationAndThrow(Documentation(), dictionary, "TimeFrame"); const std::string timeFrameType = dictionary.value(KeyType); diff --git a/src/util/timemanager.cpp b/src/util/timemanager.cpp index 4d9b030cdc..53a5aba4c8 100644 --- a/src/util/timemanager.cpp +++ b/src/util/timemanager.cpp @@ -75,10 +75,30 @@ using datamessagestructures::TimeKeyframe; TimeManager::TimeManager() : properties::PropertyOwner({ "TimeManager" }) - , _defaultTimeInterpolationDuration(DefaultTimeInterpolationDurationInfo, 2.0f, 0.f, 5.f) - , _defaultDeltaTimeInterpolationDuration(DefaultDeltaTimeInterpolationDurationInfo, 1.0f, 0.f, 5.f) - , _defaultPauseInterpolationDuration(DefaultPauseInterpolationDurationInfo, 0.5f, 0.f, 5.f) - , _defaultUnpauseInterpolationDuration(DefaultUnpauseInterpolationDurationInfo, 1.0f, 0.f, 5.f) + , _defaultTimeInterpolationDuration( + DefaultTimeInterpolationDurationInfo, + 2.f, + 0.f, + 5.f + ) + , _defaultDeltaTimeInterpolationDuration( + DefaultDeltaTimeInterpolationDurationInfo, + 1.f, + 0.f, + 5.f + ) + , _defaultPauseInterpolationDuration( + DefaultPauseInterpolationDurationInfo, + 0.5f, + 0.f, + 5.f + ) + , _defaultUnpauseInterpolationDuration( + DefaultUnpauseInterpolationDurationInfo, + 1.f, + 0.f, + 5.f + ) { addProperty(_defaultTimeInterpolationDuration); addProperty(_defaultDeltaTimeInterpolationDuration); @@ -379,7 +399,8 @@ TimeManager::CallbackHandle TimeManager::addTimeJumpCallback(TimeChangeCallback return handle; } -TimeManager::CallbackHandle TimeManager::addTimelineChangeCallback(TimeChangeCallback cb) { +TimeManager::CallbackHandle TimeManager::addTimelineChangeCallback(TimeChangeCallback cb) +{ CallbackHandle handle = _nextCallbackHandle++; _timelineChangeCallbacks.push_back({ handle, std::move(cb) }); return handle; @@ -441,8 +462,8 @@ void TimeManager::removeTimelineChangeCallback(CallbackHandle handle) { _timelineChangeCallbacks.begin(), _timelineChangeCallbacks.end(), [handle](const std::pair>& cb) { - return cb.first == handle; - } + return cb.first == handle; + } ); ghoul_assert( @@ -481,7 +502,8 @@ double TimeManager::targetDeltaTime() const { return _targetDeltaTime; } -void TimeManager::interpolateDeltaTime(double newDeltaTime, double interpolationDuration) { +void TimeManager::interpolateDeltaTime(double newDeltaTime, double interpolationDuration) +{ if (newDeltaTime == _targetDeltaTime) { return; }