Add support for converting and rendering volumetric data in the cdf format. Replace DataConverter by a more general purpose TaskRunner.

Conflicts:
	modules/volume/CMakeLists.txt
	modules/volume/linearlrucache.h
	src/engine/openspaceengine.cpp
This commit is contained in:
Emil Axelsson
2016-10-24 10:26:00 +02:00
parent 99f265c1ed
commit cb7e81cf3d
53 changed files with 2161 additions and 122 deletions
+3
View File
@@ -28,6 +28,8 @@ set(HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/galaxymodule.h
${CMAKE_CURRENT_SOURCE_DIR}/rendering/galaxyraycaster.h
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablegalaxy.h
${CMAKE_CURRENT_SOURCE_DIR}/tasks/milkywayconversiontask.h
${CMAKE_CURRENT_SOURCE_DIR}/tasks/milkywaypointsconversiontask.h
)
source_group("Header Files" FILES ${HEADER_FILES})
@@ -35,6 +37,7 @@ set(SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/galaxymodule.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/galaxyraycaster.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablegalaxy.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tasks/milkywaypointsconversiontask.cpp
)
source_group("Source Files" FILES ${SOURCE_FILES})
+7
View File
@@ -27,6 +27,8 @@
#include <openspace/util/factorymanager.h>
#include <ghoul/misc/assert.h>
#include <modules/galaxy/rendering/renderablegalaxy.h>
#include <modules/galaxy/tasks/milkywayconversiontask.h>
#include <modules/galaxy/tasks/milkywaypointsconversiontask.h>
namespace openspace {
@@ -36,6 +38,11 @@ void GalaxyModule::internalInitialize() {
auto fRenderable = FactoryManager::ref().factory<Renderable>();
ghoul_assert(fRenderable, "No renderable factory existed");
fRenderable->registerClass<RenderableGalaxy>("RenderableGalaxy");
auto fTask = FactoryManager::ref().factory<Task>();
ghoul_assert(fRenderable, "No task factory existed");
fTask->registerClass<MilkywayConversionTask>("MilkywayPointsConversionTask");
fTask->registerClass<MilkywayPointsConversionTask>("MilkywayPointsConversionTask");
}
} // namespace openspace
@@ -0,0 +1,74 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2017 *
* *
* 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/milkyway/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);
}
}
}
@@ -0,0 +1,65 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2017 *
* *
* 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 __OPENSPACE_APP_DATACONVERTER___MILKYWAYCONVERSIONTASK___H__
#define __OPENSPACE_APP_DATACONVERTER___MILKYWAYCONVERSIONTASK___H__
#include <openspace/util/task.h>
#include <string>
#include <ghoul/glm.h>
#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 Task {
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;
};
} // namespace dataconverter
} // namespace openspace
#endif // __OPENSPACE_APP_DATACONVERTER___MILKYWAYCONVERSIONTASK___H__
@@ -0,0 +1,86 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2017 *
* *
* 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/galaxy/milkywaypointsconversiontask.h>
#include <modules/volume/textureslicevolumereader.h>
#include <modules/volume/rawvolumewriter.h>
#include <modules/volume/volumesampler.h>
#include <fstream>
#include <iostream>
namespace openspace {
namespace dataconverter {
MilkyWayPointsConversionTask::MilkyWayPointsConversionTask(
const std::string& inFilename,
const std::string& outFilename)
: _inFilename(inFilename)
, _outFilename(outFilename) {}
void MilkyWayPointsConversionTask::perform(const std::function<void(float)>& onProgress) {
std::ifstream in(_inFilename, std::ios::in);
std::ofstream out(_outFilename, std::ios::out | std::ios::binary);
std::string format;
int64_t nPoints;
in >> format >> nPoints;
size_t nFloats = nPoints * 7;
float* pointData = new float[nFloats];
float x, y, z, r, g, b, a;
for (size_t i = 0; i < nPoints; ++i) {
in >> x >> y >> z >> r >> g >> b >> a;
if (in.good()) {
pointData[i * 7 + 0] = x;
pointData[i * 7 + 1] = y;
pointData[i * 7 + 2] = z;
pointData[i * 7 + 3] = r;
pointData[i * 7 + 4] = g;
pointData[i * 7 + 5] = b;
pointData[i * 7 + 6] = a;
onProgress(static_cast<float>(i + 1) / nPoints);
} else {
std::cout << "Failed to convert point data.";
return;
}
}
out.write(reinterpret_cast<char*>(&nPoints), sizeof(int64_t));
out.write(reinterpret_cast<char*>(pointData), nFloats * sizeof(float));
in.close();
out.close();
}
}
}
@@ -0,0 +1,59 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2017 *
* *
* 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 __OPENSPACE_APP_DATACONVERTER___MILKYWAYPOINTSCONVERSIONTASK___H__
#define __OPENSPACE_APP_DATACONVERTER___MILKYWAYPOINTSCONVERSIONTASK___H__
#include <modules/galaxy/conversiontask.h>
#include <string>
#include <ghoul/glm.h>
#include <functional>
#include <modules/volume/textureslicevolumereader.h>
#include <modules/volume/rawvolumewriter.h>
namespace openspace {
namespace dataconverter {
/**
* Converts ascii based point data
* int64_t n
* (float x, float y, float z, float r, float g, float b) * n
* to a binary (floating point) representation with the same layout.
*/
class MilkyWayPointsConversionTask : public Task {
public:
MilkyWayPointsConversionTask(const std::string& inFilename,
const std::string& outFilename);
void perform(const std::function<void(float)>& onProgress) override;
private:
std::string _inFilename;
std::string _outFilename;
};
} // namespace dataconverter
} // namespace openspace
#endif // __OPENSPACE_APP_DATACONVERTER___MILKYWAYPOINTSCONVERSIONTASK___H__
+49
View File
@@ -0,0 +1,49 @@
#########################################################################################
# #
# 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(${OPENSPACE_CMAKE_EXT_DIR}/module_definition.cmake)
set(HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/kameleonvolumereader.h
${CMAKE_CURRENT_SOURCE_DIR}/kameleonvolumereader.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablekameleonvolume.h
${CMAKE_CURRENT_SOURCE_DIR}/rendering/kameleonvolumeraycaster.h
${CMAKE_CURRENT_SOURCE_DIR}/tasks/kameleondocumentationtask.h
${CMAKE_CURRENT_SOURCE_DIR}/tasks/kameleonmetadatatojsontask.h
)
source_group("Header Files" FILES ${HEADER_FILES})
set(SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablekameleonvolume.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/kameleonvolumeraycaster.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tasks/kameleondocumentationtask.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tasks/kameleonmetadatatojsontask.cpp
)
source_group("Source Files" FILES ${SOURCE_FILES})
create_new_module(
"KameleonVolume"
kameleonvolume_module
${HEADER_FILES} ${SOURCE_FILES}
)
+6
View File
@@ -0,0 +1,6 @@
set (DEFAULT_MODULE ON)
set (OPENSPACE_DEPENDENCIES
kameleon
volume
)
@@ -0,0 +1,58 @@
/*****************************************************************************************
* *
* 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/kameleonvolume/kameleonvolumemodule.h>
#include <openspace/util/factorymanager.h>
#include <ghoul/misc/assert.h>
#include <vector>
#include <modules/kameleonvolume/rendering/renderablekameleonvolume.h>
#include <modules/kameleonvolume/tasks/kameleonmetadatatojsontask.h>
#include <modules/kameleonvolume/tasks/kameleondocumentationtask.h>
namespace openspace {
KameleonVolumeModule::KameleonVolumeModule() : OpenSpaceModule("KameleonVolume") {}
void KameleonVolumeModule::internalInitialize() {
auto fRenderable = FactoryManager::ref().factory<Renderable>();
ghoul_assert(fRenderable, "No renderable factory existed");
fRenderable->registerClass<RenderableKameleonVolume>("RenderableKameleonVolume");
auto fTask = FactoryManager::ref().factory<Task>();
ghoul_assert(fTask, "No task factory existed");
fTask->registerClass<KameleonMetadataToJsonTask>("KameleonMetadataToJsonTask");
fTask->registerClass<KameleonDocumentationTask>("KameleonDocumentationTask");
}
std::vector<Documentation> KameleonVolumeModule::documentations() const
{
return std::vector<Documentation>{KameleonMetadataToJsonTask::documentation()};
}
} // namespace openspace
@@ -0,0 +1,41 @@
/*****************************************************************************************
* *
* 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 __KAMELEONVOLUMEMODULE_H__
#define __KAMELEONVOLUMEMODULE_H__
#include <openspace/util/openspacemodule.h>
namespace openspace {
class KameleonVolumeModule : public OpenSpaceModule {
public:
KameleonVolumeModule();
void internalInitialize() override;
std::vector<Documentation> KameleonVolumeModule::documentations() const override;
};
} // namespace openspace
#endif // __KAMELEONVOLUMEMODULE_H__
@@ -0,0 +1,188 @@
/*****************************************************************************************
* *
* 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/kameleonvolume/kameleonvolumereader.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/filesystem/filesystem.h>
//#include <openspace/util/distanceconstants.h>
namespace {
const std::string _loggerCat = "KameleonVolumeReader";
}
namespace openspace {
KameleonVolumeReader::KameleonVolumeReader(const std::string& path)
: _path(path)
{
if (!FileSys.fileExists(path)) {
LERROR(_path << "does not exist");
return;
}
long status = _kameleon.open(_path);
if (status != ccmc::FileReader::OK) {
LERROR("Failed to open file " << _path << " with kameleon");
return;
}
_model = _kameleon.model;
_interpolator = std::unique_ptr<ccmc::Interpolator>(_model->createNewInterpolator());
}
std::unique_ptr<RawVolume<float>> KameleonVolumeReader::readFloatVolume(
const glm::uvec3 & dimensions,
const std::string & variable,
const glm::vec3 & lowerBound,
const glm::vec3 & upperBound) const
{
auto volume = std::make_unique<RawVolume<float>>(dimensions);
glm::vec3 dims = volume->dimensions();
glm::vec3 diff = upperBound - lowerBound;
_model->loadVariable(variable);
float* data = volume->data();
for (size_t index = 0; index < volume->nCells(); index++) {
glm::vec3 coords = volume->indexToCoords(index);
glm::vec3 coordsZeroToOne = coords / dims;
glm::vec3 volumeCoords = lowerBound + diff * coordsZeroToOne;
data[index] = _interpolator->interpolate(
variable,
static_cast<float>(volumeCoords[0]),
static_cast<float>(volumeCoords[1]),
static_cast<float>(volumeCoords[2]));
}
return volume;
}
std::vector<std::string> KameleonVolumeReader::gridVariableNames() const {
// get the grid system string
std::string gridSystem = _model->getGlobalAttribute("grid_system_1").getAttributeString();
// remove leading and trailing brackets
gridSystem = gridSystem.substr(1, gridSystem.length() - 2);
// remove all whitespaces
gridSystem.erase(remove_if(gridSystem.begin(), gridSystem.end(), isspace), gridSystem.end());
// replace all comma signs with whitespaces
std::replace(gridSystem.begin(), gridSystem.end(), ',', ' ');
// tokenize
std::istringstream iss(gridSystem);
std::vector<std::string> tokens{ std::istream_iterator<std::string>{iss},std::istream_iterator<std::string>{} };
// validate
if (tokens.size() != 3) {
return std::vector<std::string>();
}
std::string x = tokens.at(0);
std::string y = tokens.at(1);
std::string z = tokens.at(2);
std::transform(x.begin(), x.end(), x.begin(), ::tolower);
std::transform(y.begin(), y.end(), y.begin(), ::tolower);
std::transform(z.begin(), z.end(), z.begin(), ::tolower);
return std::vector<std::string>{x, y, z};
}
std::vector<std::string> KameleonVolumeReader::variableNames() const {
std::vector<std::string> variableNames;
int nVariables = _model->getNumberOfVariables();
for (int i = 0; i < nVariables; i++) {
variableNames.push_back(_model->getVariableName(i));
}
return variableNames;
}
std::vector<std::string> KameleonVolumeReader::variableAttributeNames() const {
return _model->getVariableAttributeNames();
}
std::vector<std::string> KameleonVolumeReader::globalAttributeNames() const {
std::vector<std::string> attributeNames;
int nAttributes = _model->getNumberOfGlobalAttributes();
for (int i = 0; i < nAttributes; i++) {
attributeNames.push_back(_model->getGlobalAttributeName(i));
}
return attributeNames;
}
void KameleonVolumeReader::addAttributeToDictionary(ghoul::Dictionary& dictionary, const std::string& key, ccmc::Attribute& attr) {
ccmc::Attribute::AttributeType type = attr.getAttributeType();
if (type == ccmc::Attribute::AttributeType::FLOAT) {
dictionary.setValue<float>(key, attr.getAttributeFloat());
}
else if (type == ccmc::Attribute::AttributeType::INT) {
dictionary.setValue<int>(key, attr.getAttributeInt());
}
else if (type == ccmc::Attribute::AttributeType::STRING) {
dictionary.setValue<std::string>(key, attr.getAttributeString());
}
}
ghoul::Dictionary KameleonVolumeReader::readMetaData() const {
ghoul::Dictionary globalAttributesDictionary;
for (const std::string& attributeName : globalAttributeNames()) {
ccmc::Attribute attribute = _model->getGlobalAttribute(attributeName);
addAttributeToDictionary(globalAttributesDictionary, attributeName, attribute);
}
ghoul::Dictionary variableDictionary;
std::vector<std::string> varAttrNames = variableAttributeNames();
for (const std::string& variableName : variableNames()) {
ghoul::Dictionary variableAttributesDictionary;
for (const std::string& attributeName : varAttrNames) {
ccmc::Attribute attribute = _model->getVariableAttribute(variableName, attributeName);
addAttributeToDictionary(variableAttributesDictionary, attributeName, attribute);
}
variableDictionary.setValue(variableName, variableAttributesDictionary);
}
ghoul::Dictionary metaData;
metaData.setValue("globalAttributes", globalAttributesDictionary);
metaData.setValue("variableAttributes", variableDictionary);
return metaData;
}
float KameleonVolumeReader::minValue(const std::string & variable) const {
return _model->getVariableAttribute(variable, "actual_min").getAttributeFloat();
}
float KameleonVolumeReader::maxValue(const std::string & variable) const {
return _model->getVariableAttribute(variable, "actual_max").getAttributeFloat();
}
}
@@ -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. *
****************************************************************************************/
#ifndef __KAMELEONVOLUMEREADER_H__
#define __KAMELEONVOLUMEREADER_H__
#include <string>
#include <memory>
#include <modules/volume/rawvolume.h>
#include <ghoul/misc/dictionary.h>
#include <ccmc/Kameleon.h>
#include <ccmc/Model.h>
#include <ccmc/Interpolator.h>
#include <ccmc/BATSRUS.h>
#include <ccmc/ENLIL.h>
#include <ccmc/CCMCTime.h>
#include <ccmc/Attribute.h>
namespace openspace {
class KameleonVolumeReader {
public:
KameleonVolumeReader(const std::string& path);
//KameleonMetaData readMetaData();
std::unique_ptr<RawVolume<float>> readFloatVolume(
const glm::uvec3& dimensions,
const std::string& variable,
const glm::vec3& lowerBound,
const glm::vec3& upperBound) const;
ghoul::Dictionary readMetaData() const;
float minValue(const std::string& variable) const;
float maxValue(const std::string& variable) const;
std::vector<std::string> gridVariableNames() const;
std::vector<std::string> gridUnits() const;
std::vector<std::string> variableNames() const;
std::vector<std::string> variableAttributeNames() const;
std::vector<std::string> globalAttributeNames() const;
private:
static void addAttributeToDictionary(ghoul::Dictionary& dictionary, const std::string& key, ccmc::Attribute& attr);
std::string _path;
ccmc::Kameleon _kameleon;
ccmc::Model* _model;
std::unique_ptr<ccmc::Interpolator> _interpolator;
};
}
#include <modules/kameleonvolume/kameleonvolumereader.inl>
#endif
@@ -0,0 +1,52 @@
/*****************************************************************************************
* *
* 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. *
****************************************************************************************/
namespace openspace {
//KameleonMetaData KameleonVolumeReader::getMetaData() {
/*
using GridUnits = std::tuple<std::string, std::string, std::string>;
GridUnits units = _kameleonWrapper.getGridUnits();
std::string unit0 = std::get<0>(units);
std::string unit1 = std::get<1>(units);
std::string unit2 = std::get<2>(units);
glm::vec3 scaling;
if (unit0 == 'R' && unit1 == 'R' && unit2 == 'R') {
scaling.x = scaling.y = scaling.z = openspace::distanceconstants::EarthRadius;
}
if (unit0 == '')
VolumeMetaData metaData(VolumeMetaData::GridType::Cartesian, scaling );
*/
//}
}
@@ -0,0 +1,142 @@
/*****************************************************************************************
* *
* 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/kameleonvolume/rendering/kameleonvolumeraycaster.h>
#include <glm/glm.hpp>
#include <ghoul/opengl/ghoul_gl.h>
#include <sstream>
#include <ghoul/opengl/programobject.h>
#include <openspace/util/powerscaledcoordinate.h>
#include <openspace/util/updatestructures.h>
#include <openspace/rendering/renderable.h>
#include <modules/kameleonvolume/rendering/renderablekameleonvolume.h>
namespace {
const std::string GlslRaycastPath = "${MODULES}/kameleonvolume/shaders/raycast.glsl";
const std::string GlslHelperPath = "${MODULES}/kameleonvolume/shaders/helper.glsl";
const std::string GlslBoundsVsPath = "${MODULES}/kameleonvolume/shaders/boundsvs.glsl";
const std::string GlslBoundsFsPath = "${MODULES}/kameleonvolume/shaders/boundsfs.glsl";
}
namespace openspace {
KameleonVolumeRaycaster::KameleonVolumeRaycaster(
std::shared_ptr<ghoul::opengl::Texture> texture,
std::shared_ptr<TransferFunction> transferFunction)
: _volumeTexture(texture)
, _transferFunction(transferFunction)
, _boundingBox(glm::vec3(1.0)) {}
KameleonVolumeRaycaster::~KameleonVolumeRaycaster() {}
void KameleonVolumeRaycaster::initialize() {
_boundingBox.initialize();
}
void KameleonVolumeRaycaster::deinitialize() {
}
void KameleonVolumeRaycaster::renderEntryPoints(const RenderData& data, ghoul::opengl::ProgramObject& program) {
//program.setUniform("modelTransform", _modelTransform);
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 KameleonVolumeRaycaster::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 KameleonVolumeRaycaster::preRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) {
std::string stepSizeUniformName = "maxStepSize" + std::to_string(data.id);
program.setUniform(stepSizeUniformName, _stepSize);
std::string id = std::to_string(data.id);
_tfUnit = std::make_unique<ghoul::opengl::TextureUnit>();
_tfUnit->activate();
_transferFunction->getTexture().bind();
program.setUniform("transferFunction_" + id, _tfUnit->unitNumber());
_textureUnit = std::make_unique<ghoul::opengl::TextureUnit>();
_textureUnit->activate();
_volumeTexture->bind();
program.setUniform("volumeTexture_" + id, _textureUnit->unitNumber());
program.setUniform("gridType_" + id, static_cast<int>(_gridType));
}
void KameleonVolumeRaycaster::postRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) {
// For example: release texture units
_textureUnit = nullptr;
_tfUnit = nullptr;
}
std::string KameleonVolumeRaycaster::getBoundsVsPath() const {
return GlslBoundsVsPath;
}
std::string KameleonVolumeRaycaster::getBoundsFsPath() const {
return GlslBoundsFsPath;
}
std::string KameleonVolumeRaycaster::getRaycastPath() const {
return GlslRaycastPath;
}
std::string KameleonVolumeRaycaster::getHelperPath() const {
return GlslHelperPath; // no helper file
}
void KameleonVolumeRaycaster::setStepSize(float stepSize) {
_stepSize = stepSize;
}
void KameleonVolumeRaycaster::setGridType(VolumeGridType gridType)
{
_gridType = gridType;
}
}
@@ -0,0 +1,89 @@
/*****************************************************************************************
* *
* 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 __KAMELEONVOLUMERAYCASTER_H__
#define __KAMELEONVOLUMERAYCASTER_H__
#include <string>
#include <vector>
#include <ghoul/glm.h>
#include <ghoul/opengl/texture.h>
#include <openspace/rendering/volumeraycaster.h>
#include <openspace/util/boxgeometry.h>
#include <openspace/util/blockplaneintersectiongeometry.h>
#include <openspace/rendering/transferfunction.h>
#include <modules/volume/volumegridtype.h>
namespace ghoul {
namespace opengl {
class Texture;
class ProgramObject;
}
}
namespace openspace {
class RenderData;
class RaycastData;
class KameleonVolumeRaycaster : public VolumeRaycaster {
public:
KameleonVolumeRaycaster(
std::shared_ptr<ghoul::opengl::Texture> texture,
std::shared_ptr<TransferFunction> transferFunction);
virtual ~KameleonVolumeRaycaster();
void initialize();
void deinitialize();
void renderEntryPoints(const RenderData& data, ghoul::opengl::ProgramObject& program) override;
void renderExitPoints(const RenderData& data, ghoul::opengl::ProgramObject& program) override;
void preRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) override;
void postRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) override;
std::string getBoundsVsPath() const override;
std::string getBoundsFsPath() const override;
std::string getRaycastPath() const override;
std::string getHelperPath() const override;
void setStepSize(float stepSize);
void setGridType(VolumeGridType gridType);
private:
std::shared_ptr<ghoul::opengl::Texture> _volumeTexture;
std::shared_ptr<TransferFunction> _transferFunction;
BoxGeometry _boundingBox;
VolumeGridType _gridType;
std::unique_ptr<ghoul::opengl::TextureUnit> _tfUnit;
std::unique_ptr<ghoul::opengl::TextureUnit> _textureUnit;
float _stepSize;
};
} // openspace
#endif // __KAMELEONVOLUMERAYCASTER_H__
@@ -0,0 +1,344 @@
/*****************************************************************************************
* *
* 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/kameleonvolume/rendering/renderablekameleonvolume.h>
#include <modules/kameleonvolume/kameleonvolumereader.h>
#include <openspace/rendering/renderable.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/rendering/raycastermanager.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <ghoul/opengl/ghoul_gl.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/filesystem/cachemanager.h>
#include <ghoul/logging/logmanager.h>
#include <modules/volume/rawvolumereader.h>
#include <modules/volume/rawvolumewriter.h>
#include <modules/volume/rawvolume.h>
namespace {
const std::string _loggerCat = "RenderableKameleonVolume";
}
namespace openspace {
RenderableKameleonVolume::RenderableKameleonVolume(const ghoul::Dictionary& dictionary)
: Renderable(dictionary)
, _dimensions("dimensions", "Dimensions")
, _variable("variable", "Variable")
, _lowerDomainBound("lowerDomainBound", "Lower Domain Bound")
, _upperDomainBound("upperDomainBound", "Upper Domain Bound")
, _autoDomainBounds(false)
, _lowerValueBound("lowerValueBound", "Lower Value Bound", 0.0, 0.0, 1)
, _upperValueBound("upperValueBound", "Upper Value Bound", 1, 0.01, 1)
, _autoValueBounds(false)
, _gridType("gridType", "Grid Type", properties::OptionProperty::DisplayType::DROPDOWN)
, _autoGridType(false)
, _stepSize("stepSize", "Step Size", 0.02, 0.01, 1)
, _sourcePath("sourcePath", "Source Path")
, _transferFunctionPath("transferFunctionPath", "Transfer Function Path")
, _raycaster(nullptr)
, _transferFunction(nullptr)
, _cache("cache", "Cache") {
glm::vec3 dimensions;
if (dictionary.getValue("Dimensions", dimensions)) {
_dimensions = dimensions;
} else {
LWARNING("No dimensions specified for volumetric data, falling back to 32^3");
_dimensions = glm::uvec3(32, 32, 32);
}
float stepSize;
if (dictionary.getValue("StepSize", stepSize)) {
_stepSize = stepSize;
}
std::string transferFunctionPath;
if (dictionary.getValue("TransferFunction", transferFunctionPath)) {
_transferFunctionPath = transferFunctionPath;
_transferFunction = std::make_shared<TransferFunction>(absPath(transferFunctionPath));
}
std::string sourcePath;
if (dictionary.getValue("Source", sourcePath)) {
_sourcePath = absPath(sourcePath);
}
std::string variable;
if (dictionary.getValue("Variable", variable)) {
_variable = variable;
}
glm::vec3 lowerDomainBound;
if (dictionary.getValue("LowerDomainBound", lowerDomainBound)) {
_lowerDomainBound = lowerDomainBound;
}
else {
_autoDomainBounds = true;
}
glm::vec3 upperDomainBound;
if (dictionary.getValue("UpperDomainBound", upperDomainBound)) {
_upperDomainBound = upperDomainBound;
}
else {
_autoDomainBounds = true;
}
float lowerValueBound;
if (dictionary.getValue("LowerValueBound", lowerValueBound)) {
_lowerValueBound = lowerValueBound;
}
else {
_autoValueBounds = true;
}
float upperValueBound;
if (dictionary.getValue("UpperValueBound", upperValueBound)) {
_upperValueBound = upperValueBound;
}
else {
_autoValueBounds = true;
}
bool cache;
if (dictionary.getValue("Cache", cache)) {
_cache = cache;
}
_gridType.addOption(static_cast<int>(VolumeGridType::Cartesian), "Cartesian grid");
_gridType.addOption(static_cast<int>(VolumeGridType::Spherical), "Spherical grid");
_gridType.setValue(static_cast<int>(VolumeGridType::Cartesian));
std::string gridType;
if (dictionary.getValue("GridType", gridType)) {
if (gridType == "Spherical") {
_gridType.setValue(static_cast<int>(VolumeGridType::Spherical));
} else {
_autoGridType = true;
}
}
// TODO: read transformation: position/rotation/scale from dictionary.
}
RenderableKameleonVolume::~RenderableKameleonVolume() {}
bool RenderableKameleonVolume::initialize() {
load();
_volumeTexture->uploadTexture();
_transferFunction->update();
_raycaster = std::make_unique<KameleonVolumeRaycaster>(_volumeTexture, _transferFunction);
_raycaster->setStepSize(_stepSize);
_gridType.onChange([this] {
_raycaster->setStepSize(_stepSize);
});
_raycaster->setGridType(static_cast<VolumeGridType>(_gridType.value()));
_gridType.onChange([this] {
_raycaster->setGridType(static_cast<VolumeGridType>(_gridType.value()));
});
_raycaster->initialize();
OsEng.renderEngine().raycasterManager().attachRaycaster(*_raycaster.get());
std::function<void(bool)> onChange = [&](bool enabled) {
if (enabled) {
OsEng.renderEngine().raycasterManager().attachRaycaster(*_raycaster.get());
}
else {
OsEng.renderEngine().raycasterManager().detachRaycaster(*_raycaster.get());
}
};
onEnabledChange(onChange);
addProperty(_dimensions);
addProperty(_stepSize);
addProperty(_transferFunctionPath);
addProperty(_sourcePath);
addProperty(_variable);
addProperty(_lowerDomainBound);
addProperty(_upperDomainBound);
addProperty(_lowerValueBound);
addProperty(_upperValueBound);
addProperty(_gridType);
addProperty(_cache);
return true;
}
bool RenderableKameleonVolume::cachingEnabled() {
return _cache;
}
void RenderableKameleonVolume::load() {
if (!FileSys.fileExists(_sourcePath)) {
LERROR("File " << _sourcePath << " does not exist.");
return;
}
if (!cachingEnabled()) {
loadFromPath(_sourcePath);
return;
}
ghoul::filesystem::File sourceFile(_sourcePath);
std::string cachePath = FileSys.cacheManager()->cachedFilename(
sourceFile.baseName(),
cacheSuffix(),
ghoul::filesystem::CacheManager::Persistent::Yes
);
if (FileSys.fileExists(cachePath)) {
loadRaw(cachePath);
} else {
loadFromPath(_sourcePath);
storeRaw(cachePath);
}
}
std::string RenderableKameleonVolume::cacheSuffix() {
glm::vec3 dims = _dimensions.value();
return "." + _variable.value() +
"." + std::to_string(dims[0]) +
"x" + std::to_string(dims[1]) +
"x" + std::to_string(dims[2]);
}
void RenderableKameleonVolume::loadFromPath(const std::string& path) {
ghoul::filesystem::File file(path);
std::string extension = file.fileExtension();
std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
if (extension == "cdf") {
loadCdf(path);
} else {
loadRaw(path);
}
}
void RenderableKameleonVolume::loadRaw(const std::string& path) {
RawVolumeReader<float> reader(path, _dimensions);
_rawVolume = reader.read();
updateTextureFromVolume();
}
void RenderableKameleonVolume::loadCdf(const std::string& path) {
KameleonVolumeReader reader(path);
if (_autoValueBounds) {
_lowerValueBound = reader.minValue(_variable);
_upperValueBound = reader.maxValue(_variable);
}
std::vector<std::string> variables = reader.gridVariableNames();
if (variables.size() == 3 && _autoDomainBounds) {
_lowerDomainBound = glm::vec3(
reader.minValue(variables[0]),
reader.minValue(variables[1]),
reader.minValue(variables[2]));
_upperDomainBound = glm::vec3(
reader.maxValue(variables[0]),
reader.maxValue(variables[1]),
reader.maxValue(variables[2]));
}
if (variables.size() == 3 && _autoGridType) {
if (variables[0] == "r" && variables[0] == "theta" && variables[0] == "phi") {
_gridType.setValue(static_cast<int>(VolumeGridType::Spherical));
}
else {
_gridType.setValue(static_cast<int>(VolumeGridType::Cartesian));
}
}
ghoul::Dictionary dict = reader.readMetaData();
_rawVolume = reader.readFloatVolume(_dimensions, _variable, _lowerDomainBound, _upperDomainBound);
updateTextureFromVolume();
}
void RenderableKameleonVolume::updateTextureFromVolume() {
_normalizedVolume = std::make_unique<RawVolume<GLfloat>>(_dimensions);
float* in = _rawVolume->data();
GLfloat* out = _normalizedVolume->data();
float min = _lowerValueBound;
float diff = _upperValueBound - _lowerValueBound;
for (size_t i = 0; i < _normalizedVolume->nCells(); i++) {
out[i] = glm::clamp((in[i] - min) / diff, 0.0f, 1.0f);
}
_volumeTexture = std::make_shared<ghoul::opengl::Texture>(
_dimensions,
ghoul::opengl::Texture::Format::Red,
GL_RED,
GL_FLOAT,
ghoul::opengl::Texture::FilterMode::Linear,
ghoul::opengl::Texture::WrappingMode::Repeat);
void* data = reinterpret_cast<void*>(_normalizedVolume->data());
_volumeTexture->setPixelData(data, ghoul::opengl::Texture::TakeOwnership::No);
}
void RenderableKameleonVolume::storeRaw(const std::string& path) {
RawVolumeWriter<float> writer(path);
writer.write(*_rawVolume);
}
bool RenderableKameleonVolume::deinitialize() {
if (_raycaster) {
OsEng.renderEngine().raycasterManager().detachRaycaster(*_raycaster.get());
_raycaster = nullptr;
}
return true;
}
bool RenderableKameleonVolume::isReady() const {
return true;
}
void RenderableKameleonVolume::update(const UpdateData& data) {
if (_raycaster) {
_raycaster->setStepSize(_stepSize);
}
}
void RenderableKameleonVolume::render(const RenderData& data, RendererTasks& tasks) {
RaycasterTask task{ _raycaster.get(), data };
tasks.raycasterTasks.push_back(task);
}
}
@@ -0,0 +1,95 @@
/*****************************************************************************************
* *
* 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 __RENDERABLEKAMELEONVOLUME_H__
#define __RENDERABLEKAMELEONVOLUME_H__
#include <openspace/properties/vectorproperty.h>
#include <openspace/properties/optionproperty.h>
#include <openspace/util/boxgeometry.h>
#include <openspace/util/blockplaneintersectiongeometry.h>
#include <openspace/rendering/renderable.h>
#include <openspace/rendering/transferfunction.h>
#include <modules/kameleon/include/kameleonwrapper.h>
#include <modules/volume/rawvolume.h>
#include <modules/kameleonvolume/rendering/kameleonvolumeraycaster.h>
namespace openspace {
struct RenderData;
class RenderableKameleonVolume : public Renderable {
public:
RenderableKameleonVolume(const ghoul::Dictionary& dictionary);
~RenderableKameleonVolume();
bool initialize() override;
bool deinitialize() override;
bool isReady() const override;
void render(const RenderData& data, RendererTasks& tasks) override;
void update(const UpdateData& data) override;
bool cachingEnabled();
private:
void load();
void loadFromPath(const std::string& path);
void loadRaw(const std::string& path);
void loadCdf(const std::string& path);
void storeRaw(const std::string& path);
std::string cacheSuffix();
void updateTextureFromVolume();
properties::UVec3Property _dimensions;
properties::StringProperty _variable;
properties::Vec3Property _lowerDomainBound;
properties::Vec3Property _upperDomainBound;
bool _autoDomainBounds;
properties::FloatProperty _lowerValueBound;
properties::FloatProperty _upperValueBound;
bool _autoValueBounds;
properties::OptionProperty _gridType;
bool _autoGridType;
properties::FloatProperty _stepSize;
properties::StringProperty _sourcePath;
properties::StringProperty _transferFunctionPath;
properties::BoolProperty _cache;
std::unique_ptr<RawVolume<float>> _rawVolume;
std::unique_ptr<RawVolume<GLfloat>> _normalizedVolume;
std::unique_ptr<KameleonVolumeRaycaster> _raycaster;
std::shared_ptr<ghoul::opengl::Texture> _volumeTexture;
std::shared_ptr<TransferFunction> _transferFunction;
};
}
#endif // __RENDERABLETOYVOLUME_H__
@@ -0,0 +1,40 @@
/*****************************************************************************************
* *
* 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. *
****************************************************************************************/
in vec3 vPosition;
in vec4 worldPosition;
#include "PowerScaling/powerScaling_fs.hglsl"
#include "fragment.glsl"
Fragment getFragment() {
vec4 fragColor = vec4(vPosition+0.5, 1.0);
vec4 position = worldPosition;
float depth = pscDepth(position);
Fragment frag;
frag.color = fragColor;
frag.depth = depth;
return frag;
}
@@ -0,0 +1,46 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 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. *
****************************************************************************************/
#version __CONTEXT__
layout(location = 0) in vec4 vertPosition;
uniform mat4 viewProjection;
out vec3 vPosition;
out vec4 worldPosition;
#include "PowerScaling/powerScaling_vs.hglsl"
void main() {
vPosition = vertPosition.xyz;
worldPosition = vertPosition;
vec4 position = pscTransform(worldPosition, mat4(1.0));
// project the position to view space
gl_Position = viewProjection * position;
gl_Position.z = 1.0;
}
@@ -0,0 +1,19 @@
#define KAMELEON_PI 3.14159265358979323846 /* pi */
#define KAMELEON_SQRT1_3 0.57735026919 /* 1/sqrt(3) */
vec3 kameleon_cartesianToSpherical(vec3 _cartesian) {
// Put cartesian in [-1..1] range first
vec3 cartesian = vec3(-1.0,-1.0,-1.0) + _cartesian * 2.0f;
float r = length(cartesian);
float theta, phi;
if (r == 0.0) {
theta = phi = 0.0;
} else {
theta = acos(cartesian.z/r) / KAMELEON_PI;
phi = (KAMELEON_PI + atan(cartesian.y, cartesian.x)) / (2.0*KAMELEON_PI );
}
r *= KAMELEON_SQRT1_3;
return vec3(r, theta, phi);
}
@@ -0,0 +1,62 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 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. *
****************************************************************************************/
uniform float maxStepSize#{id} = 0.02;
uniform sampler3D volumeTexture_#{id};
uniform sampler1D transferFunction_#{id};
uniform int gridType_#{id} = 0;
void sample#{id}(vec3 samplePos,
vec3 dir,
inout vec3 accumulatedColor,
inout vec3 accumulatedAlpha,
inout float stepSize) {
vec3 transformedPos = samplePos;
if (gridType_#{id} == 1) {
transformedPos = kameleon_cartesianToSpherical(samplePos);
}
float val = texture(volumeTexture_#{id}, transformedPos).r;
vec4 color = texture(transferFunction_#{id}, val);
vec3 backColor = color.rgb;
vec3 backAlpha = color.aaa;
backColor *= stepSize;
backAlpha *= stepSize;
backColor = clamp(backColor, 0.0, 1.0);
backAlpha = clamp(backAlpha, 0.0, 1.0);
vec3 oneMinusFrontAlpha = vec3(1.0) - accumulatedAlpha;
accumulatedColor += oneMinusFrontAlpha * backColor;
accumulatedAlpha += oneMinusFrontAlpha * backAlpha;
stepSize = maxStepSize#{id};
}
float stepSize#{id}(vec3 samplePos, vec3 dir) {
return maxStepSize#{id};
}
@@ -0,0 +1,162 @@
/*****************************************************************************************
* *
* 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/kameleonvolume/tasks/kameleondocumentationtask.h>
#include <modules/kameleonvolume/kameleonvolumereader.h>
#include <openspace/openspace.h>
#include <openspace/documentation/verifier.h>
#include <ghoul/misc/dictionaryjsonformatter.h>
#include <ghoul/filesystem/filesystem.h>
#include <string>
#include <fstream>
namespace {
const std::string KeyInput = "Input";
const std::string KeyOutput = "Output";
const std::string MainTemplateFilename = "${OPENSPACE_DATA}/web/kameleondocumentation/main.hbs";
const std::string HandlebarsFilename = "${OPENSPACE_DATA}/web/common/handlebars-v4.0.5.js";
const std::string JsFilename = "${OPENSPACE_DATA}/web/kameleondocumentation/script.js";
const std::string BootstrapFilename = "${OPENSPACE_DATA}/web/common/bootstrap.min.css";
const std::string CssFilename = "${OPENSPACE_DATA}/web/common/style.css";
}
namespace openspace {
KameleonDocumentationTask::KameleonDocumentationTask(const ghoul::Dictionary& dictionary) {
openspace::documentation::testSpecificationAndThrow(
documentation(),
dictionary,
"KameleonDocumentationTask"
);
_inputPath = absPath(dictionary.value<std::string>(KeyInput));
_outputPath = absPath(dictionary.value<std::string>(KeyOutput));
}
std::string KameleonDocumentationTask::description() {
return "Extract metadata from cdf-file " + _inputPath + " and output html documentation to " + _outputPath;
}
void KameleonDocumentationTask::perform(const Task::ProgressCallback & progressCallback) {
KameleonVolumeReader reader(_inputPath);
ghoul::Dictionary kameleonDictionary = reader.readMetaData();
progressCallback(0.33f);
ghoul::DictionaryJsonFormatter formatter;
ghoul::Dictionary dictionary;
dictionary.setValue<ghoul::Dictionary>("kameleon", kameleonDictionary);
dictionary.setValue<std::string>("version", std::to_string(OPENSPACE_VERSION_MAJOR) + "." +
std::to_string(OPENSPACE_VERSION_MINOR) + "." +
std::to_string(OPENSPACE_VERSION_PATCH));
dictionary.setValue<std::string>("input", _inputPath);
std::string json = formatter.format(dictionary);
progressCallback(0.66f);
std::ifstream handlebarsInput(absPath(HandlebarsFilename));
std::ifstream jsInput(absPath(JsFilename));
std::string jsContent;
std::back_insert_iterator<std::string> jsInserter(jsContent);
std::copy(std::istreambuf_iterator<char>{handlebarsInput}, std::istreambuf_iterator<char>(), jsInserter);
std::copy(std::istreambuf_iterator<char>{jsInput}, std::istreambuf_iterator<char>(), jsInserter);
std::ifstream bootstrapInput(absPath(BootstrapFilename));
std::ifstream cssInput(absPath(CssFilename));
std::string cssContent;
std::back_insert_iterator<std::string> cssInserter(cssContent);
std::copy(std::istreambuf_iterator<char>{bootstrapInput}, std::istreambuf_iterator<char>(), cssInserter);
std::copy(std::istreambuf_iterator<char>{cssInput}, std::istreambuf_iterator<char>(), cssInserter);
std::ifstream mainTemplateInput(absPath(MainTemplateFilename));
std::string mainTemplateContent{ std::istreambuf_iterator<char>{mainTemplateInput},
std::istreambuf_iterator<char>{}};
std::ofstream file;
file.exceptions(~std::ofstream::goodbit);
file.open(_outputPath);
std::stringstream html;
html << "<!DOCTYPE html>\n"
<< "<html>\n"
<< "\t<head>\n"
<< "\t\t<script id=\"mainTemplate\" type=\"text/x-handlebars-template\">\n"
<< mainTemplateContent << "\n"
<< "\t\t</script>\n"
<< "\t\t<script id=\"data\" type=\"application/json\">\n"
<< json << "\n"
<< "\t</script>\n"
<< "\t<script>\n"
<< jsContent << "\n"
<< "\t</script>\n"
<< "\t<style type=\"text/css\">\n"
<< cssContent << "\n"
<< "\t</style>\n"
<< "\t\t<title>Documentation</title>\n"
<< "\t</head>\n"
<< "\t<body>\n"
<< "\t</body>\n"
<< "</html>\n";
file << html.str();
progressCallback(1.0f);
}
Documentation KameleonDocumentationTask::documentation()
{
using namespace documentation;
return {
"KameleonDocumentationTask",
"kameleon_documentation_task",
{
{
"Type",
new StringEqualVerifier("KameleonDocumentationTask"),
"The type of this task"
},
{
KeyInput,
new StringAnnotationVerifier("A file path to a cdf file"),
"The cdf file to extract data from"
},
{
KeyOutput,
new StringAnnotationVerifier("A valid filepath"),
"The html file to write documentation to"
}
}
};
}
} // namespace openspace
@@ -0,0 +1,46 @@
/*****************************************************************************************
* *
* 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 __KAMELEONDOCUMENTAIONTASK_H__
#define __KAMELEONDOCUMENTAIONTASK_H__
#include <openspace/util/task.h>
namespace openspace {
class KameleonDocumentationTask : public Task {
public:
KameleonDocumentationTask(const ghoul::Dictionary& dictionary);
std::string description() override;
void perform(const Task::ProgressCallback& progressCallback) override;
static Documentation documentation();
private:
std::string _inputPath;
std::string _outputPath;
};
}
#endif __KAMELEONDOCUMENTAIONTASK_H__
@@ -0,0 +1,94 @@
/*****************************************************************************************
* *
* 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/kameleonvolume/tasks/kameleonmetadatatojsontask.h>
#include <modules/kameleonvolume/kameleonvolumereader.h>
#include <string>
#include <openspace/documentation/verifier.h>
#include <ghoul/misc/dictionaryjsonformatter.h>
#include <ghoul/filesystem/filesystem.h>
#include <fstream>
namespace {
const std::string KeyInput = "Input";
const std::string KeyOutput = "Output";
}
namespace openspace {
KameleonMetadataToJsonTask::KameleonMetadataToJsonTask(const ghoul::Dictionary& dictionary) {
openspace::documentation::testSpecificationAndThrow(
documentation(),
dictionary,
"KameleonMetadataToJsonTask"
);
_inputPath = absPath(dictionary.value<std::string>(KeyInput));
_outputPath = absPath(dictionary.value<std::string>(KeyOutput));
}
std::string KameleonMetadataToJsonTask::description() {
return "Extract metadata from cdf-file " + _inputPath + " and write as json to " + _outputPath;
}
void KameleonMetadataToJsonTask::perform(const Task::ProgressCallback & progressCallback) {
KameleonVolumeReader reader(_inputPath);
ghoul::Dictionary dictionary = reader.readMetaData();
progressCallback(0.5f);
ghoul::DictionaryJsonFormatter formatter;
std::string json = formatter.format(dictionary);
std::ofstream output(_outputPath);
output << json;
progressCallback(1.0f);
}
Documentation KameleonMetadataToJsonTask::documentation()
{
using namespace documentation;
return {
"KameleonMetadataToJsonTask",
"kameleon_metadata_to_json_task",
{
{
"Type",
new StringEqualVerifier("KameleonMetadataToJsonTask"),
"The type of this task"
},
{
KeyInput,
new StringAnnotationVerifier("A file path to a cdf file"),
"The cdf file to extract data from"
},
{
KeyOutput,
new StringAnnotationVerifier("A valid filepath"),
"The json file to export data into"
}
}
};
}
} // namespace openspace
@@ -0,0 +1,46 @@
/*****************************************************************************************
* *
* 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 __KAMELEONMETADATATOJSONTASK_H__
#define __KAMELEONMETADATATOJSONTASK_H__
#include <openspace/util/task.h>
namespace openspace {
class KameleonMetadataToJsonTask : public Task {
public:
KameleonMetadataToJsonTask(const ghoul::Dictionary& dictionary);
std::string description() override;
void perform(const Task::ProgressCallback& progressCallback) override;
static Documentation documentation();
private:
std::string _inputPath;
std::string _outputPath;
};
}
#endif __KAMELEONMETADATATOJSONTASK_H__
@@ -47,7 +47,8 @@ namespace {
namespace openspace {
MultiresVolumeRaycaster::MultiresVolumeRaycaster(std::shared_ptr<TSP> tsp,
MultiresVolumeRaycaster::MultiresVolumeRaycaster(
std::shared_ptr<TSP> tsp,
std::shared_ptr<AtlasManager> atlasManager,
std::shared_ptr<TransferFunction> transferFunction)
: _tsp(tsp)
@@ -112,11 +113,9 @@ void MultiresVolumeRaycaster::preRaycast(const RaycastData& data, ghoul::opengl:
_atlasManager->textureAtlas().bind();
program.setUniform("textureAtlas_" + id, _atlasUnit->unitNumber());
_atlasMapBinding = std::make_unique<ghoul::opengl::BufferBinding<ghoul::opengl::bufferbinding::Buffer::ShaderStorage>>();
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, _atlasMapBinding->bindingNumber(), _atlasManager->atlasMapBuffer());
program.setSsboBinding("atlasMapBlock_" + id, _atlasMapBinding->bindingNumber());
program.setUniform("gridType_" + id, static_cast<int>(_tsp->header().gridType_));
program.setUniform("maxNumBricksPerAxis_" + id, static_cast<unsigned int>(_tsp->header().xNumBricks_));
@@ -155,7 +154,8 @@ bool MultiresVolumeRaycaster::cameraIsInside(const RenderData& data, glm::vec3&
}
void MultiresVolumeRaycaster::postRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) {
// For example: release texture units
_textureUnit = nullptr;
_tfUnit = nullptr;
}
std::string MultiresVolumeRaycaster::getBoundsVsPath() const {
+3
View File
@@ -26,7 +26,10 @@ include(${OPENSPACE_CMAKE_EXT_DIR}/module_definition.cmake)
set(HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/rawvolume.h
<<<<<<< HEAD
${CMAKE_CURRENT_SOURCE_DIR}/rawvolume.inl
=======
>>>>>>> 4bf7b71... Add support for converting and rendering volumetric data in the cdf format. Replace DataConverter by a more general purpose TaskRunner.
${CMAKE_CURRENT_SOURCE_DIR}/rawvolumereader.h
${CMAKE_CURRENT_SOURCE_DIR}/rawvolumereader.inl
${CMAKE_CURRENT_SOURCE_DIR}/rawvolumewriter.h
+15 -9
View File
@@ -25,25 +25,31 @@
#ifndef __OPENSPACE_MODULE_VOLUME___RAWVOLUME___H__
#define __OPENSPACE_MODULE_VOLUME___RAWVOLUME___H__
#include <ghoul/glm.h>
#include <functional>
#include <vector>
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;
RawVolume(const glm::uvec3& dimensions);
glm::uvec3 dimensions() const;
void setDimensions(const glm::uvec3& dimensions);
size_t nCells() const;
VoxelType get(const glm::uvec3& coordinates) const;
VoxelType get(const size_t index) const;
void set(const glm::ivec3& coordinates, const VoxelType& value);
void set(const glm::uvec3& coordinates, const VoxelType& value);
void set(size_t index, const VoxelType& value);
void forEachVoxel(const std::function<void(const glm::ivec3&, const VoxelType&)>& fn);
void forEachVoxel(const std::function<void(const glm::uvec3&, const VoxelType&)>& fn);
const VoxelType* data() const;
size_t coordsToIndex(const glm::uvec3& cartesian) const;
glm::uvec3 indexToCoords(size_t linear) const;
VoxelType* data();
private:
size_t coordsToIndex(const glm::ivec3& cartesian) const;
glm::ivec3 indexToCoords(size_t linear) const;
glm::ivec3 _dimensions;
glm::uvec3 _dimensions;
std::vector<VoxelType> _data;
};
+26 -18
View File
@@ -23,31 +23,39 @@
****************************************************************************************/
#include <modules/volume/volumeutils.h>
#include "rawvolume.h"
namespace openspace {
template <typename VoxelType>
RawVolume<VoxelType>::RawVolume(const glm::ivec3& dimensions)
RawVolume<VoxelType>::RawVolume(const glm::uvec3& 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 {
glm::uvec3 RawVolume<VoxelType>::dimensions() const {
return _dimensions;
}
template <typename VoxelType>
void RawVolume<VoxelType>::setDimensions(const glm::ivec3& dimensions) {
void RawVolume<VoxelType>::setDimensions(const glm::uvec3& dimensions) {
_dimensions = dimensions;
_data.resize(static_cast<size_t>(dimensions.x) *
static_cast<size_t>(dimensions.y) *
static_cast<size_t>(dimensions.z));
_data.resize(nCells());
}
template<typename VoxelType>
size_t RawVolume<VoxelType>::nCells() const
{
return static_cast<size_t>(
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 {
VoxelType RawVolume<VoxelType>::get(const glm::uvec3& coordinates) const {
return get(coordsToIndex(coordinates, dimensions()));
}
@@ -57,7 +65,7 @@ VoxelType RawVolume<VoxelType>::get(size_t index) const {
}
template <typename VoxelType>
void RawVolume<VoxelType>::set(const glm::ivec3& coordinates, const VoxelType& value) {
void RawVolume<VoxelType>::set(const glm::uvec3& coordinates, const VoxelType& value) {
return set(coordsToIndex(coordinates, dimensions()), value);
}
@@ -68,27 +76,21 @@ void RawVolume<VoxelType>::set(size_t index, const VoxelType& value) {
template <typename VoxelType>
void RawVolume<VoxelType>::forEachVoxel(
const std::function<void(const glm::ivec3&, const VoxelType&)>& fn)
const std::function<void(const glm::uvec3&, 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++) {
for (size_t i = 0; i < nCells(); i++) {
glm::ivec3 coords = indexToCoords(i);
fn(coords, _data[i]);
}
}
template <typename VoxelType>
size_t RawVolume<VoxelType>::coordsToIndex(const glm::ivec3& cartesian) const {
size_t RawVolume<VoxelType>::coordsToIndex(const glm::uvec3& cartesian) const {
return volumeutils::coordsToIndex(cartesian, dimensions());
}
template <typename VoxelType>
glm::ivec3 RawVolume<VoxelType>::indexToCoords(size_t linear) const {
glm::uvec3 RawVolume<VoxelType>::indexToCoords(size_t linear) const {
return volumeutils::indexToCoords(linear, dimensions());
}
@@ -96,5 +98,11 @@ template <typename VoxelType>
VoxelType* RawVolume<VoxelType>::data() {
return _data.data();
}
template <typename VoxelType>
const VoxelType* RawVolume<VoxelType>::data() const {
return _data.data();
}
}
+6 -6
View File
@@ -34,18 +34,18 @@ template <typename Voxel>
class RawVolumeReader {
public:
typedef Voxel VoxelType;
RawVolumeReader(const std::string& path, const glm::ivec3& dimensions);
glm::ivec3 dimensions() const;
RawVolumeReader(const std::string& path, const glm::uvec3& dimensions);
glm::uvec3 dimensions() const;
std::string path() const;
void setPath(const std::string& path);
void setDimensions(const glm::ivec3& dimensions);
void setDimensions(const glm::uvec3& 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;
size_t coordsToIndex(const glm::uvec3& cartesian) const;
glm::uvec3 indexToCoords(size_t linear) const;
glm::uvec3 _dimensions;
std::string _path;
};
+6 -6
View File
@@ -28,18 +28,18 @@ namespace openspace {
template <typename VoxelType>
RawVolumeReader<VoxelType>::RawVolumeReader(const std::string& path,
const glm::ivec3& dimensions)
const glm::uvec3& dimensions)
: _path(path)
, _dimensions(dimensions)
{}
template <typename VoxelType>
glm::ivec3 RawVolumeReader<VoxelType>::dimensions() const {
glm::uvec3 RawVolumeReader<VoxelType>::dimensions() const {
return _dimensions;
}
template <typename VoxelType>
void RawVolumeReader<VoxelType>::setDimensions(const glm::ivec3& dimensions) {
void RawVolumeReader<VoxelType>::setDimensions(const glm::uvec3& dimensions) {
_dimensions = dimensions;
}
@@ -68,19 +68,19 @@ VoxelType RawVolumeReader<VoxelType>::get(size_t index) const {
}*/
template <typename VoxelType>
size_t RawVolumeReader<VoxelType>::coordsToIndex(const glm::ivec3& cartesian) const {
size_t RawVolumeReader<VoxelType>::coordsToIndex(const glm::uvec3& cartesian) const {
return volumeutils::coordsToIndex(cartesian, dimensions());
}
template <typename VoxelType>
glm::ivec3 RawVolumeReader<VoxelType>::indexToCoords(size_t linear) const {
glm::uvec3 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();
glm::uvec3 dims = dimensions();
std::unique_ptr<RawVolume<VoxelType>> volume =
std::make_unique<RawVolume<VoxelType>>(dims);
+4 -4
View File
@@ -36,13 +36,13 @@ 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,
glm::uvec3 dimensions() const;
void setDimensions(const glm::uvec3& dimensions);
void write(const std::function<VoxelType(const glm::uvec3&)>& fn,
const std::function<void(float t)>& onProgress = [](float t) {});
void write(const RawVolume<VoxelType>& volume);
size_t coordsToIndex(const glm::ivec3& coords) const;
size_t coordsToIndex(const glm::uvec3& coords) const;
glm::ivec3 indexToCoords(size_t linear) const;
private:
glm::ivec3 _dimensions;
+9 -12
View File
@@ -33,7 +33,7 @@ template <typename VoxelType>
, _bufferSize(bufferSize) {}
template <typename VoxelType>
size_t RawVolumeWriter<VoxelType>::coordsToIndex(const glm::ivec3& cartesian) const {
size_t RawVolumeWriter<VoxelType>::coordsToIndex(const glm::uvec3& cartesian) const {
return volumeutils::coordsToIndex(cartesian, dimensions());
}
@@ -43,21 +43,21 @@ glm::ivec3 RawVolumeWriter<VoxelType>::indexToCoords(size_t linear) const {
}
template <typename VoxelType>
void RawVolumeWriter<VoxelType>::setDimensions(const glm::ivec3& dimensions) {
void RawVolumeWriter<VoxelType>::setDimensions(const glm::uvec3& dimensions) {
_dimensions = dimensions;
}
template <typename VoxelType>
glm::ivec3 RawVolumeWriter<VoxelType>::dimensions() const {
glm::uvec3 RawVolumeWriter<VoxelType>::dimensions() const {
return _dimensions;
}
template <typename VoxelType>
void RawVolumeWriter<VoxelType>::write(const std::function<VoxelType(const glm::ivec3&)>& fn,
void RawVolumeWriter<VoxelType>::write(const std::function<VoxelType(const glm::uvec3&)>& fn,
const std::function<void(float t)>& onProgress)
{
glm::ivec3 dims = dimensions();
glm::uvec3 dims = dimensions();
size_t size = static_cast<size_t>(dims.x) *
static_cast<size_t>(dims.y) *
@@ -86,14 +86,11 @@ void RawVolumeWriter<VoxelType>::write(const std::function<VoxelType(const glm::
template <typename VoxelType>
void RawVolumeWriter<VoxelType>::write(const RawVolume<VoxelType>& volume) {
glm::ivec3 dims = dimensions();
ghoul_assert(dims == volume.dims(), "Dimensions of input and output volume must agree");
setDimensions(volume.dimensions());
reinterpret_cast<const char*>(volume.data());
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);
const char* const buffer = reinterpret_cast<const char*>(volume.data());
size_t length = volume.nCells() * sizeof(VoxelType);
std::ofstream file(_path, std::ios::binary);
file.write(buffer, length);
+33
View File
@@ -0,0 +1,33 @@
/*****************************************************************************************
* *
* 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 __VOLUMEGRIDTYPE_H__
#define __VOLUMEGRIDTYPE_H__
enum class VolumeGridType : int {
Cartesian = 0,
Spherical = 1
};
#endif
+3 -3
View File
@@ -27,7 +27,7 @@
namespace openspace {
namespace volumeutils {
size_t coordsToIndex(const glm::vec3& coords, const glm::ivec3& dims) {
size_t coordsToIndex(const glm::uvec3& coords, const glm::uvec3& dims) {
size_t w = dims.x;
size_t h = dims.y;
// size_t d = dims.z;
@@ -39,7 +39,7 @@ size_t coordsToIndex(const glm::vec3& coords, const glm::ivec3& dims) {
return coords.z * (h * w) + coords.y * w + coords.x;
}
glm::vec3 indexToCoords(size_t index, const glm::ivec3& dims) {
glm::uvec3 indexToCoords(size_t index, const glm::uvec3& dims) {
size_t w = dims.x;
size_t h = dims.y;
size_t d = dims.z;
@@ -48,7 +48,7 @@ glm::vec3 indexToCoords(size_t index, const glm::ivec3& dims) {
size_t y = (index / w) % h;
size_t z = index / w / h;
return glm::ivec3(x, y, z);
return glm::uvec3(x, y, z);
}
} // namespace volumeutils
+2 -2
View File
@@ -30,8 +30,8 @@
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);
size_t coordsToIndex(const glm::uvec3& coords, const glm::uvec3& dimensions);
glm::uvec3 indexToCoords(size_t index, const glm::uvec3& dimensions);
} // namespace volumeutils