mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-07 12:10:52 -06:00
Merge branch 'develop' of https://github.com/OpenSpace/OpenSpace-Development into develop
This commit is contained in:
45
apps/DataConverter/CMakeLists.txt
Normal file
45
apps/DataConverter/CMakeLists.txt
Normal file
@@ -0,0 +1,45 @@
|
||||
#########################################################################################
|
||||
# #
|
||||
# OpenSpace #
|
||||
# #
|
||||
# Copyright (c) 2014-2016 #
|
||||
# #
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy of this #
|
||||
# software and associated documentation files (the "Software"), to deal in the Software #
|
||||
# without restriction, including without limitation the rights to use, copy, modify, #
|
||||
# merge, publish, distribute, sublicense, and/or sell copies of the Software, and to #
|
||||
# permit persons to whom the Software is furnished to do so, subject to the following #
|
||||
# conditions: #
|
||||
# #
|
||||
# The above copyright notice and this permission notice shall be included in all copies #
|
||||
# or substantial portions of the Software. #
|
||||
# #
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, #
|
||||
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A #
|
||||
# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT #
|
||||
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF #
|
||||
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE #
|
||||
# OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #
|
||||
#########################################################################################
|
||||
|
||||
set(APPLICATION_NAME DataConverter)
|
||||
set(APPLICATION_LINK_TO_OPENSPACE ON)
|
||||
|
||||
include (${GHOUL_BASE_DIR}/support/cmake/handle_external_library.cmake)
|
||||
|
||||
set(application_path ${OPENSPACE_APPS_DIR}/DataConverter)
|
||||
|
||||
set(SOURCE_FILES
|
||||
${application_path}/main.cpp
|
||||
${application_path}/milkywayconversiontask.cpp
|
||||
)
|
||||
set(HEADER_FILES
|
||||
${application_path}/conversiontask.h
|
||||
${application_path}/milkywayconversiontask.h
|
||||
)
|
||||
|
||||
add_executable(${APPLICATION_NAME} MACOSX_BUNDLE
|
||||
${SOURCE_FILES}
|
||||
${HEADER_FILES}
|
||||
)
|
||||
|
||||
17
apps/DataConverter/conversiontask.h
Normal file
17
apps/DataConverter/conversiontask.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef __CONVERSIONTASK_H__
|
||||
#define __CONVERSIONTASK_H__
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace openspace {
|
||||
namespace dataconverter {
|
||||
|
||||
class ConversionTask {
|
||||
public:
|
||||
virtual void perform(const std::function<void(float)>& onProgress) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
77
apps/DataConverter/main.cpp
Normal file
77
apps/DataConverter/main.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <ghoul/opengl/ghoul_gl.h>
|
||||
#include <ghoul/io/texture/texturereader.h>
|
||||
#include <ghoul/io/texture/texturereaderdevil.h>
|
||||
#include <ghoul/io/texture/texturereaderfreeimage.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/ghoul.h>
|
||||
|
||||
#include <openspace/util/progressbar.h>
|
||||
|
||||
#include <apps/DataConverter/milkywayconversiontask.h>
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
using namespace openspace;
|
||||
using namespace dataconverter;
|
||||
|
||||
ghoul::initialize();
|
||||
|
||||
#ifdef GHOUL_USE_DEVIL
|
||||
ghoul::io::TextureReader::ref().addReader(std::make_shared<ghoul::io::TextureReaderDevIL>());
|
||||
#endif // GHOUL_USE_DEVIL
|
||||
#ifdef GHOUL_USE_FREEIMAGE
|
||||
ghoul::io::TextureReader::ref().addReader(std::make_shared<ghoul::io::TextureReaderFreeImage>());
|
||||
#endif // GHOUL_USE_FREEIMAGE
|
||||
|
||||
openspace::ProgressBar pb(100);
|
||||
std::function<void(float)> onProgress = [&](float progress) {
|
||||
pb.print(progress * 100);
|
||||
};
|
||||
|
||||
// TODO: Make the converter configurable using either
|
||||
// config files (json, lua dictionaries),
|
||||
// lua scripts,
|
||||
// or at the very least: a command line interface.
|
||||
|
||||
MilkyWayConversionTask mwConversionTask(
|
||||
"F:/milky-way/cam2_main.",
|
||||
".exr",
|
||||
1385,
|
||||
512,
|
||||
"F:/milky-way/mw_512_512_64.rawvolume",
|
||||
glm::vec3(512, 512, 64));
|
||||
|
||||
mwConversionTask.perform(onProgress);
|
||||
|
||||
std::cout << "Done." << std::endl;
|
||||
|
||||
std::cin.get();
|
||||
return 0;
|
||||
};
|
||||
50
apps/DataConverter/milkywayconversiontask.cpp
Normal file
50
apps/DataConverter/milkywayconversiontask.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
#include <apps/DataConverter/milkywayconversiontask.h>
|
||||
#include <modules/volume/textureslicevolumereader.h>
|
||||
#include <modules/volume/rawvolumewriter.h>
|
||||
#include <modules/volume/volumesampler.h>
|
||||
|
||||
namespace openspace {
|
||||
namespace dataconverter {
|
||||
|
||||
MilkyWayConversionTask::MilkyWayConversionTask(
|
||||
const std::string& inFilenamePrefix,
|
||||
const std::string& inFilenameSuffix,
|
||||
size_t inFirstIndex,
|
||||
size_t inNSlices,
|
||||
const std::string& outFilename,
|
||||
const glm::ivec3& outDimensions)
|
||||
: _inFilenamePrefix(inFilenamePrefix)
|
||||
, _inFilenameSuffix(inFilenameSuffix)
|
||||
, _inFirstIndex(inFirstIndex)
|
||||
, _inNSlices(inNSlices)
|
||||
, _outFilename(outFilename)
|
||||
, _outDimensions(outDimensions) {}
|
||||
|
||||
|
||||
void MilkyWayConversionTask::perform(const std::function<void(float)>& onProgress) {
|
||||
std::vector<std::string> filenames;
|
||||
for (int i = 0; i < _inNSlices; i++) {
|
||||
filenames.push_back(_inFilenamePrefix + std::to_string(i + _inFirstIndex) + _inFilenameSuffix);
|
||||
}
|
||||
|
||||
TextureSliceVolumeReader<glm::tvec4<GLfloat>> sliceReader(filenames, _inNSlices, 10);
|
||||
sliceReader.initialize();
|
||||
|
||||
RawVolumeWriter<glm::tvec4<GLfloat>> rawWriter(_outFilename);
|
||||
rawWriter.setDimensions(_outDimensions);
|
||||
|
||||
glm::vec3 resolutionRatio =
|
||||
static_cast<glm::vec3>(sliceReader.dimensions()) / static_cast<glm::vec3>(rawWriter.dimensions());
|
||||
|
||||
VolumeSampler<TextureSliceVolumeReader<glm::tvec4<GLfloat>>> sampler(sliceReader, resolutionRatio);
|
||||
std::function<glm::tvec4<GLfloat>(glm::ivec3)> sampleFunction = [&](glm::ivec3 outCoord) {
|
||||
glm::vec3 inCoord = ((glm::vec3(outCoord) + glm::vec3(0.5)) * resolutionRatio) - glm::vec3(0.5);
|
||||
glm::tvec4<GLfloat> value = sampler.sample(inCoord);
|
||||
return value;
|
||||
};
|
||||
|
||||
rawWriter.write(sampleFunction, onProgress);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
41
apps/DataConverter/milkywayconversiontask.h
Normal file
41
apps/DataConverter/milkywayconversiontask.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#ifndef __MILKYWAYCONVERSIONTASK_H__
|
||||
#define __MILKYWAYCONVERSIONTASK_H__
|
||||
|
||||
#include <apps/DataConverter/conversiontask.h>
|
||||
#include <string>
|
||||
#include <glm/glm.hpp>
|
||||
#include <functional>
|
||||
#include <modules/volume/textureslicevolumereader.h>
|
||||
#include <modules/volume/rawvolumewriter.h>
|
||||
|
||||
|
||||
namespace openspace {
|
||||
namespace dataconverter {
|
||||
|
||||
/**
|
||||
* Converts a set of exr image slices to a raw volume
|
||||
* with floating point RGBA data (32 bit per channel).
|
||||
*/
|
||||
class MilkyWayConversionTask : public ConversionTask {
|
||||
public:
|
||||
MilkyWayConversionTask(const std::string& inFilenamePrefix,
|
||||
const std::string& inFilenameSuffix,
|
||||
size_t inFirstIndex,
|
||||
size_t inNSlices,
|
||||
const std::string& outFilename,
|
||||
const glm::ivec3& outDimensions);
|
||||
|
||||
void perform(const std::function<void(float)>& onProgress) override;
|
||||
private:
|
||||
std::string _inFilenamePrefix;
|
||||
std::string _inFilenameSuffix;
|
||||
size_t _inFirstIndex;
|
||||
size_t _inNSlices;
|
||||
std::string _outFilename;
|
||||
glm::ivec3 _outDimensions;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Submodule ext/ghoul updated: 6bbf25bc7c...3ef4b9e9e4
@@ -25,14 +25,24 @@
|
||||
include(${OPENSPACE_CMAKE_EXT_DIR}/module_definition.cmake)
|
||||
|
||||
set(HEADER_FILES
|
||||
# ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablevolume.h
|
||||
# ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablevolumegl.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rawvolume.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rawvolumereader.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rawvolumewriter.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/textureslicevolumereader.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/lrucache.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/linearlrucache.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/volumesampler.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/volumeutils.h
|
||||
)
|
||||
source_group("Header Files" FILES ${HEADER_FILES})
|
||||
|
||||
set(SOURCE_FILES
|
||||
# ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablevolume.cpp
|
||||
# ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablevolumegl.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rawvolume.inl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rawvolumereader.inl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rawvolumewriter.inl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/textureslicevolumereader.inl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/volumesampler.inl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/volumeutils.cpp
|
||||
)
|
||||
source_group("Source Files" FILES ${SOURCE_FILES})
|
||||
|
||||
|
||||
91
modules/volume/linearlrucache.h
Normal file
91
modules/volume/linearlrucache.h
Normal file
@@ -0,0 +1,91 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014 - 2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __LRUCACHE_H__
|
||||
#define __LRUCACHE_H__
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <list>
|
||||
#include <iterator>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
template <typename ValueType>
|
||||
class LinearLruCache {
|
||||
public:
|
||||
LinearLruCache(size_t capacity, size_t nIndices)
|
||||
: _tracker()
|
||||
, _cache(nIndices, std::make_pair(nullptr, _tracker.end()))
|
||||
, _capacity(capacity) {};
|
||||
|
||||
bool has(size_t key) {
|
||||
return _cache[key].first != nullptr;
|
||||
};
|
||||
void set(size_t key, ValueType value) {
|
||||
auto prev = _cache[key];
|
||||
if (prev.first != nullptr) {
|
||||
prev.first = value;
|
||||
std::list<size_t>::iterator trackerIter = prev.second;
|
||||
_tracker.splice(_tracker.end(),
|
||||
_tracker,
|
||||
trackerIter);
|
||||
}
|
||||
else {
|
||||
insert(key, value);
|
||||
}
|
||||
};
|
||||
ValueType& use(size_t key) {
|
||||
auto pair = _cache[key];
|
||||
std::list<size_t>::iterator trackerIter = pair.second;
|
||||
_tracker.splice(_tracker.end(),
|
||||
_tracker,
|
||||
trackerIter);
|
||||
return pair.first;
|
||||
};
|
||||
ValueType& get(size_t key) {
|
||||
return _cache[key].first;
|
||||
};
|
||||
void evict() {
|
||||
_cache[_tracker.front()] = make_pair(nullptr, _tracker.end());
|
||||
_tracker.pop_front();
|
||||
};
|
||||
size_t capacity() {
|
||||
return _capacity;
|
||||
};
|
||||
private:
|
||||
void insert(size_t key, const ValueType& value) {
|
||||
if (_tracker.size() == _capacity) {
|
||||
evict();
|
||||
}
|
||||
auto iter = _tracker.insert(_tracker.end(), key);
|
||||
_cache[key] = std::make_pair(value, iter);
|
||||
};
|
||||
std::list<size_t> _tracker;
|
||||
std::vector<std::pair<ValueType, typename std::list<size_t>::iterator>> _cache;
|
||||
size_t _capacity;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
91
modules/volume/lrucache.h
Normal file
91
modules/volume/lrucache.h
Normal file
@@ -0,0 +1,91 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014 - 2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __LRUCACHE_H__
|
||||
#define __LRUCACHE_H__
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <list>
|
||||
#include <iterator>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
template <typename KeyType, typename ValueType, template<typename...> class ContainerType>
|
||||
class LruCache {
|
||||
typedef KeyType K;
|
||||
public:
|
||||
LruCache(size_t capacity) {
|
||||
_capacity = capacity;
|
||||
};
|
||||
bool has(const KeyType& key) {
|
||||
return (_cache.find(key) != _cache.end());
|
||||
};
|
||||
void set(const KeyType& key, ValueType value) {
|
||||
auto prev = _cache.find(key);
|
||||
if (prev != _cache.end()) {
|
||||
prev->second.first = value;
|
||||
std::list<KeyType>::iterator trackerIter = prev->second.second;
|
||||
_tracker.splice(_tracker.end(),
|
||||
_tracker,
|
||||
trackerIter);
|
||||
}
|
||||
else {
|
||||
insert(key, value);
|
||||
}
|
||||
};
|
||||
ValueType& use(const KeyType& key) {
|
||||
auto iter = _cache.find(key);
|
||||
std::list<KeyType>::iterator trackerIter = iter->second.second;
|
||||
_tracker.splice(_tracker.end(),
|
||||
_tracker,
|
||||
trackerIter);
|
||||
return iter->second.first;
|
||||
};
|
||||
ValueType& get(const KeyType& key) {
|
||||
auto iter = _cache.find(key);
|
||||
return iter->second.first;
|
||||
};
|
||||
void evict() {
|
||||
_cache.erase(_cache.find(_tracker.front()));
|
||||
_tracker.pop_front();
|
||||
};
|
||||
size_t capacity() {
|
||||
return _capacity;
|
||||
};
|
||||
private:
|
||||
void insert(const KeyType& key, const ValueType& value) {
|
||||
if (_cache.size() == _capacity) {
|
||||
evict();
|
||||
}
|
||||
auto iter = _tracker.insert(_tracker.end(), key);
|
||||
_cache[key] = std::make_pair(value, iter);
|
||||
};
|
||||
ContainerType<KeyType, std::pair<ValueType, typename std::list<KeyType>::iterator>> _cache;
|
||||
std::list<KeyType> _tracker;
|
||||
size_t _capacity;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
54
modules/volume/rawvolume.h
Normal file
54
modules/volume/rawvolume.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014 - 2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __RAWVOLUME_H__
|
||||
#define __RAWVOLUME_H__
|
||||
|
||||
namespace openspace {
|
||||
|
||||
template <typename Voxel>
|
||||
class RawVolume {
|
||||
public:
|
||||
typedef Voxel VoxelType;
|
||||
RawVolume(const glm::ivec3& dimensions);
|
||||
glm::ivec3 dimensions() const;
|
||||
void setDimensions(const glm::ivec3& dimensions);
|
||||
VoxelType get(const glm::ivec3& coordinates) const;
|
||||
VoxelType get(const size_t index) const;
|
||||
void set(const glm::ivec3& coordinates, const VoxelType& value);
|
||||
void set(size_t index, const VoxelType& value);
|
||||
void forEachVoxel(const std::function<void(const glm::ivec3&, const VoxelType&)>& fn);
|
||||
VoxelType* data();
|
||||
private:
|
||||
size_t coordsToIndex(const glm::ivec3& cartesian) const;
|
||||
glm::ivec3 indexToCoords(size_t linear) const;
|
||||
glm::ivec3 _dimensions;
|
||||
std::vector<VoxelType> _data;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#include "rawvolume.inl"
|
||||
|
||||
#endif // __RAWVOLUME_H__
|
||||
100
modules/volume/rawvolume.inl
Normal file
100
modules/volume/rawvolume.inl
Normal file
@@ -0,0 +1,100 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014 - 2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/volume/volumeutils.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
template <typename VoxelType>
|
||||
RawVolume<VoxelType>::RawVolume(const glm::ivec3& dimensions)
|
||||
: _dimensions(dimensions)
|
||||
, _data(static_cast<size_t>(dimensions.x) *
|
||||
static_cast<size_t>(dimensions.y) *
|
||||
static_cast<size_t>(dimensions.z)) {}
|
||||
|
||||
template <typename VoxelType>
|
||||
glm::ivec3 RawVolume<VoxelType>::dimensions() const {
|
||||
return _dimensions;
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
void RawVolume<VoxelType>::setDimensions(const glm::ivec3& dimensions) {
|
||||
_dimensions = dimensions;
|
||||
_data.resize(static_cast<size_t>(dimensions.x) *
|
||||
static_cast<size_t>(dimensions.y) *
|
||||
static_cast<size_t>(dimensions.z));
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType RawVolume<VoxelType>::get(const glm::ivec3& coordinates) const {
|
||||
return get(coordsToIndex(coordinates, dimensions()));
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType RawVolume<VoxelType>::get(size_t index) const {
|
||||
return _data[index];
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
void RawVolume<VoxelType>::set(const glm::ivec3& coordinates, const VoxelType& value) {
|
||||
return set(coordsToIndex(coordinates, dimensions()), value);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
void RawVolume<VoxelType>::set(size_t index, const VoxelType& value) {
|
||||
_data[index] = value;
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
void RawVolume<VoxelType>::forEachVoxel(
|
||||
const std::function<void(const glm::ivec3&, const VoxelType&)>& fn)
|
||||
{
|
||||
|
||||
glm::ivec3 dims = dimensions();
|
||||
size_t nVals = static_cast<size_t>(dims.x) *
|
||||
static_cast<size_t>(dims.y) *
|
||||
static_cast<size_t>(dims.z);
|
||||
|
||||
for (size_t i = 0; i < nVals; i++) {
|
||||
glm::ivec3 coords = indexToCoords(i);
|
||||
fn(coords, _data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
size_t RawVolume<VoxelType>::coordsToIndex(const glm::ivec3& cartesian) const {
|
||||
return volumeutils::coordsToIndex(cartesian, dimensions());
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
glm::ivec3 RawVolume<VoxelType>::indexToCoords(size_t linear) const {
|
||||
return volumeutils::indexToCoords(linear, dimensions());
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType* RawVolume<VoxelType>::data() {
|
||||
return _data.data();
|
||||
}
|
||||
|
||||
}
|
||||
56
modules/volume/rawvolumereader.h
Normal file
56
modules/volume/rawvolumereader.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014 - 2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __RAWVOLUMEREADER_H__
|
||||
#define __RAWVOLUMEREADER_H__
|
||||
|
||||
#include <functional>
|
||||
#include <modules/volume/rawvolume.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
template <typename Voxel>
|
||||
class RawVolumeReader {
|
||||
public:
|
||||
typedef Voxel VoxelType;
|
||||
RawVolumeReader(const std::string& path, const glm::ivec3& dimensions);
|
||||
glm::ivec3 dimensions() const;
|
||||
std::string path() const;
|
||||
void setPath(const std::string& path);
|
||||
void setDimensions(const glm::ivec3& dimensions);
|
||||
//VoxelType get(const glm::ivec3& coordinates) const; // TODO: Implement this
|
||||
//VoxelType get(const size_t index) const; // TODO: Implement this
|
||||
std::unique_ptr<RawVolume<VoxelType>> read();
|
||||
private:
|
||||
size_t coordsToIndex(const glm::ivec3& cartesian) const;
|
||||
glm::ivec3 indexToCoords(size_t linear) const;
|
||||
glm::ivec3 _dimensions;
|
||||
std::string _path;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#include "rawvolumereader.inl"
|
||||
|
||||
#endif // __RAWVOLUMEREADER_H__
|
||||
73
modules/volume/rawvolumereader.inl
Normal file
73
modules/volume/rawvolumereader.inl
Normal file
@@ -0,0 +1,73 @@
|
||||
#include <fstream>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
template <typename VoxelType>
|
||||
RawVolumeReader<VoxelType>::RawVolumeReader(const std::string& path,
|
||||
const glm::ivec3& dimensions)
|
||||
: _path(path)
|
||||
, _dimensions(dimensions) {}
|
||||
|
||||
template <typename VoxelType>
|
||||
glm::ivec3 RawVolumeReader<VoxelType>::dimensions() const {
|
||||
return _dimensions;
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
void RawVolumeReader<VoxelType>::setDimensions(const glm::ivec3& dimensions) {
|
||||
_dimensions = dimensions;
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
std::string RawVolumeReader<VoxelType>::path() const {
|
||||
return _path;
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
void RawVolumeReader<VoxelType>::setPath(const std::string& path) {
|
||||
_path = path;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
TODO: Implement these methods for random access in raw volume file
|
||||
template <typename VoxelType>
|
||||
VoxelType RawVolumeReader<VoxelType>::get(const glm::ivec3& coordinates) const {
|
||||
return get(coordsToIndex(coordinates, dimensions()));
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType RawVolumeReader<VoxelType>::get(size_t index) const {
|
||||
// TODO: read from specific position.
|
||||
return VoxelType();
|
||||
}*/
|
||||
|
||||
template <typename VoxelType>
|
||||
size_t RawVolumeReader<VoxelType>::coordsToIndex(const glm::ivec3& cartesian) const {
|
||||
return volumeutils::coordsToIndex(cartesian, dimensions());
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
glm::ivec3 RawVolumeReader<VoxelType>::indexToCoords(size_t linear) const {
|
||||
return volumeutils::indexToCoords(linear, dimensions());
|
||||
}
|
||||
|
||||
|
||||
template <typename VoxelType>
|
||||
std::unique_ptr<RawVolume<VoxelType>> RawVolumeReader<VoxelType>::read() {
|
||||
glm::ivec3 dims = dimensions();
|
||||
std::unique_ptr<RawVolume<VoxelType>> volume =
|
||||
std::make_unique<RawVolume<VoxelType>>(dims);
|
||||
|
||||
std::ifstream file(_path, std::ios::binary);
|
||||
char *buffer = reinterpret_cast<char*>(volume->data());
|
||||
size_t length = static_cast<size_t>(dims.x) *
|
||||
static_cast<size_t>(dims.y) *
|
||||
static_cast<size_t>(dims.z) *
|
||||
sizeof(VoxelType);
|
||||
|
||||
file.read(buffer, length);
|
||||
return volume;
|
||||
}
|
||||
|
||||
}
|
||||
33
modules/volume/rawvolumewriter.h
Normal file
33
modules/volume/rawvolumewriter.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#ifndef __RAWVOLUMEWRITER_H__
|
||||
#define __RAWVOLUMEWRITER_H__
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <modules/volume/rawvolume.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
template <typename VoxelType>
|
||||
class RawVolumeWriter {
|
||||
public:
|
||||
RawVolumeWriter(std::string path, size_t bufferSize = 1024);
|
||||
void setPath(const std::string& path);
|
||||
glm::ivec3 dimensions() const;
|
||||
void setDimensions(const glm::ivec3& dimensions);
|
||||
void write(const std::function<VoxelType(const glm::ivec3&)>& fn,
|
||||
const std::function<void(float t)>& onProgress = [&](float t) {});
|
||||
void write(const RawVolume<VoxelType>& volume);
|
||||
|
||||
size_t coordsToIndex(const glm::ivec3& coords) const;
|
||||
glm::ivec3 indexToCoords(size_t linear) const;
|
||||
private:
|
||||
glm::ivec3 _dimensions;
|
||||
std::string _path;
|
||||
size_t _bufferSize;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#include "rawvolumewriter.inl";
|
||||
|
||||
#endif
|
||||
80
modules/volume/rawvolumewriter.inl
Normal file
80
modules/volume/rawvolumewriter.inl
Normal file
@@ -0,0 +1,80 @@
|
||||
#include <fstream>
|
||||
#include <modules/volume/volumeutils.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
template <typename VoxelType>
|
||||
RawVolumeWriter<VoxelType>::RawVolumeWriter(std::string path, size_t bufferSize)
|
||||
: _path(path)
|
||||
, _bufferSize(bufferSize) {}
|
||||
|
||||
template <typename VoxelType>
|
||||
size_t RawVolumeWriter<VoxelType>::coordsToIndex(const glm::ivec3& cartesian) const {
|
||||
return volumeutils::coordsToIndex(cartesian, dimensions());
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
glm::ivec3 RawVolumeWriter<VoxelType>::indexToCoords(size_t linear) const {
|
||||
return volumeutils::indexToCoords(linear, dimensions());
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
void RawVolumeWriter<VoxelType>::setDimensions(const glm::ivec3& dimensions) {
|
||||
_dimensions = dimensions;
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
glm::ivec3 RawVolumeWriter<VoxelType>::dimensions() const {
|
||||
return _dimensions;
|
||||
}
|
||||
|
||||
|
||||
template <typename VoxelType>
|
||||
void RawVolumeWriter<VoxelType>::write(const std::function<VoxelType(const glm::ivec3&)>& fn,
|
||||
const std::function<void(float t)>& onProgress)
|
||||
{
|
||||
glm::ivec3 dims = dimensions();
|
||||
|
||||
size_t size = static_cast<size_t>(dims.x) *
|
||||
static_cast<size_t>(dims.y) *
|
||||
static_cast<size_t>(dims.z);
|
||||
|
||||
std::vector<VoxelType> buffer(_bufferSize);
|
||||
std::ofstream file(_path, std::ios::binary);
|
||||
|
||||
int nChunks = size / _bufferSize;
|
||||
if (size % _bufferSize > 0) {
|
||||
nChunks++;
|
||||
}
|
||||
|
||||
size_t i = 0;
|
||||
for (int c = 0; c < nChunks; c++) {
|
||||
size_t bufferPos = 0;
|
||||
size_t bufferSize = std::min(_bufferSize, size - i);
|
||||
for (bufferPos = 0; bufferPos < bufferSize; bufferPos++, i++) {
|
||||
buffer[bufferPos] = fn(indexToCoords(i));
|
||||
}
|
||||
file.write(reinterpret_cast<char*>(buffer.data()), bufferSize * sizeof(VoxelType));
|
||||
onProgress(static_cast<float>(c + 1) / nChunks);
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
void RawVolumeWriter<VoxelType>::write(const RawVolume<VoxelType>& volume) {
|
||||
glm::ivec3 dims = dimensions();
|
||||
ghoul_assert(dims == volume.dims());
|
||||
|
||||
const char* buffer = reinterpret_cast<char*>(volume.data());
|
||||
size_t length = static_cast<size_t>(dims.x) *
|
||||
static_cast<size_t>(dims.y) *
|
||||
static_cast<size_t>(dims.z) *
|
||||
sizeof(VoxelType);
|
||||
|
||||
std::ofstream file(_path, std::ios::binary);
|
||||
file.write(buffer, length);
|
||||
file.close();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
35
modules/volume/textureslicevolumereader.h
Normal file
35
modules/volume/textureslicevolumereader.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef __TEXTURESLICEVOLUMEREADER_H__
|
||||
#define __TEXTURESLICEVOLUMEREADER_H__
|
||||
|
||||
#include <vector>
|
||||
#include <ghoul/opengl/texture.h>
|
||||
#include <memory>
|
||||
#include <modules/volume/linearlrucache.h>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
template <typename Voxel>
|
||||
class TextureSliceVolumeReader {
|
||||
public:
|
||||
typedef Voxel VoxelType;
|
||||
TextureSliceVolumeReader(std::vector<std::string> paths, size_t sliceCacheMaxItems, size_t sliceCacheSize);
|
||||
VoxelType get(const glm::ivec3& coordinates) const;
|
||||
virtual glm::ivec3 dimensions() const;
|
||||
void setPaths(const std::vector<std::string> paths);
|
||||
void setCacheSize(size_t size);
|
||||
void initialize();
|
||||
private:
|
||||
ghoul::opengl::Texture& getSlice(int sliceIndex) const;
|
||||
std::vector<std::string> _paths;
|
||||
mutable LinearLruCache<std::shared_ptr<ghoul::opengl::Texture>> _cache;
|
||||
glm::ivec2 _sliceDimensions;
|
||||
bool _initialized;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#include "textureslicevolumereader.inl"
|
||||
|
||||
#endif // __TEXTURESLICEVOLUME_H__
|
||||
63
modules/volume/textureslicevolumereader.inl
Normal file
63
modules/volume/textureslicevolumereader.inl
Normal file
@@ -0,0 +1,63 @@
|
||||
#include <ghoul/io/texture/texturereader.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType TextureSliceVolumeReader<VoxelType>::get(const glm::ivec3& coordinates) const {
|
||||
ghoul::opengl::Texture& slice = getSlice(coordinates.z);
|
||||
return slice.texel<VoxelType>(coordinates.xy());
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
glm::ivec3 TextureSliceVolumeReader<VoxelType>::dimensions() const {
|
||||
return glm::ivec3(_sliceDimensions, _paths.size());
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
TextureSliceVolumeReader<VoxelType>::TextureSliceVolumeReader(std::vector<std::string> paths,
|
||||
size_t sliceCacheNIndices,
|
||||
size_t sliceCacheCapacity)
|
||||
: _initialized(false)
|
||||
, _paths(paths)
|
||||
, _cache(sliceCacheCapacity, sliceCacheNIndices) {}
|
||||
|
||||
template <typename VoxelType>
|
||||
void TextureSliceVolumeReader<VoxelType>::initialize() {
|
||||
ghoul_assert(_paths.size() > 0, "No paths to read slices from.");
|
||||
|
||||
std::shared_ptr<ghoul::opengl::Texture> firstSlice =
|
||||
ghoul::io::TextureReader::ref().loadTexture(_paths[0]);
|
||||
|
||||
_sliceDimensions = firstSlice->dimensions().xy();
|
||||
_initialized = true;
|
||||
_cache.set(0, firstSlice);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
void TextureSliceVolumeReader<VoxelType>::setPaths(const std::vector<std::string> paths) {
|
||||
_paths = paths;
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
void TextureSliceVolumeReader<VoxelType>::setCacheSize(size_t sliceCacheSize) {
|
||||
_cache.resize(sliceCacheSize);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
ghoul::opengl::Texture& TextureSliceVolumeReader<VoxelType>::getSlice(int sliceIndex) const {
|
||||
ghoul_assert(_initialized, "Volume is not initialized");
|
||||
ghoul_assert(sliceIndex >= 0 && sliceIndex < _paths.size(),
|
||||
"Slice index " + std::to_string(sliceIndex) + "is outside the range.");
|
||||
|
||||
if (!_cache.has(sliceIndex)) {
|
||||
std::shared_ptr<ghoul::opengl::Texture> texture =
|
||||
ghoul::io::TextureReader::ref().loadTexture(_paths[sliceIndex]);
|
||||
|
||||
glm::ivec2 dims = texture->dimensions().xy();
|
||||
ghoul_assert(dims == _sliceDimensions, "Slice dimensions do not agree.");
|
||||
_cache.set(sliceIndex, std::move(texture));
|
||||
}
|
||||
return *_cache.get(sliceIndex).get();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -40,8 +40,6 @@ VolumeModule::VolumeModule()
|
||||
void VolumeModule::internalInitialize() {
|
||||
auto fRenderable = FactoryManager::ref().factory<Renderable>();
|
||||
ghoul_assert(fRenderable, "No renderable factory existed");
|
||||
|
||||
//fRenderable->registerClass<RenderableVolumeGL>("RenderableVolumeGL");
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
20
modules/volume/volumesampler.h
Normal file
20
modules/volume/volumesampler.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef __VOLUMESAMPLER_H__
|
||||
#define __VOLUMESAMPLER_H__
|
||||
|
||||
namespace openspace {
|
||||
|
||||
template <typename VolumeType>
|
||||
class VolumeSampler {
|
||||
public:
|
||||
VolumeSampler(const VolumeType& volume, const glm::vec3& filterSize);
|
||||
typename VolumeType::VoxelType sample(const glm::vec3& position) const;
|
||||
private:
|
||||
glm::ivec3 _filterSize;
|
||||
const VolumeType* _volume;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#include "volumesampler.inl"
|
||||
|
||||
#endif
|
||||
57
modules/volume/volumesampler.inl
Normal file
57
modules/volume/volumesampler.inl
Normal file
@@ -0,0 +1,57 @@
|
||||
namespace openspace {
|
||||
|
||||
template <typename VolumeType>
|
||||
VolumeSampler<VolumeType>::VolumeSampler(const VolumeType& volume, const glm::vec3& filterSize) {
|
||||
// Only accept filter sizes of size 1, 3, 5, 7...
|
||||
// Round down to closest odd number.
|
||||
_filterSize = static_cast<glm::ivec3>((filterSize - glm::vec3(1.0)) * glm::vec3(0.5)) *
|
||||
glm::ivec3(2) + glm::ivec3(1);
|
||||
|
||||
_volume = &volume;
|
||||
}
|
||||
|
||||
template <typename VolumeType>
|
||||
typename VolumeType::VoxelType VolumeSampler<VolumeType>::sample(const glm::vec3& position) const {
|
||||
glm::ivec3 flooredPos = static_cast<glm::ivec3>(glm::floor(position));
|
||||
glm::vec3 t = glm::fract(position);
|
||||
|
||||
// t is now in interval [0, 1[ (never 1)
|
||||
glm::ivec3 minCoords = flooredPos - _filterSize / 2; // min coord to sample from
|
||||
glm::ivec3 maxCoords = minCoords + _filterSize; // max coords to sample from, including interpolation.
|
||||
glm::ivec3 clampCeiling = _volume->dimensions() - glm::ivec3(1);
|
||||
|
||||
VolumeType::VoxelType value;
|
||||
for (int z = minCoords.z; z <= maxCoords.z; z++) {
|
||||
for (int y = minCoords.y; y <= maxCoords.y; y++) {
|
||||
for (int x = minCoords.x; x <= maxCoords.x; x++) {
|
||||
glm::ivec3 sampleCoords = glm::ivec3(x, y, z);
|
||||
float filterCoefficient = 1.0;
|
||||
|
||||
if (x == minCoords.x) {
|
||||
filterCoefficient *= (1.0 - t.x);
|
||||
} else if (x == maxCoords.x) {
|
||||
filterCoefficient *= t.x;
|
||||
}
|
||||
if (y == minCoords.y) {
|
||||
filterCoefficient *= (1.0 - t.y);
|
||||
} else if (y == maxCoords.y) {
|
||||
filterCoefficient *= t.y;
|
||||
}
|
||||
if (z == minCoords.z) {
|
||||
filterCoefficient *= (1.0 - t.z);
|
||||
} else if (z == maxCoords.z) {
|
||||
filterCoefficient *= t.z;
|
||||
}
|
||||
|
||||
glm::ivec3 clampedCoords = glm::clamp(sampleCoords, glm::ivec3(0), clampCeiling);
|
||||
value += filterCoefficient * _volume->get(clampedCoords);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
value /= static_cast<float>(_filterSize.x * _filterSize.y * _filterSize.z);
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
31
modules/volume/volumeutils.cpp
Normal file
31
modules/volume/volumeutils.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#include "volumeutils.h"
|
||||
|
||||
namespace openspace {
|
||||
namespace volumeutils {
|
||||
|
||||
size_t coordsToIndex(const glm::vec3& coords, const glm::ivec3& dims) {
|
||||
size_t w = dims.x;
|
||||
size_t h = dims.y;
|
||||
size_t d = dims.z;
|
||||
|
||||
size_t x = coords.x;
|
||||
size_t y = coords.y;
|
||||
size_t z = coords.z;
|
||||
|
||||
return coords.z * (h * w) + coords.y * w + coords.x;
|
||||
}
|
||||
|
||||
glm::vec3 indexToCoords(size_t index, const glm::ivec3& dims) {
|
||||
size_t w = dims.x;
|
||||
size_t h = dims.y;
|
||||
size_t d = dims.z;
|
||||
|
||||
size_t x = index % w;
|
||||
size_t y = (index / w) % h;
|
||||
size_t z = index / w / h;
|
||||
|
||||
return glm::ivec3(x, y, z);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
39
modules/volume/volumeutils.h
Normal file
39
modules/volume/volumeutils.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014 - 2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __VOLUMEUTILS_H__
|
||||
#define __VOLUMEUTILS_H__
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
namespace openspace {
|
||||
namespace volumeutils {
|
||||
|
||||
size_t coordsToIndex(const glm::vec3& coords, const glm::ivec3& dimensions);
|
||||
glm::vec3 indexToCoords(size_t index, const glm::ivec3& dimensions);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // __VOLUMEUTILS__
|
||||
Reference in New Issue
Block a user