mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-02-23 05:19:18 -06:00
Added working CDF data loading
- RenderableVolume can now load .raw and .cdf data to ghoul Texture - KameleonWrapper included for easy interaction with Kameleon - openspace-data updated with support for BATSRUS model - CMakeLists.txt updated with settings to Kamelon library - ext/kameleon not included due to Kameleon is currently being ported to git. Waiting to add it as submodule to avoid duplication of files.
This commit is contained in:
@@ -92,6 +92,15 @@ if(OPENCL_FOUND)
|
||||
set(GHOUL_DEPENDENCIES ${GHOUL_DEPENDENCIES} ${OPENCL_LIBRARIES})
|
||||
endif(OPENCL_FOUND)
|
||||
|
||||
# Kameleon
|
||||
option(KAMELEON_LIBRARY_ONLY "Build with Kameleon as library only" ON)
|
||||
option(BUILD_SHARED_LIBS "Build Shared Libraries" ON)
|
||||
set(KAMELEON_ROOT_DIR ${OPENSPACE_EXT_DIR}/kameleon)
|
||||
set(KAMELEON_INCLUDES ${KAMELEON_ROOT_DIR}/src)
|
||||
add_subdirectory(${KAMELEON_ROOT_DIR})
|
||||
include_directories(${KAMELEON_INCLUDES})
|
||||
set(DEPENDENT_LIBS ${DEPENDENT_LIBS} ccmc)
|
||||
|
||||
if (APPLE)
|
||||
include_directories(/Developer/Headers/FlatCarbon)
|
||||
find_library(CARBON_LIBRARY Carbon)
|
||||
|
||||
@@ -44,6 +44,7 @@ public:
|
||||
|
||||
protected:
|
||||
std::string findPath(const std::string& path);
|
||||
ghoul::opengl::Texture* loadVolume(const std::string& filepath, const ghoul::Dictionary& hintsDictionary);
|
||||
ghoul::RawVolumeReader::ReadHints readHints(const ghoul::Dictionary& dictionary);
|
||||
ghoul::opengl::Texture* loadTransferFunction(const std::string& filepath);
|
||||
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
#include <ghoul/opencl/clcommandqueue.h>
|
||||
#include <ghoul/opencl/clprogram.h>
|
||||
#include <ghoul/opencl/clkernel.h>
|
||||
#include <ghoul/io/rawvolumereader.h>
|
||||
#include <ghoul/filesystem/file.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
@@ -75,7 +74,7 @@ private:
|
||||
|
||||
// Volumes
|
||||
std::vector<std::string> _volumePaths;
|
||||
std::vector<ghoul::RawVolumeReader::ReadHints> _volumeHints;
|
||||
std::vector<ghoul::Dictionary> _volumeHints;
|
||||
|
||||
// Textures
|
||||
ghoul::opengl::Texture* _output;
|
||||
@@ -105,7 +104,6 @@ private:
|
||||
std::mutex* _textureLock;
|
||||
|
||||
ghoul::opengl::ProgramObject *_quadProgram;
|
||||
sgct_utils::SGCTBox* _boundingBox;
|
||||
GLuint _screenQuad;
|
||||
|
||||
VolumeRaycasterBox* _colorBoxRenderer;
|
||||
|
||||
57
include/openspace/util/kameleonwrapper.h
Normal file
57
include/openspace/util/kameleonwrapper.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014 *
|
||||
* *
|
||||
* 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 KAMELEONWRAPPER_H_
|
||||
#define KAMELEONWRAPPER_H_
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtx/std_based_type.hpp>
|
||||
|
||||
namespace ccmc {
|
||||
class Model;
|
||||
class Interpolator;
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class KameleonWrapper {
|
||||
public:
|
||||
|
||||
enum class Model {
|
||||
ENLIL, // Heliosphere
|
||||
BATSRUS // Magnetosphere
|
||||
};
|
||||
|
||||
KameleonWrapper(const std::string& filename, Model model);
|
||||
~KameleonWrapper();
|
||||
float* getUniformSampledValues(const std::string& var, glm::size3_t outDimensions);
|
||||
|
||||
private:
|
||||
ccmc::Model* _model;
|
||||
ccmc::Interpolator* _interpolator;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // KAMELEONWRAPPER_H_
|
||||
Submodule openspace-data updated: 700afc3b72...23fa37b495
@@ -29,6 +29,8 @@
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/util/kameleonwrapper.h>
|
||||
|
||||
#include <sgct.h>
|
||||
|
||||
#include <iostream>
|
||||
@@ -41,10 +43,11 @@
|
||||
namespace {
|
||||
std::string _loggerCat = "RenderableVolume";
|
||||
|
||||
bool hasEnding (std::string const &fullString, std::string const &ending)
|
||||
bool hasExtension (std::string const &filepath, std::string const &extension)
|
||||
{
|
||||
if (fullString.length() >= ending.length()) {
|
||||
return (0 == fullString.compare (fullString.length() - ending.length(), ending.length(), ending));
|
||||
std::string ending = "." + extension;
|
||||
if (filepath.length() > ending.length()) {
|
||||
return (0 == filepath.compare (filepath.length() - ending.length(), ending.length(), ending));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -96,6 +99,66 @@ std::string RenderableVolume::findPath(const std::string& path) {
|
||||
return "";
|
||||
}
|
||||
|
||||
ghoul::opengl::Texture* RenderableVolume::loadVolume(const std::string& filepath, const ghoul::Dictionary& hintsDictionary) {
|
||||
if( ! FileSys.fileExists(filepath)) {
|
||||
LWARNING("Could not load volume, could not find '" << filepath << "'");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if(hasExtension(filepath, "raw")) {
|
||||
ghoul::RawVolumeReader::ReadHints hints = readHints(hintsDictionary);
|
||||
ghoul::RawVolumeReader rawReader(hints);
|
||||
return rawReader.read(filepath);
|
||||
} else if(hasExtension(filepath, "cdf")) {
|
||||
|
||||
std::string modelString;
|
||||
if (hintsDictionary.hasKey("Model") && hintsDictionary.getValue("Model", modelString)) {
|
||||
KameleonWrapper::Model model;
|
||||
if (modelString == "BATSRUS") {
|
||||
model = KameleonWrapper::Model::BATSRUS;
|
||||
} else if (modelString == "ENLIL") {
|
||||
model = KameleonWrapper::Model::ENLIL;
|
||||
} else {
|
||||
LWARNING("Hints does not specify a valid 'Model'");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string variableString;
|
||||
if (hintsDictionary.hasKey("Variable") && hintsDictionary.getValue("Variable", variableString)) {
|
||||
glm::size3_t dimensions(1,1,1);
|
||||
double tempValue;
|
||||
if (hintsDictionary.hasKey("Dimensions.1") && hintsDictionary.getValue("Dimensions.1", tempValue)) {
|
||||
int intVal = static_cast<int>(tempValue);
|
||||
if(intVal > 0)
|
||||
dimensions[0] = intVal;
|
||||
}
|
||||
if (hintsDictionary.hasKey("Dimensions.2") && hintsDictionary.getValue("Dimensions.2", tempValue)) {
|
||||
int intVal = static_cast<int>(tempValue);
|
||||
if(intVal > 0)
|
||||
dimensions[1] = intVal;
|
||||
}
|
||||
if (hintsDictionary.hasKey("Dimensions.3") && hintsDictionary.getValue("Dimensions.3", tempValue)) {
|
||||
int intVal = static_cast<int>(tempValue);
|
||||
if(intVal > 0)
|
||||
dimensions[2] = intVal;
|
||||
}
|
||||
|
||||
KameleonWrapper kw(filepath, model);
|
||||
float* data = kw.getUniformSampledValues(variableString, dimensions);
|
||||
return new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT);
|
||||
} else {
|
||||
LWARNING("Hints does not specify a 'Variable'");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
LWARNING("Hints does not specify a 'Model'");
|
||||
} else {
|
||||
LWARNING("No valid file extension.");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ghoul::RawVolumeReader::ReadHints RenderableVolume::readHints(const ghoul::Dictionary& dictionary) {
|
||||
ghoul::RawVolumeReader::ReadHints hints;
|
||||
hints._dimensions = glm::ivec3(1, 1, 1);
|
||||
@@ -165,7 +228,7 @@ ghoul::opengl::Texture* RenderableVolume::loadTransferFunction(const std::string
|
||||
}
|
||||
|
||||
// check if not a txt based texture
|
||||
if ( ! hasEnding(filepath, ".txt")) {
|
||||
if ( ! hasExtension(filepath, "txt")) {
|
||||
return ghoul::opengl::loadTexture(f);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <ghoul/opengl/texturereader.h>
|
||||
#include <ghoul/opencl/clworksize.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/io/rawvolumereader.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -85,10 +86,9 @@ RenderableVolumeExpert::RenderableVolumeExpert(const ghoul::Dictionary& dictiona
|
||||
ghoul::Dictionary hintsDictionary;
|
||||
if(volume.hasKey("Hints"))
|
||||
volume.getValue("Hints", hintsDictionary);
|
||||
ghoul::RawVolumeReader::ReadHints hints = readHints(hintsDictionary);
|
||||
|
||||
_volumePaths.push_back(file);
|
||||
_volumeHints.push_back(hints);
|
||||
_volumeHints.push_back(hintsDictionary);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -204,13 +204,15 @@ bool RenderableVolumeExpert::initialize() {
|
||||
}
|
||||
|
||||
for (int i = 0; i < _volumePaths.size(); ++i) {
|
||||
ghoul::RawVolumeReader rawReader(_volumeHints.at(i));
|
||||
ghoul::opengl::Texture* volume = rawReader.read(_volumePaths.at(i));
|
||||
volume->uploadTexture();
|
||||
cl_mem volumeTexture = _context.createTextureFromGLTexture(CL_MEM_READ_ONLY, *volume);
|
||||
|
||||
_volumes.push_back(volume);
|
||||
_clVolumes.push_back(volumeTexture);
|
||||
|
||||
ghoul::opengl::Texture* volume = loadVolume(_volumePaths.at(i), _volumeHints.at(i));
|
||||
if(volume) {
|
||||
volume->uploadTexture();
|
||||
cl_mem volumeTexture = _context.createTextureFromGLTexture(CL_MEM_READ_ONLY, *volume);
|
||||
|
||||
_volumes.push_back(volume);
|
||||
_clVolumes.push_back(volumeTexture);
|
||||
}
|
||||
}
|
||||
|
||||
// ------ SETUP GEOMETRY ----------------
|
||||
|
||||
114
src/util/kameleonwrapper.cpp
Normal file
114
src/util/kameleonwrapper.cpp
Normal file
@@ -0,0 +1,114 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014 *
|
||||
* *
|
||||
* 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 <ghoul/logging/logmanager.h>
|
||||
#include <openspace/util/kameleonwrapper.h>
|
||||
|
||||
#include <ccmc/Model.h>
|
||||
#include <ccmc/Interpolator.h>
|
||||
#include <ccmc/BATSRUS.h>
|
||||
#include <ccmc/ENLIL.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
std::string _loggerCat = "KameleonWrapper";
|
||||
|
||||
KameleonWrapper::KameleonWrapper(const std::string& filename, Model model) {
|
||||
switch (model) {
|
||||
case Model::BATSRUS:
|
||||
_model = new ccmc::BATSRUS();
|
||||
if(!_model) LERROR("BATSRUS:Failed to create model instance");
|
||||
if (_model->open(filename) != ccmc::FileReader::OK)
|
||||
LERROR("BATSRUS:Failed to open "+filename);
|
||||
_interpolator = _model->createNewInterpolator();
|
||||
if (!_interpolator) LERROR("BATSRUS:Failed to create interpolator");
|
||||
break;
|
||||
case Model::ENLIL:
|
||||
_model = new ccmc::ENLIL();
|
||||
if(!_model) LERROR("Failed to create model instance");
|
||||
if (_model->open(filename) != ccmc::FileReader::OK)
|
||||
LERROR("Failed to open "+filename);
|
||||
_interpolator = _model->createNewInterpolator();
|
||||
if (!_interpolator) LERROR("Failed to create interpolator");
|
||||
break;
|
||||
default:
|
||||
LERROR("Only the BATSRUS model is supported for now. Sorry.");
|
||||
}
|
||||
}
|
||||
|
||||
KameleonWrapper::~KameleonWrapper() {
|
||||
delete _model;
|
||||
delete _interpolator;
|
||||
}
|
||||
|
||||
float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::size3_t outDimensions) {
|
||||
assert(_model && _interpolator);
|
||||
assert(outDimensions.x > 0 && outDimensions.y > 0 && outDimensions.z > 0);
|
||||
LDEBUG("getUniformSampledValues");
|
||||
|
||||
int size = outDimensions.x*outDimensions.y*outDimensions.z;
|
||||
float* data = new float[size];
|
||||
|
||||
// TODO Check which coordinate system the model use. Currently assumes {x,y,z}
|
||||
float xMin = _model->getVariableAttribute("x", "actual_min").getAttributeFloat();
|
||||
float xMax = _model->getVariableAttribute("x", "actual_max").getAttributeFloat();
|
||||
float yMin = _model->getVariableAttribute("y", "actual_min").getAttributeFloat();
|
||||
float yMax = _model->getVariableAttribute("y", "actual_max").getAttributeFloat();
|
||||
float zMin = _model->getVariableAttribute("z", "actual_min").getAttributeFloat();
|
||||
float zMax = _model->getVariableAttribute("z", "actual_max").getAttributeFloat();
|
||||
float varMin = _model->getVariableAttribute(var, "actual_min").getAttributeFloat();
|
||||
float varMax = _model->getVariableAttribute(var, "actual_max").getAttributeFloat();
|
||||
|
||||
float stepX = (xMax-xMin)/((float)outDimensions.x-1.0);
|
||||
float stepY = (yMax-yMin)/((float)outDimensions.y-1.0);
|
||||
float stepZ = (zMax-zMin)/((float)outDimensions.z-1.0);
|
||||
|
||||
// Temporary hack to keep data proportions correct, will give a lot of empty
|
||||
// voxels in y and z. TODO Add spacing/voxel dimensions
|
||||
float step = std::max(stepX, stepY);
|
||||
step = std::max(step, stepZ);
|
||||
|
||||
for (int x = 0; x < outDimensions.x; ++x) {
|
||||
unsigned int progress = (unsigned int)(((float)x/(float)outDimensions.x)*100.f);
|
||||
if (progress % 10 == 0) {
|
||||
std::cout << "Getting data from kameleon: "<< progress << "% \r" << std::flush;
|
||||
}
|
||||
for (int y = 0; y < outDimensions.y; ++y) {
|
||||
for (int z = 0; z < outDimensions.z; ++z) {
|
||||
|
||||
float xPos = xMin + step*x;
|
||||
float yPos = yMin + step*y;
|
||||
float zPos = zMin + step*z;
|
||||
int index = x + y*outDimensions.x + z*outDimensions.x*outDimensions.y;
|
||||
// get interpolated data value for (xPos, yPos, zPos) and scale to [0,1]
|
||||
data[index] = (_interpolator->interpolate(var, xPos, yPos, zPos)-varMin)/(varMax-varMin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
Reference in New Issue
Block a user