mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-02-26 14:58:51 -06:00
Merge branch 'master' into feature/DU
This commit is contained in:
@@ -31,12 +31,15 @@
|
||||
#include <ghoul/io/texture/texturereaderdevil.h>
|
||||
#include <ghoul/io/texture/texturereaderfreeimage.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/filesystem/directory.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/logging/consolelog.h>
|
||||
#include <ghoul/ghoul.h>
|
||||
#include <ghoul/cmdparser/commandlineparser.h>
|
||||
#include <ghoul/cmdparser/singlecommand.h>
|
||||
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
|
||||
#include <openspace/rendering/renderable.h>
|
||||
|
||||
#include <openspace/util/progressbar.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/engine/configurationmanager.h>
|
||||
@@ -62,10 +65,54 @@ void initTextureReaders() {
|
||||
#endif // GHOUL_USE_FREEIMAGE
|
||||
}
|
||||
|
||||
void performTasks(const std::string& path) {
|
||||
using namespace openspace;
|
||||
|
||||
TaskLoader taskLoader;
|
||||
std::vector<std::unique_ptr<Task>> tasks = taskLoader.tasksFromFile(path);
|
||||
|
||||
size_t nTasks = tasks.size();
|
||||
if (nTasks == 1) {
|
||||
LINFO("Task queue has 1 item");
|
||||
}
|
||||
else {
|
||||
LINFO("Task queue has " << tasks.size() << " items");
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < tasks.size(); i++) {
|
||||
Task& task = *tasks[i].get();
|
||||
LINFO("Performing task " << (i + 1) << " out of " << tasks.size() << ": " << task.description());
|
||||
ProgressBar progressBar(100);
|
||||
auto onProgress = [&progressBar](float progress) {
|
||||
progressBar.print(progress * 100);
|
||||
};
|
||||
task.perform(onProgress);
|
||||
}
|
||||
std::cout << "Done performing tasks." << std::endl;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
using namespace openspace;
|
||||
|
||||
ghoul::initialize();
|
||||
|
||||
ghoul::logging::LogManager::initialize(
|
||||
ghoul::logging::LogLevel::Debug,
|
||||
ghoul::logging::LogManager::ImmediateFlush::Yes
|
||||
);
|
||||
LogMgr.addLog(std::make_unique< ghoul::logging::ConsoleLog>());
|
||||
|
||||
LDEBUG("Initialize FileSystem");
|
||||
|
||||
ghoul::filesystem::Directory launchDirectory = FileSys.currentDirectory();
|
||||
|
||||
#ifdef __APPLE__
|
||||
ghoul::filesystem::File app(argv[0]);
|
||||
std::string dirName = app.directoryName();
|
||||
LINFO("Setting starting directory to '" << dirName << "'");
|
||||
FileSys.setCurrentDirectory(dirName);
|
||||
#endif
|
||||
|
||||
initTextureReaders();
|
||||
|
||||
FactoryManager::initialize();
|
||||
@@ -98,34 +145,49 @@ int main(int argc, char** argv) {
|
||||
|
||||
ModuleEngine moduleEngine;
|
||||
moduleEngine.initialize();
|
||||
|
||||
std::string tasksPath;
|
||||
configuration.getValue(ConfigurationManager::KeyConfigTask, tasksPath);
|
||||
|
||||
LINFO("Initialization done.");
|
||||
|
||||
TaskLoader taskLoader;
|
||||
std::vector<std::unique_ptr<Task>> tasks = taskLoader.tasksFromFile(tasksPath);
|
||||
|
||||
size_t nTasks = tasks.size();
|
||||
if (nTasks == 1) {
|
||||
LINFO("Task queue has 1 item");
|
||||
} else {
|
||||
LINFO("Task queue has " << tasks.size() << " items");
|
||||
// Parse commandline arguments
|
||||
std::vector<std::string> args(argv, argv + argc);
|
||||
|
||||
ghoul::cmdparser::CommandlineParser commandlineParser(
|
||||
"OpenSpace TaskRunner",
|
||||
ghoul::cmdparser::CommandlineParser::AllowUnknownCommands::Yes
|
||||
);
|
||||
|
||||
std::string tasksPath = "";
|
||||
commandlineParser.addCommand(
|
||||
std::make_unique<ghoul::cmdparser::SingleCommand<std::string>>(
|
||||
&tasksPath,
|
||||
"--task",
|
||||
"-t",
|
||||
"Provides the path to a task file to execute"
|
||||
)
|
||||
);
|
||||
|
||||
commandlineParser.setCommandLine(args);
|
||||
commandlineParser.execute();
|
||||
|
||||
FileSys.setCurrentDirectory(launchDirectory);
|
||||
|
||||
if (tasksPath != "") {
|
||||
performTasks(tasksPath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < tasks.size(); i++) {
|
||||
Task& task = *tasks[i].get();
|
||||
LINFO("Performing task " << (i+1) << " out of " << tasks.size() << ": " << task.description());
|
||||
ProgressBar progressBar(100);
|
||||
auto onProgress = [&progressBar](float progress) {
|
||||
progressBar.print(progress * 100);
|
||||
};
|
||||
task.perform(onProgress);
|
||||
// If no task file was specified in as argument, run in CLI mode.
|
||||
|
||||
std::string tasksRoot;
|
||||
if (configuration.getValue(ConfigurationManager::KeyConfigTasksRoot, tasksRoot)) {
|
||||
LINFO("Task root: " << tasksRoot);
|
||||
FileSys.setCurrentDirectory(ghoul::filesystem::Directory(absPath(tasksRoot)));
|
||||
}
|
||||
|
||||
std::cout << "Done performing tasks." << std::endl;
|
||||
std::cout << "TASK >";
|
||||
while (std::cin >> tasksPath) {
|
||||
performTasks(tasksPath);
|
||||
std::cout << "TASK >";
|
||||
}
|
||||
|
||||
std::cin.get();
|
||||
return 0;
|
||||
};
|
||||
|
||||
@@ -69,8 +69,8 @@ public:
|
||||
static const std::string KeyFactoryDocumentation;
|
||||
/// The key that stores the location of the scene file that is initially loaded
|
||||
static const std::string KeyConfigScene;
|
||||
/// The key that stores the location of the tasks file that is initially loaded
|
||||
static const std::string KeyConfigTask;
|
||||
/// The key that stores the location of the tasks files
|
||||
static const std::string KeyConfigTasksRoot;
|
||||
/// The key that stores the subdirectory containing a list of all startup scripts to
|
||||
/// be executed on application start before the scene file is loaded
|
||||
static const std::string KeyStartupScript;
|
||||
|
||||
@@ -46,7 +46,6 @@ namespace ghoul::opengl {
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class RenderableVolume;
|
||||
class Camera;
|
||||
class Scene;
|
||||
|
||||
|
||||
@@ -22,15 +22,15 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___CONCURRENT_JOB_MANAGER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___CONCURRENT_JOB_MANAGER___H__
|
||||
#ifndef __OPENSPACE_CORE___CONCURRENT_JOB_MANAGER___H__
|
||||
#define __OPENSPACE_CORE___CONCURRENT_JOB_MANAGER___H__
|
||||
|
||||
#include <modules/globebrowsing/other/concurrentqueue.h>
|
||||
#include <modules/globebrowsing/other/threadpool.h>
|
||||
#include <openspace/util/concurrentqueue.h>
|
||||
#include <openspace/util/threadpool.h>
|
||||
|
||||
#include <mutex>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
namespace openspace {
|
||||
|
||||
// Templated abstract base class representing a job to be done.
|
||||
// Client code derive from this class and implement the virtual execute() method
|
||||
@@ -66,8 +66,8 @@ private:
|
||||
ThreadPool threadPool;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
} // namespace openspace
|
||||
|
||||
#include "concurrentjobmanager.inl"
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___CONCURRENT_JOB_MANAGER___H__
|
||||
#endif // __OPENSPACE_CORE___CONCURRENT_JOB_MANAGER___H__
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
#include <ghoul/misc/assert.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
namespace openspace {
|
||||
|
||||
template<typename P>
|
||||
Job<P>::Job() {}
|
||||
@@ -63,4 +63,4 @@ size_t ConcurrentJobManager<P>::numFinishedJobs() const {
|
||||
return _finishedJobs.size();
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
} // namespace openspace
|
||||
@@ -22,14 +22,14 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___CONCURRENT_QUEUE___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___CONCURRENT_QUEUE___H__
|
||||
#ifndef __OPENSPACE_CORE___CONCURRENT_QUEUE___H__
|
||||
#define __OPENSPACE_CORE___CONCURRENT_QUEUE___H__
|
||||
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
namespace openspace {
|
||||
|
||||
/**
|
||||
* Templated thread-safe queue based on std::thread and std::queue
|
||||
@@ -53,8 +53,8 @@ private:
|
||||
mutable std::condition_variable _cond;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
} // namespace openspace
|
||||
|
||||
#include "concurrentqueue.inl"
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___CONCURRENT_QUEUE___H__
|
||||
#endif // __OPENSPACE_CORE___CONCURRENT_QUEUE___H__
|
||||
@@ -22,7 +22,7 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
namespace openspace {
|
||||
|
||||
template <typename T>
|
||||
T ConcurrentQueue<T>::pop() {
|
||||
@@ -70,4 +70,4 @@ size_t ConcurrentQueue<T>::size() const {
|
||||
return s;
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
} // namespace openspace
|
||||
@@ -22,8 +22,8 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___THREAD_POOL___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___THREAD_POOL___H__
|
||||
#ifndef __OPENSPACE_CORE___THREAD_POOL___H__
|
||||
#define __OPENSPACE_CORE___THREAD_POOL___H__
|
||||
|
||||
#include <condition_variable>
|
||||
#include <functional>
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
// Implementatin based on http://progsch.net/wordpress/?p=81
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
namespace openspace {
|
||||
|
||||
class ThreadPool;
|
||||
|
||||
@@ -69,6 +69,6 @@ private:
|
||||
bool stop;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___THREAD_POOL___H__
|
||||
#endif // __OPENSPACE_CORE___THREAD_POOL___H__
|
||||
@@ -42,8 +42,11 @@ public:
|
||||
void removeKeyframesBefore(double timestamp);
|
||||
void removeKeyframesAfter(double timestamp);
|
||||
void clearKeyframes();
|
||||
void setTimeNextFrame(Time t);
|
||||
size_t nKeyframes() const;
|
||||
private:
|
||||
bool _shouldSetTime;
|
||||
Time _timeNextFrame;
|
||||
Timeline<Time> _timeline;
|
||||
SyncData<Time> _currentTime;
|
||||
void consumeKeyframes(double dt);
|
||||
|
||||
@@ -59,19 +59,14 @@ set(HEADER_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/meshes/skirtedgrid.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/meshes/trianglesoup.h
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/concurrentjobmanager.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/concurrentjobmanager.inl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/prioritizingconcurrentjobmanager.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/prioritizingconcurrentjobmanager.inl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/concurrentqueue.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/concurrentqueue.inl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/distanceswitch.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/pixelbuffer.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/pixelbuffercontainer.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/pixelbuffercontainer.inl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/statscollector.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/statscollector.inl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/threadpool.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/lruthreadpool.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/lruthreadpool.inl
|
||||
|
||||
@@ -157,7 +152,6 @@ set(SOURCE_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/distanceswitch.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/pixelbuffer.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/statscollector.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/threadpool.cpp
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/chunkrenderer.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/layershadermanager.cpp
|
||||
|
||||
@@ -123,6 +123,15 @@ namespace openspace {
|
||||
GlobeBrowsingModule::GlobeBrowsingModule() : OpenSpaceModule(Name) {}
|
||||
|
||||
void GlobeBrowsingModule::internalInitialize() {
|
||||
// TODO: Remove dependency on OsEng.
|
||||
// Instead, make this class implement an interface that OsEng depends on.
|
||||
// Do not try to register module callbacks if OsEng does not exist,
|
||||
// for example in the TaskRunner.
|
||||
|
||||
if (!OpenSpaceEngine::isCreated()) {
|
||||
return;
|
||||
}
|
||||
|
||||
using namespace globebrowsing;
|
||||
|
||||
// Initialize
|
||||
@@ -232,6 +241,7 @@ scripting::LuaLibrary GlobeBrowsingModule::luaLibrary() const {
|
||||
"Get geographic coordinates of the camera poosition in latitude, "
|
||||
"longitude, and altitude"
|
||||
},
|
||||
#ifdef GLOBEBROWSING_USE_GDAL
|
||||
{
|
||||
"loadWMSCapabilities",
|
||||
&globebrowsing::luascriptfunctions::loadWMSCapabilities,
|
||||
@@ -259,6 +269,7 @@ scripting::LuaLibrary GlobeBrowsingModule::luaLibrary() const {
|
||||
"component of the returned table can be used in the 'FilePath' argument "
|
||||
"for a call to the 'addLayer' function to add the value to a globe."
|
||||
}
|
||||
#endif // GLOBEBROWSING_USE_GDAL
|
||||
},
|
||||
{
|
||||
"${MODULE_GLOBEBROWSING}/scripts/layer_support.lua"
|
||||
|
||||
@@ -204,6 +204,7 @@ int getGeoPosition(lua_State* L) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
#ifdef GLOBEBROWSING_USE_GDAL
|
||||
int loadWMSCapabilities(lua_State* L) {
|
||||
int nArguments = lua_gettop(L);
|
||||
|
||||
@@ -220,8 +221,6 @@ int loadWMSCapabilities(lua_State* L) {
|
||||
std::move(globe),
|
||||
std::move(url)
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int removeWMSServer(lua_State* L) {
|
||||
@@ -266,5 +265,7 @@ int capabilities(lua_State* L) {
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif // GLOBEBROWSING_USE_GDAL
|
||||
|
||||
|
||||
} // namespace openspace::globebrowsing::luascriptfunctions
|
||||
|
||||
@@ -25,9 +25,10 @@
|
||||
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___PRIORITIZING_CONCURRENT_JOB_MANAGER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___PRIORITIZING_CONCURRENT_JOB_MANAGER___H__
|
||||
|
||||
#include <modules/globebrowsing/other/concurrentqueue.h>
|
||||
#include <modules/globebrowsing/other/lruthreadpool.h>
|
||||
#include <modules/globebrowsing/other/concurrentjobmanager.h>
|
||||
|
||||
#include <openspace/util/concurrentjobmanager.h>
|
||||
#include <openspace/util/concurrentqueue.h>
|
||||
|
||||
#include <mutex>
|
||||
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___TILELOADJOB___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___TILELOADJOB___H__
|
||||
|
||||
#include <modules/globebrowsing/other/concurrentjobmanager.h>
|
||||
#include <modules/globebrowsing/tile/tile.h>
|
||||
#include <openspace/util/concurrentjobmanager.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
|
||||
@@ -67,7 +67,9 @@ public:
|
||||
//protected:
|
||||
GuiHelpComponent _help;
|
||||
GuiFilePathComponent _filePath;
|
||||
#ifdef GLOBEBROWSING_USE_GDAL
|
||||
GuiGlobeBrowsingComponent _globeBrowsing;
|
||||
#endif // GLOBEBROWSING_USE_GDAL
|
||||
GuiOriginComponent _origin;
|
||||
GuiPerformanceComponent _performance;
|
||||
GuiPropertyComponent _globalProperty;
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifdef GLOBEBROWSING_USE_GDAL
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_IMGUI___GUIGLOBEBROWSINGCOMPONENT___H__
|
||||
#define __OPENSPACE_MODULE_IMGUI___GUIGLOBEBROWSINGCOMPONENT___H__
|
||||
|
||||
@@ -49,3 +51,5 @@ private:
|
||||
|
||||
|
||||
#endif // __OPENSPACE_MODULE_IMGUI___GUIGLOBEBROWSINGCOMPONENT___H__
|
||||
|
||||
#endif // GLOBEBROWSING_USE_GDAL
|
||||
|
||||
@@ -242,7 +242,9 @@ GUI::GUI()
|
||||
addPropertySubOwner(_property);
|
||||
addPropertySubOwner(_screenSpaceProperty);
|
||||
addPropertySubOwner(_virtualProperty);
|
||||
#ifdef GLOBEBROWSING_USE_GDAL
|
||||
addPropertySubOwner(_globeBrowsing);
|
||||
#endif // GLOBEBROWSING_USE_GDAL
|
||||
addPropertySubOwner(_filePath);
|
||||
addPropertySubOwner(_time);
|
||||
#ifdef OPENSPACE_MODULE_ISWA_ENABLED
|
||||
@@ -330,7 +332,9 @@ void GUI::initialize() {
|
||||
_globalProperty.setHasRegularProperties(true);
|
||||
_virtualProperty.initialize();
|
||||
_filePath.initialize();
|
||||
#ifdef GLOBEBROWSING_USE_GDAL
|
||||
_globeBrowsing.initialize();
|
||||
#endif // GLOBEBROWSING_USE_GDAL
|
||||
_performance.initialize();
|
||||
_help.initialize();
|
||||
_parallel.initialize();
|
||||
@@ -352,7 +356,9 @@ void GUI::deinitialize() {
|
||||
_screenSpaceProperty.deinitialize();
|
||||
_virtualProperty.deinitialize();
|
||||
_filePath.deinitialize();
|
||||
#ifdef GLOBEBROWSING_USE_GDAL
|
||||
_globeBrowsing.deinitialize();
|
||||
#endif // GLOBEBROWSING_USE_GDAL
|
||||
_property.deinitialize();
|
||||
|
||||
delete iniFileBuffer;
|
||||
@@ -427,8 +433,10 @@ void GUI::initializeGL() {
|
||||
_screenSpaceProperty.initializeGL();
|
||||
_globalProperty.initializeGL();
|
||||
_performance.initializeGL();
|
||||
_help.initializeGL();
|
||||
_help.initializeGL();
|
||||
#ifdef GLOBEBROWSING_USE_GDAL
|
||||
_globeBrowsing.initializeGL();
|
||||
#endif // GLOBEBROWSING_USE_GDAL
|
||||
_filePath.initializeGL();
|
||||
_parallel.initializeGL();
|
||||
#ifdef OPENSPACE_MODULE_ISWA_ENABLED
|
||||
@@ -459,7 +467,9 @@ void GUI::deinitializeGL() {
|
||||
_performance.deinitializeGL();
|
||||
_globalProperty.deinitializeGL();
|
||||
_screenSpaceProperty.deinitializeGL();
|
||||
#ifdef GLOBEBROWSING_USE_GDAL
|
||||
_globeBrowsing.deinitializeGL();
|
||||
#endif // GLOBEBROWSING_USE_GDAL
|
||||
_filePath.deinitializeGL();
|
||||
_property.deinitializeGL();
|
||||
}
|
||||
@@ -520,9 +530,11 @@ void GUI::endFrame() {
|
||||
_filePath.render();
|
||||
}
|
||||
|
||||
#ifdef GLOBEBROWSING_USE_GDAL
|
||||
if (_globeBrowsing.isEnabled()) {
|
||||
_globeBrowsing.render();
|
||||
}
|
||||
#endif // GLOBEBROWSING_USE_GDAL
|
||||
}
|
||||
|
||||
ImGui::Render();
|
||||
@@ -622,9 +634,11 @@ void GUI::render() {
|
||||
ImGui::Checkbox("File Paths", &filePath);
|
||||
_filePath.setEnabled(filePath);
|
||||
|
||||
#ifdef GLOBEBROWSING_USE_GDAL
|
||||
bool globeBrowsing = _globeBrowsing.isEnabled();
|
||||
ImGui::Checkbox("GlobeBrowsing", &globeBrowsing);
|
||||
_globeBrowsing.setEnabled(globeBrowsing);
|
||||
#endif // GLOBEBROWSING_USE_GDAL
|
||||
|
||||
#ifdef OPENSPACE_MODULE_ISWA_ENABLED
|
||||
bool iswa = _iswa.isEnabled();
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifdef GLOBEBROWSING_USE_GDAL
|
||||
|
||||
#include <modules/imgui/include/guiglobebrowsingcomponent.h>
|
||||
|
||||
#include <modules/imgui/include/imgui_include.h>
|
||||
@@ -332,3 +334,5 @@ void GuiGlobeBrowsingComponent::render() {
|
||||
}
|
||||
|
||||
} // namespace openspace::gui
|
||||
|
||||
#endif // GLOBEBROWSING_USE_GDAL
|
||||
|
||||
@@ -28,17 +28,17 @@ 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
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tasks/kameleonvolumetorawtask.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
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tasks/kameleonvolumetorawtask.cpp
|
||||
)
|
||||
source_group("Source Files" FILES ${SOURCE_FILES})
|
||||
|
||||
|
||||
@@ -32,9 +32,13 @@
|
||||
#include <modules/kameleonvolume/rendering/renderablekameleonvolume.h>
|
||||
#include <modules/kameleonvolume/tasks/kameleonmetadatatojsontask.h>
|
||||
#include <modules/kameleonvolume/tasks/kameleondocumentationtask.h>
|
||||
#include <modules/kameleonvolume/tasks/kameleonvolumetorawtask.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
|
||||
using namespace kameleonvolume;
|
||||
|
||||
KameleonVolumeModule::KameleonVolumeModule() : OpenSpaceModule(Name) {}
|
||||
|
||||
void KameleonVolumeModule::internalInitialize() {
|
||||
@@ -46,6 +50,7 @@ void KameleonVolumeModule::internalInitialize() {
|
||||
ghoul_assert(fTask, "No task factory existed");
|
||||
fTask->registerClass<KameleonMetadataToJsonTask>("KameleonMetadataToJsonTask");
|
||||
fTask->registerClass<KameleonDocumentationTask>("KameleonDocumentationTask");
|
||||
fTask->registerClass<KameleonVolumeToRawTask>("KameleonVolumeToRawTask");
|
||||
}
|
||||
|
||||
std::vector<documentation::Documentation> KameleonVolumeModule::documentations() const {
|
||||
|
||||
@@ -48,36 +48,66 @@ namespace {
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
namespace kameleonvolume {
|
||||
|
||||
KameleonVolumeReader::KameleonVolumeReader(const std::string& path)
|
||||
: _path(path)
|
||||
{
|
||||
if (!FileSys.fileExists(path)) {
|
||||
LERROR(_path << "does not exist");
|
||||
return;
|
||||
LERROR(_path << " does not exist");
|
||||
throw ghoul::FileNotFoundError(_path);
|
||||
}
|
||||
|
||||
long status = _kameleon.open(_path);
|
||||
if (status != ccmc::FileReader::OK) {
|
||||
LERROR("Failed to open file " << _path << " with kameleon");
|
||||
LERROR("Failed to open file " << _path << " with Kameleon");
|
||||
throw ghoul::RuntimeError("Failed to open file: " + _path + " with Kameleon");
|
||||
return;
|
||||
}
|
||||
|
||||
_model = _kameleon.model;
|
||||
|
||||
// Possibly use a kameleon interpolator instead of a model interpolator?
|
||||
_interpolator = std::unique_ptr<ccmc::Interpolator>(_model->createNewInterpolator());
|
||||
}
|
||||
|
||||
std::unique_ptr<RawVolume<float>> KameleonVolumeReader::readFloatVolume(
|
||||
std::unique_ptr<volume::RawVolume<float>> KameleonVolumeReader::readFloatVolume(
|
||||
const glm::uvec3 & dimensions,
|
||||
const std::string & variable,
|
||||
const glm::vec3 & lowerDomainBound,
|
||||
const glm::vec3 & upperDomainBound) const
|
||||
{
|
||||
float min, max;
|
||||
return readFloatVolume(dimensions, variable, lowerDomainBound, upperDomainBound, min, max);
|
||||
}
|
||||
|
||||
std::unique_ptr<volume::RawVolume<float>> KameleonVolumeReader::readFloatVolume(
|
||||
const glm::uvec3 & dimensions,
|
||||
const std::string & variable,
|
||||
const glm::vec3 & lowerBound,
|
||||
const glm::vec3 & upperBound) const
|
||||
const glm::vec3 & upperBound,
|
||||
float& minValue,
|
||||
float& maxValue) const
|
||||
{
|
||||
auto volume = std::make_unique<RawVolume<float>>(dimensions);
|
||||
minValue = FLT_MAX;
|
||||
maxValue = FLT_MIN;
|
||||
|
||||
auto volume = std::make_unique<volume::RawVolume<float>>(dimensions);
|
||||
const glm::vec3 dims = volume->dimensions();
|
||||
const glm::vec3 diff = upperBound - lowerBound;
|
||||
|
||||
_model->loadVariable(variable);
|
||||
auto interpolate =
|
||||
[this](const std::string& variable, glm::vec3 volumeCoords) {
|
||||
return _interpolator->interpolate(
|
||||
variable,
|
||||
volumeCoords[0],
|
||||
volumeCoords[1],
|
||||
volumeCoords[2]);
|
||||
};
|
||||
|
||||
auto sample = [this, &variable, &interpolate](glm::vec3 volumeCoords) {
|
||||
return interpolate(variable, volumeCoords);
|
||||
};
|
||||
|
||||
float* data = volume->data();
|
||||
for (size_t index = 0; index < volume->nCells(); index++) {
|
||||
@@ -85,11 +115,14 @@ std::unique_ptr<RawVolume<float>> KameleonVolumeReader::readFloatVolume(
|
||||
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]));
|
||||
data[index] = sample(volumeCoords);
|
||||
|
||||
if (data[index] < minValue) {
|
||||
minValue = data[index];
|
||||
}
|
||||
if (data[index] > maxValue) {
|
||||
maxValue = data[index];
|
||||
}
|
||||
}
|
||||
|
||||
return volume;
|
||||
@@ -205,12 +238,80 @@ ghoul::Dictionary KameleonVolumeReader::readMetaData() const {
|
||||
};
|
||||
}
|
||||
|
||||
float KameleonVolumeReader::minValue(const std::string & variable) const {
|
||||
std::string KameleonVolumeReader::simulationStart() const {
|
||||
std::string startTime;
|
||||
if (_model->doesAttributeExist("start_time")){
|
||||
startTime =
|
||||
_model->getGlobalAttribute("start_time").getAttributeString();
|
||||
} else if (_model->doesAttributeExist("tim_rundate_cal")) {
|
||||
startTime =
|
||||
_model->getGlobalAttribute("tim_rundate_cal").getAttributeString();
|
||||
size_t numChars = startTime.length();
|
||||
if (numChars < 19) {
|
||||
// Fall through to add the required characters
|
||||
switch (numChars) {
|
||||
case 10 : // YYYY-MM-DD => YYYY-MM-DDTHH
|
||||
startTime += "T00";
|
||||
[[fallthrough]];
|
||||
case 13 : // YYYY-MM-DDTHH => YYYY-MM-DDTHH:
|
||||
startTime += ":";
|
||||
[[fallthrough]];
|
||||
case 14 : // YYYY-MM-DDTHH: => YYYY-MM-DDTHH:MM
|
||||
startTime += "00";
|
||||
[[fallthrough]];
|
||||
case 16 : // YYYY-MM-DDTHH:MM => YYYY-MM-DDTHH:MM:
|
||||
startTime += ":";
|
||||
[[fallthrough]];
|
||||
case 17 : // YYYY-MM-DDTHH:MM: => YYYY-MM-DDTHH:MM:SS
|
||||
startTime += "00";
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (_model->doesAttributeExist("tim_obsdate_cal")) {
|
||||
startTime =
|
||||
_model->getGlobalAttribute("tim_obsdate_cal").getAttributeString();
|
||||
} else if (_model->doesAttributeExist("tim_crstart_cal")) {
|
||||
startTime =
|
||||
_model->getGlobalAttribute("tim_crstart_cal").getAttributeString();
|
||||
}
|
||||
|
||||
if (startTime.length() == 19) {
|
||||
startTime += ".000Z";
|
||||
}
|
||||
|
||||
return startTime;
|
||||
}
|
||||
|
||||
float KameleonVolumeReader::elapsedTime() const {
|
||||
if (_model->doesAttributeExist("elapsed_time_in_seconds")) {
|
||||
return _model->getGlobalAttribute("elapsed_time_in_seconds").getAttributeFloat();
|
||||
} else if (_model->doesAttributeExist("time_physical_time")) {
|
||||
return _model->getGlobalAttribute("time_physical_time").getAttributeFloat();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string KameleonVolumeReader::simulationEnd() const {
|
||||
return _model->getGlobalAttribute("end_time").getAttributeString();
|
||||
}
|
||||
|
||||
std::string KameleonVolumeReader::time() const {
|
||||
double start =
|
||||
ccmc::Time(simulationStart()).getEpoch();
|
||||
// Get elapsed time in seconds and convert to milliseconds.
|
||||
double elapsed = elapsedTime() * 1000;
|
||||
return ccmc::Time(start + elapsed).toString();
|
||||
}
|
||||
|
||||
double KameleonVolumeReader::minValue(const std::string & variable) const {
|
||||
return _model->getVariableAttribute(variable, "actual_min").getAttributeFloat();
|
||||
}
|
||||
|
||||
float KameleonVolumeReader::maxValue(const std::string & variable) const {
|
||||
double KameleonVolumeReader::maxValue(const std::string & variable) const {
|
||||
return _model->getVariableAttribute(variable, "actual_max").getAttributeFloat();
|
||||
}
|
||||
|
||||
} // namepace kameleonvolume
|
||||
} // namespace openspace
|
||||
|
||||
@@ -47,23 +47,37 @@
|
||||
namespace ccmc { class Model; }
|
||||
|
||||
namespace openspace {
|
||||
namespace kameleonvolume {
|
||||
|
||||
class KameleonVolumeReader {
|
||||
public:
|
||||
KameleonVolumeReader(const std::string& path);
|
||||
//KameleonMetaData readMetaData();
|
||||
|
||||
std::unique_ptr<RawVolume<float>> readFloatVolume(
|
||||
std::unique_ptr<volume::RawVolume<float>> readFloatVolume(
|
||||
const glm::uvec3& dimensions,
|
||||
const std::string& variable,
|
||||
const glm::vec3& lowerDomainBound,
|
||||
const glm::vec3& upperDomainBound) const;
|
||||
|
||||
std::unique_ptr<volume::RawVolume<float>> readFloatVolume(
|
||||
const glm::uvec3& dimensions,
|
||||
const std::string& variable,
|
||||
const glm::vec3& lowerBound,
|
||||
const glm::vec3& upperBound) const;
|
||||
const glm::vec3& upperBound,
|
||||
float& minValue,
|
||||
float& maxValue) const;
|
||||
|
||||
ghoul::Dictionary readMetaData() const;
|
||||
float minValue(const std::string& variable) const;
|
||||
float maxValue(const std::string& variable) const;
|
||||
|
||||
std::string time() const;
|
||||
std::string simulationStart() const;
|
||||
std::string simulationEnd() const;
|
||||
float elapsedTime() const;
|
||||
|
||||
double minValue(const std::string& variable) const;
|
||||
double 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;
|
||||
@@ -77,6 +91,7 @@ private:
|
||||
|
||||
};
|
||||
|
||||
} // namespace kameleonvolume
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_KAMELEONVOLUME___KAMELEONVOLUMEREADER___H__
|
||||
|
||||
@@ -133,6 +133,7 @@ namespace {
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
namespace kameleonvolume {
|
||||
|
||||
RenderableKameleonVolume::RenderableKameleonVolume(const ghoul::Dictionary& dictionary)
|
||||
: Renderable(dictionary)
|
||||
@@ -226,7 +227,7 @@ RenderableKameleonVolume::RenderableKameleonVolume(const ghoul::Dictionary& dict
|
||||
|
||||
ghoul::Dictionary clipPlanesDictionary;
|
||||
dictionary.getValue(KeyClipPlanes, clipPlanesDictionary);
|
||||
_clipPlanes = std::make_shared<VolumeClipPlanes>(clipPlanesDictionary);
|
||||
_clipPlanes = std::make_shared<volume::VolumeClipPlanes>(clipPlanesDictionary);
|
||||
_clipPlanes->setName("clipPlanes");
|
||||
|
||||
bool cache;
|
||||
@@ -234,14 +235,14 @@ RenderableKameleonVolume::RenderableKameleonVolume(const ghoul::Dictionary& dict
|
||||
_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));
|
||||
_gridType.addOption(static_cast<int>(volume::VolumeGridType::Cartesian), "Cartesian grid");
|
||||
_gridType.addOption(static_cast<int>(volume::VolumeGridType::Spherical), "Spherical grid");
|
||||
_gridType.setValue(static_cast<int>(volume::VolumeGridType::Cartesian));
|
||||
|
||||
std::string gridType;
|
||||
if (dictionary.getValue(KeyGridType, gridType)) {
|
||||
if (gridType == ValueSphericalGridType) {
|
||||
_gridType.setValue(static_cast<int>(VolumeGridType::Spherical));
|
||||
_gridType.setValue(static_cast<int>(volume::VolumeGridType::Spherical));
|
||||
} else {
|
||||
_autoGridType = true;
|
||||
}
|
||||
@@ -256,15 +257,15 @@ void RenderableKameleonVolume::initialize() {
|
||||
_volumeTexture->uploadTexture();
|
||||
_transferFunction->update();
|
||||
|
||||
_raycaster = std::make_unique<KameleonVolumeRaycaster>(_volumeTexture, _transferFunction, _clipPlanes);
|
||||
_raycaster = std::make_unique<volume::BasicVolumeRaycaster>(_volumeTexture, _transferFunction, _clipPlanes);
|
||||
|
||||
_raycaster->setStepSize(_stepSize);
|
||||
_gridType.onChange([this] {
|
||||
_raycaster->setStepSize(_stepSize);
|
||||
});
|
||||
_raycaster->setGridType(static_cast<VolumeGridType>(_gridType.value()));
|
||||
_raycaster->setGridType(static_cast<volume::VolumeGridType>(_gridType.value()));
|
||||
_gridType.onChange([this] {
|
||||
_raycaster->setGridType(static_cast<VolumeGridType>(_gridType.value()));
|
||||
_raycaster->setGridType(static_cast<volume::VolumeGridType>(_gridType.value()));
|
||||
});
|
||||
|
||||
updateRaycasterModelTransform();
|
||||
@@ -372,7 +373,7 @@ void RenderableKameleonVolume::loadFromPath(const std::string& path) {
|
||||
}
|
||||
|
||||
void RenderableKameleonVolume::loadRaw(const std::string& path) {
|
||||
RawVolumeReader<float> reader(path, _dimensions);
|
||||
volume::RawVolumeReader<float> reader(path, _dimensions);
|
||||
_rawVolume = reader.read();
|
||||
updateTextureFromVolume();
|
||||
}
|
||||
@@ -401,10 +402,10 @@ void RenderableKameleonVolume::loadCdf(const std::string& path) {
|
||||
|
||||
if (variables.size() == 3 && _autoGridType) {
|
||||
if (variables[0] == "r" && variables[0] == "theta" && variables[0] == "phi") {
|
||||
_gridType.setValue(static_cast<int>(VolumeGridType::Spherical));
|
||||
_gridType.setValue(static_cast<int>(volume::VolumeGridType::Spherical));
|
||||
}
|
||||
else {
|
||||
_gridType.setValue(static_cast<int>(VolumeGridType::Cartesian));
|
||||
_gridType.setValue(static_cast<int>(volume::VolumeGridType::Cartesian));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -414,7 +415,7 @@ void RenderableKameleonVolume::loadCdf(const std::string& path) {
|
||||
}
|
||||
|
||||
void RenderableKameleonVolume::updateTextureFromVolume() {
|
||||
_normalizedVolume = std::make_unique<RawVolume<GLfloat>>(_dimensions);
|
||||
_normalizedVolume = std::make_unique<volume::RawVolume<GLfloat>>(_dimensions);
|
||||
float* in = _rawVolume->data();
|
||||
GLfloat* out = _normalizedVolume->data();
|
||||
float min = _lowerValueBound;
|
||||
@@ -438,7 +439,7 @@ void RenderableKameleonVolume::updateTextureFromVolume() {
|
||||
}
|
||||
|
||||
void RenderableKameleonVolume::storeRaw(const std::string& path) {
|
||||
RawVolumeWriter<float> writer(path);
|
||||
volume::RawVolumeWriter<float> writer(path);
|
||||
writer.write(*_rawVolume);
|
||||
}
|
||||
|
||||
@@ -464,3 +465,4 @@ void RenderableKameleonVolume::render(const RenderData& data, RendererTasks& tas
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,21 +29,21 @@
|
||||
#include <openspace/properties/optionproperty.h>
|
||||
#include <openspace/properties/stringproperty.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>
|
||||
#include <modules/volume/rendering/basicvolumeraycaster.h>
|
||||
|
||||
#include <modules/volume/rendering/volumeclipplanes.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
struct RenderData;
|
||||
|
||||
|
||||
namespace kameleonvolume {
|
||||
|
||||
class RenderableKameleonVolume : public Renderable {
|
||||
public:
|
||||
RenderableKameleonVolume(const ghoul::Dictionary& dictionary);
|
||||
@@ -81,7 +81,7 @@ private:
|
||||
properties::OptionProperty _gridType;
|
||||
bool _autoGridType;
|
||||
|
||||
std::shared_ptr<VolumeClipPlanes> _clipPlanes;
|
||||
std::shared_ptr<volume::VolumeClipPlanes> _clipPlanes;
|
||||
|
||||
properties::FloatProperty _stepSize;
|
||||
properties::StringProperty _sourcePath;
|
||||
@@ -89,14 +89,15 @@ private:
|
||||
properties::BoolProperty _cache;
|
||||
|
||||
|
||||
std::unique_ptr<RawVolume<float>> _rawVolume;
|
||||
std::unique_ptr<RawVolume<GLfloat>> _normalizedVolume;
|
||||
std::unique_ptr<KameleonVolumeRaycaster> _raycaster;
|
||||
std::unique_ptr<volume::RawVolume<float>> _rawVolume;
|
||||
std::unique_ptr<volume::RawVolume<GLfloat>> _normalizedVolume;
|
||||
std::unique_ptr<volume::BasicVolumeRaycaster> _raycaster;
|
||||
|
||||
std::shared_ptr<ghoul::opengl::Texture> _volumeTexture;
|
||||
std::shared_ptr<TransferFunction> _transferFunction;
|
||||
};
|
||||
|
||||
} // namespace kameleonvolume
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_KAMELEONVOLUME___RENDERABLEKAMELEONVOLUME___H__
|
||||
|
||||
@@ -46,6 +46,7 @@ namespace {
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
namespace kameleonvolume {
|
||||
|
||||
KameleonDocumentationTask::KameleonDocumentationTask(const ghoul::Dictionary& dictionary) {
|
||||
openspace::documentation::testSpecificationAndThrow(
|
||||
@@ -164,4 +165,5 @@ documentation::Documentation KameleonDocumentationTask::documentation() {
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace kameleonvolume
|
||||
} // namespace openspace
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <string>
|
||||
|
||||
namespace openspace {
|
||||
namespace kameleonvolume {
|
||||
|
||||
class KameleonDocumentationTask : public Task {
|
||||
public:
|
||||
@@ -43,6 +44,7 @@ private:
|
||||
std::string _outputPath;
|
||||
};
|
||||
|
||||
} // namespace kameleonvolume
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_KAMELEONVOLUME___KAMELEONDOCUMENTATIONTASK___H__
|
||||
|
||||
@@ -39,6 +39,7 @@ namespace {
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
namespace kameleonvolume {
|
||||
|
||||
KameleonMetadataToJsonTask::KameleonMetadataToJsonTask(
|
||||
const ghoul::Dictionary& dictionary)
|
||||
@@ -98,4 +99,5 @@ documentation::Documentation KameleonMetadataToJsonTask::documentation() {
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace kameleonvolume
|
||||
} // namespace openspace
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <string>
|
||||
|
||||
namespace openspace {
|
||||
namespace kameleonvolume {
|
||||
|
||||
class KameleonMetadataToJsonTask : public Task {
|
||||
public:
|
||||
@@ -43,6 +44,7 @@ private:
|
||||
std::string _outputPath;
|
||||
};
|
||||
|
||||
} // namespace kameleonvolume
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_KAMELEONVOLUME___KAMELEONMETADATATOJSONTASK___H__
|
||||
|
||||
207
modules/kameleonvolume/tasks/kameleonvolumetorawtask.cpp
Normal file
207
modules/kameleonvolume/tasks/kameleonvolumetorawtask.cpp
Normal file
@@ -0,0 +1,207 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/kameleonvolume/tasks/kameleonvolumetorawtask.h>
|
||||
#include <modules/kameleonvolume/kameleonvolumereader.h>
|
||||
#include <modules/volume/rawvolume.h>
|
||||
#include <modules/volume/rawvolumewriter.h>
|
||||
|
||||
#include <openspace/documentation/verifier.h>
|
||||
|
||||
#include <ghoul/misc/dictionaryjsonformatter.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/dictionaryluaformatter.h>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
namespace {
|
||||
const char* KeyInput = "Input";
|
||||
const char* KeyRawVolumeOutput = "RawVolumeOutput";
|
||||
const char* KeyDictionaryOutput = "DictionaryOutput";
|
||||
const char* KeyDimensions = "Dimensions";
|
||||
const char* KeyVariable = "Variable";
|
||||
const char* KeyTime = "Time";
|
||||
const char* KeyLowerDomainBound = "LowerDomainBound";
|
||||
const char* KeyUpperDomainBound = "UpperDomainBound";
|
||||
|
||||
const char* KeyMinValue = "MinValue";
|
||||
const char* KeyMaxValue = "MaxValue";
|
||||
|
||||
const char* _loggerCat = "KameleonVolumeToRawTask";
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
namespace kameleonvolume {
|
||||
|
||||
KameleonVolumeToRawTask::KameleonVolumeToRawTask(const ghoul::Dictionary& dictionary)
|
||||
: _autoDomainBounds(false)
|
||||
{
|
||||
openspace::documentation::testSpecificationAndThrow(
|
||||
documentation(),
|
||||
dictionary,
|
||||
"KameleonVolumeToRawTask"
|
||||
);
|
||||
|
||||
_inputPath = absPath(dictionary.value<std::string>(KeyInput));
|
||||
_rawVolumeOutputPath = absPath(dictionary.value<std::string>(KeyRawVolumeOutput));
|
||||
_dictionaryOutputPath = absPath(dictionary.value<std::string>(KeyDictionaryOutput));
|
||||
_variable = dictionary.value<std::string>(KeyVariable);
|
||||
_dimensions = glm::uvec3(dictionary.value<glm::vec3>(KeyDimensions));
|
||||
|
||||
if (!dictionary.getValue<glm::vec3>(KeyLowerDomainBound, _lowerDomainBound)) {
|
||||
_autoDomainBounds = true;
|
||||
}
|
||||
if (!dictionary.getValue<glm::vec3>(KeyUpperDomainBound, _upperDomainBound)) {
|
||||
_autoDomainBounds = true;
|
||||
}
|
||||
}
|
||||
|
||||
std::string KameleonVolumeToRawTask::description() {
|
||||
return "Extract volumetric data from cdf-file " + _inputPath + "." +
|
||||
"Write raw volume data into " + _rawVolumeOutputPath +
|
||||
" and dictionary with metadata to " + _dictionaryOutputPath;
|
||||
}
|
||||
|
||||
void KameleonVolumeToRawTask::perform(const Task::ProgressCallback& progressCallback) {
|
||||
KameleonVolumeReader reader(_inputPath);
|
||||
|
||||
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]));
|
||||
}
|
||||
|
||||
|
||||
std::unique_ptr<volume::RawVolume<float>> rawVolume = reader.readFloatVolume(
|
||||
_dimensions,
|
||||
_variable,
|
||||
_lowerDomainBound,
|
||||
_upperDomainBound);
|
||||
|
||||
progressCallback(0.5f);
|
||||
|
||||
volume::RawVolumeWriter<float> writer(_rawVolumeOutputPath);
|
||||
writer.write(*rawVolume);
|
||||
|
||||
progressCallback(0.9f);
|
||||
|
||||
ghoul::Dictionary inputMetadata = reader.readMetaData();
|
||||
ghoul::Dictionary outputMetadata;
|
||||
|
||||
std::string time = reader.time();
|
||||
|
||||
// Do not include time offset in time string
|
||||
if (time.back() == 'Z') {
|
||||
time.pop_back();
|
||||
}
|
||||
|
||||
outputMetadata.setValue<std::string>(KeyTime, time);
|
||||
outputMetadata.setValue<glm::vec3>(KeyDimensions, _dimensions);
|
||||
outputMetadata.setValue<glm::vec3>(KeyLowerDomainBound, _lowerDomainBound);
|
||||
outputMetadata.setValue<glm::vec3>(KeyUpperDomainBound, _upperDomainBound);
|
||||
outputMetadata.setValue<float>(KeyMinValue, reader.minValue(_variable));
|
||||
outputMetadata.setValue<float>(KeyMaxValue, reader.maxValue(_variable));
|
||||
|
||||
ghoul::DictionaryLuaFormatter formatter;
|
||||
std::string metadataString = formatter.format(outputMetadata);
|
||||
|
||||
std::fstream f(_dictionaryOutputPath, std::ios::out);
|
||||
f << "return " << metadataString;
|
||||
f.close();
|
||||
|
||||
progressCallback(1.0f);
|
||||
}
|
||||
|
||||
documentation::Documentation KameleonVolumeToRawTask::documentation() {
|
||||
using namespace documentation;
|
||||
return {
|
||||
"KameleonVolumeToRawTask",
|
||||
"kameleon_metadata_to_json_task",
|
||||
{
|
||||
{
|
||||
"Type",
|
||||
new StringEqualVerifier("KameleonVolumeToRawTask"),
|
||||
Optional::No,
|
||||
"The type of this task",
|
||||
},
|
||||
{
|
||||
KeyInput,
|
||||
new StringAnnotationVerifier("A file path to a cdf file"),
|
||||
Optional::No,
|
||||
"The cdf file to extract data from",
|
||||
},
|
||||
{
|
||||
KeyRawVolumeOutput,
|
||||
new StringAnnotationVerifier("A valid filepath"),
|
||||
Optional::No,
|
||||
"The raw volume file to export data to",
|
||||
},
|
||||
{
|
||||
KeyDictionaryOutput,
|
||||
new StringAnnotationVerifier("A valid filepath"),
|
||||
Optional::No,
|
||||
"The lua dictionary file to export metadata to",
|
||||
},
|
||||
{
|
||||
KeyVariable,
|
||||
new StringAnnotationVerifier("A valid kameleon variable"),
|
||||
Optional::No,
|
||||
"The variable name to read from the kameleon dataset",
|
||||
},
|
||||
{
|
||||
KeyDimensions,
|
||||
new DoubleVector3Verifier,
|
||||
Optional::No,
|
||||
"A vector representing the number of cells in each dimension",
|
||||
},
|
||||
{
|
||||
KeyLowerDomainBound,
|
||||
new DoubleVector3Verifier,
|
||||
Optional::Yes,
|
||||
"A vector representing the lower bound of the domain, "
|
||||
"in the native kameleon grid units",
|
||||
},
|
||||
{
|
||||
KeyUpperDomainBound,
|
||||
new DoubleVector3Verifier,
|
||||
Optional::Yes,
|
||||
"A vector representing the lower bound of the domain, "
|
||||
"in the native kameleon grid units",
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace kameleonvolume
|
||||
} // namespace openspace
|
||||
59
modules/kameleonvolume/tasks/kameleonvolumetorawtask.h
Normal file
59
modules/kameleonvolume/tasks/kameleonvolumetorawtask.h
Normal file
@@ -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_MODULE_KAMELEONVOLUME___KAMELEONVOLUMETORAWTASK___H__
|
||||
#define __OPENSPACE_MODULE_KAMELEONVOLUME___KAMELEONVOLUMETORAWTASK___H__
|
||||
|
||||
#include <openspace/util/task.h>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace openspace {
|
||||
namespace kameleonvolume {
|
||||
|
||||
class KameleonVolumeToRawTask : public Task {
|
||||
public:
|
||||
KameleonVolumeToRawTask(const ghoul::Dictionary& dictionary);
|
||||
std::string description() override;
|
||||
void perform(const Task::ProgressCallback& progressCallback) override;
|
||||
static documentation::Documentation documentation();
|
||||
|
||||
private:
|
||||
std::string _inputPath;
|
||||
std::string _rawVolumeOutputPath;
|
||||
std::string _dictionaryOutputPath;
|
||||
|
||||
std::string _variable;
|
||||
glm::uvec3 _dimensions;
|
||||
bool _autoDomainBounds;
|
||||
glm::vec3 _lowerDomainBound;
|
||||
glm::vec3 _upperDomainBound;
|
||||
};
|
||||
|
||||
} // namespace kameleon
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_KAMELEONVOLUME___KAMELEONMETADATATORAWTASK___H__
|
||||
@@ -44,12 +44,11 @@ RenderableToyVolume::RenderableToyVolume(const ghoul::Dictionary& dictionary)
|
||||
, _rotation({ "Rotation", "Euler rotation", "" }, glm::vec3(0.f, 0.f, 0.f), glm::vec3(0), glm::vec3(6.28f)) // @TODO Missing documentation
|
||||
, _color({ "Color", "Color", "" }, glm::vec4(1.f, 0.f, 0.f, 0.1f), glm::vec4(0.f), glm::vec4(1.f)) // @TODO Missing documentation
|
||||
{
|
||||
float stepSize;
|
||||
int scalingExponent;
|
||||
float stepSize, scalingExponent;
|
||||
glm::vec3 scaling, translation, rotation;
|
||||
glm::vec4 color;
|
||||
if (dictionary.getValue("ScalingExponent", scalingExponent)) {
|
||||
_scalingExponent = scalingExponent;
|
||||
_scalingExponent = static_cast<int>(scalingExponent);
|
||||
}
|
||||
if (dictionary.getValue("Scaling", scaling)) {
|
||||
_scaling = scaling;
|
||||
|
||||
@@ -39,6 +39,8 @@ set(HEADER_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/volumesampler.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/volumesampler.inl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/volumeutils.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderabletimevaryingvolume.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/basicvolumeraycaster.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/volumeclipplane.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/volumeclipplanes.h
|
||||
)
|
||||
@@ -50,7 +52,10 @@ set(SOURCE_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rawvolumewriter.inl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/textureslicevolumereader.inl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/volumesampler.inl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/volumegridtype.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/volumeutils.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderabletimevaryingvolume.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/basicvolumeraycaster.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/volumeclipplane.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/volumeclipplanes.cpp
|
||||
)
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <iterator>
|
||||
|
||||
namespace openspace {
|
||||
namespace volume {
|
||||
|
||||
template <typename ValueType>
|
||||
class LinearLruCache {
|
||||
@@ -86,6 +87,7 @@ private:
|
||||
size_t _capacity;
|
||||
};
|
||||
|
||||
} // namespace volume
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_VOLUME___LINEARLRUCACHE___H__
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <iterator>
|
||||
|
||||
namespace openspace {
|
||||
namespace volume {
|
||||
|
||||
template <typename KeyType, typename ValueType, template<typename...> class ContainerType>
|
||||
class LruCache {
|
||||
@@ -85,6 +86,7 @@ private:
|
||||
size_t _capacity;
|
||||
};
|
||||
|
||||
} // namespace volume
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_VOLUME___LRUCACHE___H__
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <vector>
|
||||
|
||||
namespace openspace {
|
||||
namespace volume {
|
||||
|
||||
template <typename Type>
|
||||
class RawVolume {
|
||||
@@ -54,6 +55,7 @@ private:
|
||||
std::vector<VoxelType> _data;
|
||||
};
|
||||
|
||||
} // namespace volume
|
||||
} // namespace openspace
|
||||
|
||||
#include "rawvolume.inl"
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "rawvolume.h"
|
||||
|
||||
namespace openspace {
|
||||
namespace volume {
|
||||
|
||||
template <typename VoxelType>
|
||||
RawVolume<VoxelType>::RawVolume(const glm::uvec3& dimensions)
|
||||
@@ -57,7 +58,7 @@ size_t RawVolume<VoxelType>::nCells() const
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType RawVolume<VoxelType>::get(const glm::uvec3& coordinates) const {
|
||||
return get(coordsToIndex(coordinates, dimensions()));
|
||||
return get(coordsToIndex(coordinates));
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@@ -67,7 +68,7 @@ VoxelType RawVolume<VoxelType>::get(size_t index) const {
|
||||
|
||||
template <typename VoxelType>
|
||||
void RawVolume<VoxelType>::set(const glm::uvec3& coordinates, const VoxelType& value) {
|
||||
return set(coordsToIndex(coordinates, dimensions()), value);
|
||||
return set(coordsToIndex(coordinates), value);
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@@ -87,12 +88,12 @@ void RawVolume<VoxelType>::forEachVoxel(
|
||||
|
||||
template <typename VoxelType>
|
||||
size_t RawVolume<VoxelType>::coordsToIndex(const glm::uvec3& cartesian) const {
|
||||
return volumeutils::coordsToIndex(cartesian, dimensions());
|
||||
return volume::coordsToIndex(cartesian, dimensions());
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
glm::uvec3 RawVolume<VoxelType>::indexToCoords(size_t linear) const {
|
||||
return volumeutils::indexToCoords(linear, dimensions());
|
||||
return volume::indexToCoords(linear, dimensions());
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@@ -105,5 +106,5 @@ const VoxelType* RawVolume<VoxelType>::data() const {
|
||||
return _data.data();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
} // namespace volume
|
||||
} // namespace openspace
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <modules/volume/rawvolume.h>
|
||||
|
||||
namespace openspace {
|
||||
namespace volume {
|
||||
|
||||
template <typename Type>
|
||||
class RawVolumeReader {
|
||||
@@ -51,6 +52,7 @@ private:
|
||||
std::string _path;
|
||||
};
|
||||
|
||||
} // namespace volume
|
||||
} // namespace openspace
|
||||
|
||||
#include "rawvolumereader.inl"
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <fstream>
|
||||
|
||||
namespace openspace {
|
||||
namespace volume {
|
||||
|
||||
template <typename VoxelType>
|
||||
RawVolumeReader<VoxelType>::RawVolumeReader(const std::string& path,
|
||||
@@ -69,12 +70,12 @@ VoxelType RawVolumeReader<VoxelType>::get(size_t index) const {
|
||||
|
||||
template <typename VoxelType>
|
||||
size_t RawVolumeReader<VoxelType>::coordsToIndex(const glm::uvec3& cartesian) const {
|
||||
return volumeutils::coordsToIndex(cartesian, dimensions());
|
||||
return coordsToIndex(cartesian, dimensions());
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
glm::uvec3 RawVolumeReader<VoxelType>::indexToCoords(size_t linear) const {
|
||||
return volumeutils::indexToCoords(linear, dimensions());
|
||||
return indexToCoords(linear, dimensions());
|
||||
}
|
||||
|
||||
|
||||
@@ -95,4 +96,5 @@ std::unique_ptr<RawVolume<VoxelType>> RawVolumeReader<VoxelType>::read() {
|
||||
return volume;
|
||||
}
|
||||
|
||||
} // namepsace volume
|
||||
} // namespace openspace
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <modules/volume/rawvolume.h>
|
||||
|
||||
namespace openspace {
|
||||
namespace volume {
|
||||
|
||||
template <typename VoxelType>
|
||||
class RawVolumeWriter {
|
||||
@@ -51,6 +52,7 @@ private:
|
||||
size_t _bufferSize;
|
||||
};
|
||||
|
||||
} // namespace volume
|
||||
} // namespace openspace
|
||||
|
||||
#include "rawvolumewriter.inl"
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <modules/volume/volumeutils.h>
|
||||
|
||||
namespace openspace {
|
||||
namespace volume {
|
||||
|
||||
template <typename VoxelType>
|
||||
RawVolumeWriter<VoxelType>::RawVolumeWriter(std::string path, size_t bufferSize)
|
||||
@@ -35,12 +36,12 @@ RawVolumeWriter<VoxelType>::RawVolumeWriter(std::string path, size_t bufferSize)
|
||||
|
||||
template <typename VoxelType>
|
||||
size_t RawVolumeWriter<VoxelType>::coordsToIndex(const glm::uvec3& cartesian) const {
|
||||
return volumeutils::coordsToIndex(cartesian, dimensions());
|
||||
return coordsToIndex(cartesian, dimensions());
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
glm::ivec3 RawVolumeWriter<VoxelType>::indexToCoords(size_t linear) const {
|
||||
return volumeutils::indexToCoords(linear, dimensions());
|
||||
return indexToCoords(linear, dimensions());
|
||||
}
|
||||
|
||||
template <typename VoxelType>
|
||||
@@ -96,4 +97,5 @@ void RawVolumeWriter<VoxelType>::write(const RawVolume<VoxelType>& volume) {
|
||||
file.close();
|
||||
}
|
||||
|
||||
} // namespace volume
|
||||
} // namespace openspace
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/kameleonvolume/rendering/kameleonvolumeraycaster.h>
|
||||
#include <modules/volume/rendering/basicvolumeraycaster.h>
|
||||
|
||||
#include <ghoul/glm.h>
|
||||
#include <ghoul/opengl/ghoul_gl.h>
|
||||
@@ -32,44 +32,44 @@
|
||||
#include <openspace/util/powerscaledcoordinate.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <modules/kameleonvolume/rendering/renderablekameleonvolume.h>
|
||||
|
||||
namespace {
|
||||
const char* GlslRaycastPath = "${MODULES}/kameleonvolume/shaders/raycast.glsl";
|
||||
const char* GlslHelperPath = "${MODULES}/kameleonvolume/shaders/helper.glsl";
|
||||
const char* GlslBoundsVsPath = "${MODULES}/kameleonvolume/shaders/boundsvs.glsl";
|
||||
const char* GlslBoundsFsPath = "${MODULES}/kameleonvolume/shaders/boundsfs.glsl";
|
||||
} // namespace
|
||||
const char* GlslRaycastPath = "${MODULE_VOLUME}/shaders/raycast.glsl";
|
||||
const char* GlslHelperPath = "${MODULE_VOLUME}/shaders/helper.glsl";
|
||||
const char* GlslBoundsVsPath = "${MODULE_VOLUME}/shaders/boundsvs.glsl";
|
||||
const char* GlslBoundsFsPath = "${MODULE_VOLUME}/shaders/boundsfs.glsl";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
namespace volume {
|
||||
|
||||
KameleonVolumeRaycaster::KameleonVolumeRaycaster(
|
||||
std::shared_ptr<ghoul::opengl::Texture> texture,
|
||||
std::shared_ptr<TransferFunction> transferFunction,
|
||||
std::shared_ptr<VolumeClipPlanes> clipPlanes)
|
||||
: _clipPlanes(clipPlanes)
|
||||
, _volumeTexture(texture)
|
||||
BasicVolumeRaycaster::BasicVolumeRaycaster(
|
||||
std::shared_ptr<ghoul::opengl::Texture> volumeTexture,
|
||||
std::shared_ptr<TransferFunction> transferFunction,
|
||||
std::shared_ptr<VolumeClipPlanes> clipPlanes)
|
||||
: _volumeTexture(volumeTexture)
|
||||
, _transferFunction(transferFunction)
|
||||
, _clipPlanes(clipPlanes)
|
||||
, _boundingBox(glm::vec3(1.0))
|
||||
, _opacity(20.0)
|
||||
, _rNormalization(0.0)
|
||||
, _rUpperBound(1.0)
|
||||
, _valueRemapping(0.0, 1.0)
|
||||
{}
|
||||
|
||||
KameleonVolumeRaycaster::~KameleonVolumeRaycaster() {}
|
||||
|
||||
void KameleonVolumeRaycaster::initialize() {
|
||||
BasicVolumeRaycaster::~BasicVolumeRaycaster() {}
|
||||
|
||||
void BasicVolumeRaycaster::initialize() {
|
||||
_boundingBox.initialize();
|
||||
}
|
||||
|
||||
void KameleonVolumeRaycaster::deinitialize() {
|
||||
}
|
||||
void BasicVolumeRaycaster::deinitialize() {}
|
||||
|
||||
void KameleonVolumeRaycaster::renderEntryPoints(const RenderData& data, ghoul::opengl::ProgramObject& program) {
|
||||
glm::dmat4 modelTransform =
|
||||
glm::translate(glm::dmat4(1.0), data.modelTransform.translation) * // Translation
|
||||
glm::dmat4(data.modelTransform.rotation) * // Spice rotation
|
||||
glm::dmat4(glm::scale(glm::dmat4(_modelTransform), glm::dvec3(data.modelTransform.scale)));
|
||||
glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() * modelTransform;
|
||||
|
||||
program.setUniform("modelViewTransform", glm::mat4(modelViewTransform));
|
||||
void BasicVolumeRaycaster::renderEntryPoints(
|
||||
const RenderData& data,
|
||||
ghoul::opengl::ProgramObject& program)
|
||||
{
|
||||
program.setUniform("modelViewTransform", glm::mat4(modelViewTransform(data)));
|
||||
program.setUniform("projectionTransform", data.camera.projectionMatrix());
|
||||
|
||||
// Cull back face
|
||||
@@ -79,15 +79,23 @@ void KameleonVolumeRaycaster::renderEntryPoints(const RenderData& data, ghoul::o
|
||||
// Render bounding geometry
|
||||
_boundingBox.render();
|
||||
}
|
||||
|
||||
void KameleonVolumeRaycaster::renderExitPoints(const RenderData& data, ghoul::opengl::ProgramObject& program) {
|
||||
|
||||
glm::dmat4 BasicVolumeRaycaster::modelViewTransform(const RenderData& data) {
|
||||
glm::dmat4 modelTransform =
|
||||
glm::translate(glm::dmat4(1.0), data.modelTransform.translation) *
|
||||
glm::dmat4(data.modelTransform.rotation) *
|
||||
glm::dmat4(glm::scale(glm::dmat4(_modelTransform), glm::dvec3(data.modelTransform.scale)));
|
||||
glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() * modelTransform;
|
||||
glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale)) *
|
||||
glm::dmat4(_modelTransform);
|
||||
|
||||
program.setUniform("modelViewTransform", glm::mat4(modelViewTransform));
|
||||
return data.camera.combinedViewMatrix() * modelTransform;
|
||||
}
|
||||
|
||||
|
||||
void BasicVolumeRaycaster::renderExitPoints(
|
||||
const RenderData& data,
|
||||
ghoul::opengl::ProgramObject& program)
|
||||
{
|
||||
program.setUniform("modelViewTransform", glm::mat4(modelViewTransform(data)));
|
||||
program.setUniform("projectionTransform", data.camera.projectionMatrix());
|
||||
|
||||
// Cull front face
|
||||
@@ -101,7 +109,14 @@ void KameleonVolumeRaycaster::renderExitPoints(const RenderData& data, ghoul::op
|
||||
glCullFace(GL_BACK);
|
||||
}
|
||||
|
||||
void KameleonVolumeRaycaster::preRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) {
|
||||
void BasicVolumeRaycaster::preRaycast(
|
||||
const RaycastData& data,
|
||||
ghoul::opengl::ProgramObject& program)
|
||||
{
|
||||
if (!_volumeTexture || !_transferFunction) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string stepSizeUniformName = "maxStepSize" + std::to_string(data.id);
|
||||
program.setUniform(stepSizeUniformName, _stepSize);
|
||||
|
||||
@@ -126,56 +141,110 @@ void KameleonVolumeRaycaster::preRaycast(const RaycastData& data, ghoul::opengl:
|
||||
program.setUniform("nClips_" + id, nClips);
|
||||
program.setUniform("clipNormals_" + id, clipNormals.data(), nClips);
|
||||
program.setUniform("clipOffsets_" + id, clipOffsets.data(), nClips);
|
||||
program.setUniform("opacity_" + id, _opacity);
|
||||
program.setUniform("rNormalization_" + id, _rNormalization);
|
||||
program.setUniform("rUpperBound_" + id, _rUpperBound);
|
||||
program.setUniform("valueRemapping_" + id, _valueRemapping);
|
||||
}
|
||||
|
||||
void KameleonVolumeRaycaster::postRaycast(const RaycastData&,
|
||||
ghoul::opengl::ProgramObject&)
|
||||
void BasicVolumeRaycaster::postRaycast(const RaycastData&, ghoul::opengl::ProgramObject&)
|
||||
{
|
||||
// For example: release texture units
|
||||
_textureUnit = nullptr;
|
||||
_tfUnit = nullptr;
|
||||
}
|
||||
|
||||
bool KameleonVolumeRaycaster::cameraIsInside(const RenderData & data, glm::vec3 & localPosition)
|
||||
{
|
||||
glm::dmat4 modelTransform =
|
||||
glm::translate(glm::dmat4(1.0), data.modelTransform.translation) *
|
||||
glm::dmat4(data.modelTransform.rotation) *
|
||||
glm::dmat4(glm::scale(glm::dmat4(_modelTransform), glm::dvec3(data.modelTransform.scale)));
|
||||
glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() * modelTransform;
|
||||
|
||||
glm::vec4 modelPos = glm::inverse(modelViewTransform) * glm::vec4(0.0, 0.0, 0.0, 1.0);
|
||||
|
||||
bool BasicVolumeRaycaster::cameraIsInside(
|
||||
const RenderData & data,
|
||||
glm::vec3 & localPosition)
|
||||
{
|
||||
glm::vec4 modelPos =
|
||||
glm::inverse(modelViewTransform(data)) * glm::vec4(0.0, 0.0, 0.0, 1.0);
|
||||
|
||||
localPosition = (glm::vec3(modelPos) + glm::vec3(0.5));
|
||||
return (localPosition.x > 0 && localPosition.y > 0 && localPosition.z > 0 && localPosition.x < 1 && localPosition.y < 1 && localPosition.z < 1);
|
||||
|
||||
return (localPosition.x > 0 && localPosition.x < 1 &&
|
||||
localPosition.y > 0 && localPosition.y < 1 &&
|
||||
localPosition.z > 0 && localPosition.z < 1);
|
||||
}
|
||||
|
||||
std::string KameleonVolumeRaycaster::getBoundsVsPath() const {
|
||||
std::string BasicVolumeRaycaster::getBoundsVsPath() const {
|
||||
return GlslBoundsVsPath;
|
||||
}
|
||||
|
||||
std::string KameleonVolumeRaycaster::getBoundsFsPath() const {
|
||||
std::string BasicVolumeRaycaster::getBoundsFsPath() const {
|
||||
return GlslBoundsFsPath;
|
||||
}
|
||||
|
||||
std::string KameleonVolumeRaycaster::getRaycastPath() const {
|
||||
std::string BasicVolumeRaycaster::getRaycastPath() const {
|
||||
return GlslRaycastPath;
|
||||
}
|
||||
|
||||
std::string KameleonVolumeRaycaster::getHelperPath() const {
|
||||
std::string BasicVolumeRaycaster::getHelperPath() const {
|
||||
return GlslHelperPath;
|
||||
}
|
||||
|
||||
void KameleonVolumeRaycaster::setStepSize(float stepSize) {
|
||||
|
||||
void BasicVolumeRaycaster::setTransferFunction(
|
||||
std::shared_ptr<TransferFunction> transferFunction)
|
||||
{
|
||||
_transferFunction = transferFunction;
|
||||
}
|
||||
|
||||
void BasicVolumeRaycaster::setVolumeTexture(
|
||||
std::shared_ptr<ghoul::opengl::Texture> volumeTexture)
|
||||
{
|
||||
_volumeTexture = volumeTexture;
|
||||
}
|
||||
|
||||
std::shared_ptr<ghoul::opengl::Texture> BasicVolumeRaycaster::volumeTexture() const {
|
||||
return _volumeTexture;
|
||||
}
|
||||
|
||||
void BasicVolumeRaycaster::setStepSize(float stepSize) {
|
||||
_stepSize = stepSize;
|
||||
}
|
||||
|
||||
void KameleonVolumeRaycaster::setGridType(VolumeGridType gridType) {
|
||||
void BasicVolumeRaycaster::setOpacity(float opacity) {
|
||||
_opacity = opacity;
|
||||
}
|
||||
|
||||
float BasicVolumeRaycaster::opacity() const {
|
||||
return _opacity;
|
||||
}
|
||||
|
||||
void BasicVolumeRaycaster::setRNormalization(float rNormalization) {
|
||||
_rNormalization = rNormalization;
|
||||
}
|
||||
|
||||
float BasicVolumeRaycaster::rNormalization() const {
|
||||
return _rNormalization;
|
||||
}
|
||||
|
||||
void BasicVolumeRaycaster::setRUpperBound(float rUpperBound) {
|
||||
_rUpperBound = rUpperBound;
|
||||
}
|
||||
|
||||
float BasicVolumeRaycaster::rUpperBound() const {
|
||||
return _rUpperBound;
|
||||
}
|
||||
|
||||
void BasicVolumeRaycaster::setValueRemapping(float mapZeroTo, float mapOneTo) {
|
||||
_valueRemapping = glm::vec2(mapZeroTo, mapOneTo);
|
||||
}
|
||||
|
||||
VolumeGridType BasicVolumeRaycaster::gridType() const {
|
||||
return _gridType;
|
||||
}
|
||||
|
||||
void BasicVolumeRaycaster::setGridType(VolumeGridType gridType) {
|
||||
_gridType = gridType;
|
||||
}
|
||||
|
||||
void KameleonVolumeRaycaster::setModelTransform(const glm::mat4 & transform) {
|
||||
void BasicVolumeRaycaster::setModelTransform(const glm::mat4 & transform) {
|
||||
_modelTransform = transform;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace volume
|
||||
} // namespace openspace
|
||||
@@ -22,8 +22,8 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_KAMELEONVOLUME___KAMELEONVOLUMERAYCASTER___H__
|
||||
#define __OPENSPACE_MODULE_KAMELEONVOLUME___KAMELEONVOLUMERAYCASTER___H__
|
||||
#ifndef __OPENSPACE_MODULE_VOLUME___BASICVOLUMERAYCASTER___H__
|
||||
#define __OPENSPACE_MODULE_VOLUME___BASICVOLUMERAYCASTER___H__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -50,16 +50,18 @@ namespace openspace {
|
||||
struct RenderData;
|
||||
struct RaycastData;
|
||||
|
||||
class KameleonVolumeRaycaster : public VolumeRaycaster {
|
||||
namespace volume {
|
||||
|
||||
class BasicVolumeRaycaster : public VolumeRaycaster {
|
||||
public:
|
||||
KameleonVolumeRaycaster(
|
||||
BasicVolumeRaycaster(
|
||||
std::shared_ptr<ghoul::opengl::Texture> texture,
|
||||
std::shared_ptr<TransferFunction> transferFunction,
|
||||
std::shared_ptr<VolumeClipPlanes> clipPlanes);
|
||||
|
||||
virtual ~KameleonVolumeRaycaster();
|
||||
virtual ~BasicVolumeRaycaster();
|
||||
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;
|
||||
@@ -71,23 +73,42 @@ public:
|
||||
std::string getRaycastPath() const override;
|
||||
std::string getHelperPath() const override;
|
||||
|
||||
void setVolumeTexture(std::shared_ptr<ghoul::opengl::Texture> texture);
|
||||
std::shared_ptr<ghoul::opengl::Texture> volumeTexture() const;
|
||||
void setTransferFunction(std::shared_ptr<TransferFunction> transferFunction);
|
||||
void setStepSize(float stepSize);
|
||||
float opacity() const;
|
||||
void setOpacity(float opacity);
|
||||
float rNormalization() const;
|
||||
void setRNormalization(float rNormalization);
|
||||
float rUpperBound() const;
|
||||
void setRUpperBound(float rNormalization);
|
||||
void setValueRemapping(float mapZeroTo, float mapOneTo);
|
||||
VolumeGridType gridType() const;
|
||||
void setGridType(VolumeGridType gridType);
|
||||
void setModelTransform(const glm::mat4& transform);
|
||||
|
||||
|
||||
private:
|
||||
glm::dmat4 modelViewTransform(const RenderData& data);
|
||||
|
||||
std::shared_ptr<VolumeClipPlanes> _clipPlanes;
|
||||
std::shared_ptr<ghoul::opengl::Texture> _volumeTexture;
|
||||
std::shared_ptr<TransferFunction> _transferFunction;
|
||||
BoxGeometry _boundingBox;
|
||||
VolumeGridType _gridType;
|
||||
glm::mat4 _modelTransform;
|
||||
float _opacity;
|
||||
float _rNormalization;
|
||||
float _rUpperBound;
|
||||
glm::vec2 _valueRemapping;
|
||||
|
||||
std::unique_ptr<ghoul::opengl::TextureUnit> _tfUnit;
|
||||
std::unique_ptr<ghoul::opengl::TextureUnit> _textureUnit;
|
||||
float _stepSize;
|
||||
};
|
||||
|
||||
} // namespace volume
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_KAMELEONVOLUME___KAMELEONVOLUMERAYCASTER___H__
|
||||
|
||||
#endif // __OPENSPACE_MODULE_VOLUME___BASICVOLUMERAYCASTER___H__
|
||||
473
modules/volume/rendering/renderabletimevaryingvolume.cpp
Normal file
473
modules/volume/rendering/renderabletimevaryingvolume.cpp
Normal file
@@ -0,0 +1,473 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/volume/rendering/renderabletimevaryingvolume.h>
|
||||
#include <modules/volume/rawvolumereader.h>
|
||||
#include <modules/volume/rawvolume.h>
|
||||
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/rendering/raycastermanager.h>
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/util/timemanager.h>
|
||||
#include <openspace/util/time.h>
|
||||
|
||||
#include <ghoul/glm.h>
|
||||
#include <ghoul/opengl/ghoul_gl.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/filesystem/cachemanager.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
namespace {
|
||||
const char* _loggerCat = "RenderableTimeVaryingVolume";
|
||||
}
|
||||
|
||||
namespace {
|
||||
const char* KeyDimensions = "Dimensions";
|
||||
const char* KeyStepSize = "StepSize";
|
||||
const char* KeyTransferFunction = "TransferFunction";
|
||||
const char* KeySourceDirectory = "SourceDirectory";
|
||||
const char* KeyLowerDomainBound = "LowerDomainBound";
|
||||
const char* KeyUpperDomainBound = "UpperDomainBound";
|
||||
const char* KeyLowerValueBound = "LowerValueBound";
|
||||
const char* KeyUpperValueBound = "UpperValueBound";
|
||||
const char* KeyClipPlanes = "ClipPlanes";
|
||||
const char* KeySecondsBefore = "SecondsBefore";
|
||||
const char* KeySecondsAfter = "SecondsAfter";
|
||||
const char* KeyGridType = "GridType";
|
||||
const char* KeyMinValue = "MinValue";
|
||||
const char* KeyMaxValue = "MaxValue";
|
||||
const char* KeyTime = "Time";
|
||||
const float SecondsInOneDay = 60 * 60 * 24;
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
namespace volume {
|
||||
|
||||
RenderableTimeVaryingVolume::RenderableTimeVaryingVolume(const ghoul::Dictionary& dictionary)
|
||||
: Renderable(dictionary)
|
||||
, _clipPlanes(nullptr)
|
||||
, _stepSize({ "stepSize", "Step Size", "" }, 0.02, 0.01, 1)
|
||||
, _gridType({ "gridType", "Grid Type", "" }, properties::OptionProperty::DisplayType::Dropdown)
|
||||
, _secondsBefore({ "secondsBefore", "Seconds before", "" }, 0.0, 0.01, SecondsInOneDay)
|
||||
, _secondsAfter({ "secondsAfter", "Seconds after", "" }, 0.0, 0.01, SecondsInOneDay)
|
||||
, _sourceDirectory({ "sourceDirectory", "Source Directory", "" })
|
||||
, _transferFunctionPath({"transferFunctionPath", "Transfer Function Path", "" })
|
||||
, _triggerTimeJump({"triggerTimeJump", "Jump", "" })
|
||||
, _jumpToTimestep({"jumpToTimestep", "Jump to timestep", "" }, 0, 0, 256)
|
||||
, _currentTimestep({"currentTimestep", "Current timestep", "" }, 0, 0, 256)
|
||||
, _opacity({"opacity", "Opacity", "" }, 10.0f, 0.0f, 50.0f)
|
||||
, _rNormalization({"rNormalization", "Radius normalization", "" }, 0.0f, 0.0f, 2.0f)
|
||||
, _rUpperBound({"rUpperBound", "Radius upper bound", "" }, 1.0f, 0.0f, 2.0f)
|
||||
, _lowerValueBound({"lowerValueBound", "Lower value bound", "" }, 0.0f, 0.0f, 1000000.0f)
|
||||
, _upperValueBound({"upperValueBound", "Upper value bound", "" }, 0.0f, 0.0f, 1000000.0f)
|
||||
, _raycaster(nullptr)
|
||||
, _transferFunction(nullptr)
|
||||
{
|
||||
documentation::testSpecificationAndThrow(
|
||||
Documentation(),
|
||||
dictionary,
|
||||
"RenderableTimeVaryingVolume"
|
||||
);
|
||||
|
||||
_sourceDirectory = absPath(dictionary.value<std::string>(KeySourceDirectory));
|
||||
_transferFunctionPath = absPath(dictionary.value<std::string>(KeyTransferFunction));
|
||||
_lowerValueBound = dictionary.value<float>(KeyLowerValueBound);
|
||||
_upperValueBound = dictionary.value<float>(KeyUpperValueBound);
|
||||
_transferFunction = std::make_shared<TransferFunction>(_transferFunctionPath);
|
||||
|
||||
_gridType.addOption(static_cast<int>(volume::VolumeGridType::Cartesian), "Cartesian grid");
|
||||
_gridType.addOption(static_cast<int>(volume::VolumeGridType::Spherical), "Spherical grid");
|
||||
_gridType.setValue(static_cast<int>(volume::VolumeGridType::Cartesian));
|
||||
|
||||
|
||||
if (dictionary.hasValue<float>(KeySecondsBefore)) {
|
||||
_secondsBefore = dictionary.value<float>(KeySecondsBefore);
|
||||
}
|
||||
_secondsAfter = dictionary.value<float>(KeySecondsAfter);
|
||||
|
||||
ghoul::Dictionary clipPlanesDictionary;
|
||||
dictionary.getValue(KeyClipPlanes, clipPlanesDictionary);
|
||||
_clipPlanes = std::make_shared<volume::VolumeClipPlanes>(clipPlanesDictionary);
|
||||
_clipPlanes->setName("clipPlanes");
|
||||
|
||||
if (dictionary.hasValue<std::string>(KeyGridType)) {
|
||||
VolumeGridType gridType = volume::parseGridType(dictionary.value<std::string>(KeyGridType));
|
||||
_gridType = (gridType == VolumeGridType::Spherical) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
RenderableTimeVaryingVolume::~RenderableTimeVaryingVolume() {}
|
||||
|
||||
void RenderableTimeVaryingVolume::initialize() {
|
||||
|
||||
using RawPath = ghoul::filesystem::Directory::RawPath;
|
||||
ghoul::filesystem::Directory sequenceDir(_sourceDirectory, RawPath::Yes);
|
||||
|
||||
if (!FileSys.directoryExists(sequenceDir)) {
|
||||
LERROR("Could not load sequence directory '" << sequenceDir.path() << "'");
|
||||
return;
|
||||
}
|
||||
|
||||
using Recursive = ghoul::filesystem::Directory::Recursive;
|
||||
using Sort = ghoul::filesystem::Directory::Sort;
|
||||
|
||||
std::vector<std::string> sequencePaths = sequenceDir.read(Recursive::Yes, Sort::No);
|
||||
for (auto path : sequencePaths) {
|
||||
ghoul::filesystem::File currentFile(path);
|
||||
std::string extension = currentFile.fileExtension();
|
||||
if (extension == "dictionary") {
|
||||
loadTimestepMetadata(path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO: defer loading of data to later. (separate thread or at least not when loading)
|
||||
for (auto& p : _volumeTimesteps) {
|
||||
Timestep& t = p.second;
|
||||
std::string path = FileSys.pathByAppendingComponent(_sourceDirectory, t.baseName) + ".rawvolume";
|
||||
RawVolumeReader<float> reader(path, t.dimensions);
|
||||
t.rawVolume = reader.read();
|
||||
|
||||
float min = t.minValue;
|
||||
float diff = t.maxValue - t.minValue;
|
||||
|
||||
float *data = t.rawVolume->data();
|
||||
for (size_t i = 0; i < t.rawVolume->nCells(); ++i) {
|
||||
data[i] = glm::clamp((data[i] - min) / diff, 0.0f, 1.0f);
|
||||
}
|
||||
// TODO: handle normalization properly for different timesteps + transfer function
|
||||
|
||||
t.texture = std::make_shared<ghoul::opengl::Texture>(
|
||||
t.dimensions,
|
||||
ghoul::opengl::Texture::Format::Red,
|
||||
GL_RED,
|
||||
GL_FLOAT,
|
||||
ghoul::opengl::Texture::FilterMode::Linear,
|
||||
ghoul::opengl::Texture::WrappingMode::Clamp
|
||||
);
|
||||
|
||||
t.texture->setPixelData(reinterpret_cast<void*>(data), ghoul::opengl::Texture::TakeOwnership::No);
|
||||
t.texture->uploadTexture();
|
||||
}
|
||||
|
||||
_clipPlanes->initialize();
|
||||
_transferFunction->update();
|
||||
_raycaster = std::make_unique<volume::BasicVolumeRaycaster>(nullptr, _transferFunction, _clipPlanes);
|
||||
_raycaster->initialize();
|
||||
OsEng.renderEngine().raycasterManager().attachRaycaster(*_raycaster.get());
|
||||
auto onChange = [&](bool enabled) {
|
||||
if (enabled) {
|
||||
OsEng.renderEngine().raycasterManager().attachRaycaster(*_raycaster.get());
|
||||
} else {
|
||||
OsEng.renderEngine().raycasterManager().detachRaycaster(*_raycaster.get());
|
||||
}
|
||||
};
|
||||
onEnabledChange(onChange);
|
||||
|
||||
_triggerTimeJump.onChange([this] () {
|
||||
jumpToTimestep(_jumpToTimestep);
|
||||
});
|
||||
|
||||
_jumpToTimestep.onChange([this] () {
|
||||
jumpToTimestep(_jumpToTimestep);
|
||||
});
|
||||
|
||||
const int lastTimestep = (_volumeTimesteps.size() > 0) ? (_volumeTimesteps.size() - 1) : 0;
|
||||
_currentTimestep.setMaxValue(lastTimestep);
|
||||
_jumpToTimestep.setMaxValue(lastTimestep);
|
||||
|
||||
addProperty(_stepSize);
|
||||
addProperty(_transferFunctionPath);
|
||||
addProperty(_sourceDirectory);
|
||||
addPropertySubOwner(_clipPlanes.get());
|
||||
addProperty(_triggerTimeJump);
|
||||
addProperty(_jumpToTimestep);
|
||||
addProperty(_currentTimestep);
|
||||
addProperty(_opacity);
|
||||
addProperty(_rNormalization);
|
||||
addProperty(_rUpperBound);
|
||||
addProperty(_lowerValueBound);
|
||||
addProperty(_upperValueBound);
|
||||
|
||||
_raycaster->setGridType((_gridType.value() == 1) ? VolumeGridType::Spherical : VolumeGridType::Cartesian);
|
||||
_gridType.onChange([this] {
|
||||
_raycaster->setGridType((_gridType.value() == 1) ? VolumeGridType::Spherical : VolumeGridType::Cartesian);
|
||||
});
|
||||
}
|
||||
|
||||
void RenderableTimeVaryingVolume::loadTimestepMetadata(const std::string& path) {
|
||||
ghoul::Dictionary dictionary = ghoul::lua::loadDictionaryFromFile(path);
|
||||
try {
|
||||
documentation::testSpecificationAndThrow(TimestepDocumentation(), dictionary, "TimeVaryingVolumeTimestep");
|
||||
} catch (const documentation::SpecificationError& e) {
|
||||
LERROR(e.message << e.component);
|
||||
return;
|
||||
}
|
||||
|
||||
Timestep t;
|
||||
t.baseName = ghoul::filesystem::File(path).baseName();
|
||||
t.dimensions = dictionary.value<glm::vec3>(KeyDimensions);
|
||||
t.lowerDomainBound = dictionary.value<glm::vec3>(KeyLowerDomainBound);
|
||||
t.upperDomainBound = dictionary.value<glm::vec3>(KeyUpperDomainBound);
|
||||
t.minValue = dictionary.value<float>(KeyMinValue);
|
||||
t.maxValue = dictionary.value<float>(KeyMaxValue);
|
||||
|
||||
std::string timeString = dictionary.value<std::string>(KeyTime);
|
||||
t.time = Time::convertTime(timeString);
|
||||
t.inRam = false;
|
||||
t.onGpu = false;
|
||||
|
||||
_volumeTimesteps[t.time] = std::move(t);
|
||||
}
|
||||
|
||||
RenderableTimeVaryingVolume::Timestep* RenderableTimeVaryingVolume::currentTimestep() {
|
||||
if (_volumeTimesteps.size() == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
double currentTime = OsEng.timeManager().time().j2000Seconds();
|
||||
|
||||
// Get the first item with time > currentTime
|
||||
auto currentTimestepIt = _volumeTimesteps.upper_bound(currentTime);
|
||||
if (currentTimestepIt == _volumeTimesteps.end()) {
|
||||
// No such timestep was found: show last timestep if it is within the time margin.
|
||||
RenderableTimeVaryingVolume::Timestep* lastTimestep = &(_volumeTimesteps.rbegin()->second);
|
||||
double threshold = lastTimestep->time + static_cast<double>(_secondsAfter);
|
||||
return currentTime < threshold ? lastTimestep : nullptr;
|
||||
}
|
||||
|
||||
if (currentTimestepIt == _volumeTimesteps.begin()) {
|
||||
// No such timestep was found: show first timestep if it is within the time margin.
|
||||
RenderableTimeVaryingVolume::Timestep* firstTimestep = &(_volumeTimesteps.begin()->second);
|
||||
double threshold = firstTimestep->time - static_cast<double>(_secondsBefore);
|
||||
return currentTime >= threshold ? firstTimestep : nullptr;
|
||||
}
|
||||
|
||||
// Get the last item with time <= currentTime
|
||||
currentTimestepIt--;
|
||||
return &(currentTimestepIt->second);
|
||||
}
|
||||
|
||||
int RenderableTimeVaryingVolume::timestepIndex(const RenderableTimeVaryingVolume::Timestep* t) const {
|
||||
if (!t) {
|
||||
return -1;
|
||||
}
|
||||
int index = 0;
|
||||
for (auto& it : _volumeTimesteps) {
|
||||
if (&(it.second) == t) {
|
||||
return index;
|
||||
}
|
||||
++index;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
RenderableTimeVaryingVolume::Timestep* RenderableTimeVaryingVolume::timestepFromIndex(int target) {
|
||||
if (target < 0) target = 0;
|
||||
int index = 0;
|
||||
for (auto& it : _volumeTimesteps) {
|
||||
if (index == target) {
|
||||
return &(it.second);
|
||||
}
|
||||
++index;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void RenderableTimeVaryingVolume::jumpToTimestep(int target) {
|
||||
Timestep* t = timestepFromIndex(target);
|
||||
if (!t) {
|
||||
return;
|
||||
}
|
||||
OsEng.timeManager().setTimeNextFrame(t->time);
|
||||
}
|
||||
|
||||
void RenderableTimeVaryingVolume::update(const UpdateData& data) {
|
||||
if (_raycaster) {
|
||||
Timestep* t = currentTimestep();
|
||||
_currentTimestep = timestepIndex(t);
|
||||
if (t && t->texture) {
|
||||
if (_raycaster->gridType() == volume::VolumeGridType::Cartesian) {
|
||||
glm::dvec3 scale = t->upperDomainBound - t->lowerDomainBound;
|
||||
glm::dvec3 translation = (t->lowerDomainBound + t->upperDomainBound) * 0.5f;
|
||||
|
||||
glm::dmat4 modelTransform = glm::translate(glm::dmat4(1.0), translation);
|
||||
glm::dmat4 scaleMatrix = glm::scale(glm::dmat4(1.0), scale);
|
||||
modelTransform = modelTransform * scaleMatrix;
|
||||
_raycaster->setModelTransform(glm::mat4(modelTransform));
|
||||
} else {
|
||||
_raycaster->setModelTransform(
|
||||
glm::scale(
|
||||
glm::dmat4(1.0),
|
||||
glm::dvec3(t->upperDomainBound[0])
|
||||
)
|
||||
);
|
||||
}
|
||||
_raycaster->setVolumeTexture(t->texture);
|
||||
|
||||
// Remap volume value to that TF value 0 is sampled for lowerValueBound, and 1 is sampled for upperLowerBound.
|
||||
// This means that volume values = 0 need to be remapped to how localMin relates to the global range.
|
||||
float zeroMap = (t->minValue - _lowerValueBound) / (_upperValueBound - _lowerValueBound);
|
||||
|
||||
// Volume values = 1 are mapped to how localMax relates to the global range.
|
||||
float oneMap = (t->maxValue - _lowerValueBound) / (_upperValueBound - _lowerValueBound);
|
||||
_raycaster->setValueRemapping(zeroMap, oneMap);
|
||||
} else {
|
||||
_raycaster->setVolumeTexture(nullptr);
|
||||
}
|
||||
_raycaster->setStepSize(_stepSize);
|
||||
_raycaster->setOpacity(_opacity);
|
||||
_raycaster->setRNormalization(_rNormalization);
|
||||
_raycaster->setRUpperBound(_rUpperBound);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableTimeVaryingVolume::render(const RenderData& data, RendererTasks& tasks) {
|
||||
if (_raycaster && _raycaster->volumeTexture()) {
|
||||
tasks.raycasterTasks.push_back({ _raycaster.get(), data });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool RenderableTimeVaryingVolume::isReady() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void RenderableTimeVaryingVolume::deinitialize() {
|
||||
if (_raycaster) {
|
||||
OsEng.renderEngine().raycasterManager().detachRaycaster(*_raycaster.get());
|
||||
_raycaster = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
documentation::Documentation RenderableTimeVaryingVolume::Documentation() {
|
||||
using namespace documentation;
|
||||
return {
|
||||
"RenderableTimevaryingVolume",
|
||||
"volume_renderable_timevaryingvolume",
|
||||
{
|
||||
{
|
||||
KeySourceDirectory,
|
||||
new StringVerifier,
|
||||
Optional::No,
|
||||
"Specifies the path to load timesteps from"
|
||||
},
|
||||
{
|
||||
KeyTransferFunction,
|
||||
new StringVerifier,
|
||||
Optional::No,
|
||||
"Specifies the transfer function file path",
|
||||
},
|
||||
{
|
||||
KeyLowerValueBound,
|
||||
new DoubleVerifier,
|
||||
Optional::No,
|
||||
"Specifies the lower value bound."
|
||||
"This number will be mapped to 0 before uploadin to the GPU.",
|
||||
},
|
||||
{
|
||||
KeyUpperValueBound,
|
||||
new DoubleVerifier,
|
||||
Optional::No,
|
||||
"Specifies the lower value bound."
|
||||
"This number will be mapped to 0 before uploadin to the GPU."
|
||||
},
|
||||
{
|
||||
KeyGridType,
|
||||
new StringInListVerifier({"Cartesian", "Spherical"}),
|
||||
Optional::Yes,
|
||||
"Specifies the grid type"
|
||||
},
|
||||
{
|
||||
KeySecondsBefore,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
"Specifies the number of seconds to show the the first timestep before its actual time."
|
||||
"The default value is 0.",
|
||||
},
|
||||
{
|
||||
KeySecondsAfter,
|
||||
new DoubleVerifier,
|
||||
Optional::No,
|
||||
"Specifies the number of seconds to show the the last timestep after its actual time",
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
documentation::Documentation RenderableTimeVaryingVolume::TimestepDocumentation() {
|
||||
using namespace documentation;
|
||||
return {
|
||||
"TimevaryingVolumeTimestep",
|
||||
"volume_timevaryingvolumetimestep",
|
||||
{
|
||||
{
|
||||
KeyLowerDomainBound,
|
||||
new Vector3Verifier<float>,
|
||||
Optional::No,
|
||||
"Specifies the lower domain bounds in the model coordinate system",
|
||||
},
|
||||
{
|
||||
KeyUpperDomainBound,
|
||||
new Vector3Verifier<float>,
|
||||
Optional::No,
|
||||
"Specifies the upper domain bounds in the model coordinate system",
|
||||
},
|
||||
{
|
||||
KeyDimensions,
|
||||
new Vector3Verifier<float>,
|
||||
Optional::No,
|
||||
"Specifies the number of grid cells in each dimension",
|
||||
},
|
||||
{
|
||||
KeyTime,
|
||||
new StringVerifier,
|
||||
Optional::No,
|
||||
"Specifies the time on the format YYYY-MM-DDTHH:MM:SS.000Z",
|
||||
},
|
||||
{
|
||||
KeyMinValue,
|
||||
new DoubleVerifier,
|
||||
Optional::No,
|
||||
"Specifies the minimum value stored in the volume"
|
||||
},
|
||||
{
|
||||
KeyMaxValue,
|
||||
new DoubleVerifier,
|
||||
Optional::No,
|
||||
"Specifies the maximum value stored in the volume"
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace volume
|
||||
} // namespace openspace
|
||||
109
modules/volume/rendering/renderabletimevaryingvolume.h
Normal file
109
modules/volume/rendering/renderabletimevaryingvolume.h
Normal file
@@ -0,0 +1,109 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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_MODULE_VOLUME___RENDERABLEKAMELEONVOLUME___H__
|
||||
#define __OPENSPACE_MODULE_VOLUME___RENDERABLEKAMELEONVOLUME___H__
|
||||
|
||||
#include <openspace/rendering/renderable.h>
|
||||
|
||||
#include <modules/volume/rawvolume.h>
|
||||
#include <modules/volume/rendering/basicvolumeraycaster.h>
|
||||
#include <modules/volume/rendering/volumeclipplanes.h>
|
||||
|
||||
#include <openspace/properties/vectorproperty.h>
|
||||
#include <openspace/properties/optionproperty.h>
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
#include <openspace/rendering/transferfunction.h>
|
||||
#include <openspace/util/boxgeometry.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
struct RenderData;
|
||||
|
||||
namespace volume {
|
||||
|
||||
class RenderableTimeVaryingVolume : public Renderable {
|
||||
public:
|
||||
RenderableTimeVaryingVolume(const ghoul::Dictionary& dictionary);
|
||||
~RenderableTimeVaryingVolume();
|
||||
|
||||
void initialize() override;
|
||||
void deinitialize() override;
|
||||
bool isReady() const override;
|
||||
void render(const RenderData& data, RendererTasks& tasks) override;
|
||||
void update(const UpdateData& data) override;
|
||||
|
||||
static documentation::Documentation Documentation();
|
||||
static documentation::Documentation TimestepDocumentation();
|
||||
|
||||
private:
|
||||
struct Timestep {
|
||||
std::string baseName;
|
||||
double time;
|
||||
float minValue;
|
||||
float maxValue;
|
||||
glm::uvec3 dimensions;
|
||||
glm::vec3 lowerDomainBound;
|
||||
glm::vec3 upperDomainBound;
|
||||
bool inRam;
|
||||
bool onGpu;
|
||||
std::unique_ptr<RawVolume<float>> rawVolume;
|
||||
std::shared_ptr<ghoul::opengl::Texture> texture;
|
||||
};
|
||||
|
||||
Timestep* currentTimestep();
|
||||
int timestepIndex(const Timestep* t) const;
|
||||
Timestep* timestepFromIndex(int index);
|
||||
void jumpToTimestep(int i);
|
||||
|
||||
void loadTimestepMetadata(const std::string& path);
|
||||
|
||||
properties::OptionProperty _gridType;
|
||||
std::shared_ptr<VolumeClipPlanes> _clipPlanes;
|
||||
|
||||
properties::FloatProperty _stepSize;
|
||||
properties::FloatProperty _opacity;
|
||||
properties::FloatProperty _rNormalization;
|
||||
properties::FloatProperty _rUpperBound;
|
||||
properties::FloatProperty _secondsBefore;
|
||||
properties::FloatProperty _secondsAfter;
|
||||
properties::StringProperty _sourceDirectory;
|
||||
properties::StringProperty _transferFunctionPath;
|
||||
properties::FloatProperty _lowerValueBound;
|
||||
properties::FloatProperty _upperValueBound;
|
||||
|
||||
properties::TriggerProperty _triggerTimeJump;
|
||||
properties::IntProperty _jumpToTimestep;
|
||||
properties::IntProperty _currentTimestep;
|
||||
|
||||
std::map<double, Timestep> _volumeTimesteps;
|
||||
std::unique_ptr<BasicVolumeRaycaster> _raycaster;
|
||||
|
||||
std::shared_ptr<TransferFunction> _transferFunction;
|
||||
};
|
||||
|
||||
} // namespace volume
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_KAMELEONVOLUME___RENDERABLEKAMELEONVOLUME___H__
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
@@ -28,6 +27,7 @@
|
||||
|
||||
|
||||
namespace openspace {
|
||||
namespace volume {
|
||||
|
||||
VolumeClipPlane::VolumeClipPlane(const ghoul::Dictionary& dictionary)
|
||||
: properties::PropertyOwner({ "" }) // @TODO Missing name
|
||||
@@ -66,4 +66,5 @@ glm::vec2 VolumeClipPlane::offsets() {
|
||||
return _offsets;
|
||||
}
|
||||
|
||||
} // namespace volume
|
||||
} // namespace openspace
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
namespace ghoul { class Dictionary; }
|
||||
|
||||
namespace openspace {
|
||||
namespace volume {
|
||||
|
||||
class VolumeClipPlane : public properties::PropertyOwner {
|
||||
public:
|
||||
@@ -45,6 +46,7 @@ private:
|
||||
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
} // namespace volume
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_VOLUME___VOLUMECLIPPLANE___H__
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
|
||||
namespace openspace {
|
||||
namespace volume {
|
||||
|
||||
VolumeClipPlanes::VolumeClipPlanes(const ghoul::Dictionary& dictionary)
|
||||
: properties::PropertyOwner({ "" }) // @TODO Missing name
|
||||
@@ -70,4 +71,5 @@ std::vector<glm::vec2> VolumeClipPlanes::offsets() {
|
||||
return offsets;
|
||||
}
|
||||
|
||||
} // namespace volume
|
||||
} // namespace openspace
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
namespace ghoul { class Dictionary; }
|
||||
|
||||
namespace openspace {
|
||||
namespace volume {
|
||||
|
||||
class VolumeClipPlanes : public properties::PropertyOwner {
|
||||
public:
|
||||
@@ -51,6 +52,7 @@ private:
|
||||
std::vector<std::shared_ptr<VolumeClipPlane>> _clipPlanes;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
} // namepsace volume
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_VOLUME___VOLUMECLIPPLANES___H__
|
||||
|
||||
@@ -22,20 +22,21 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#define KAMELEON_PI 3.14159265358979323846 /* pi */
|
||||
#define KAMELEON_SQRT1_3 0.57735026919 /* 1/sqrt(3) */
|
||||
#define VOLUME_PI 3.14159265358979323846 /* pi */
|
||||
#define VOLUME_SQRT1_3 0.57735026919 /* 1/sqrt(3) */
|
||||
|
||||
vec3 kameleon_cartesianToSpherical(vec3 zeroToOneCoords) {
|
||||
vec3 volume_cartesianToSpherical(vec3 zeroToOneCoords) {
|
||||
// Put cartesian in [-1..1] range first
|
||||
vec3 cartesian = vec3(-1.0,-1.0,-1.0) + zeroToOneCoords * 2.0f;
|
||||
|
||||
float r = length(cartesian);
|
||||
|
||||
float theta = 0.0;
|
||||
float phi = 0.0;
|
||||
|
||||
if (r != 0.0) {
|
||||
theta = acos(cartesian.z / r) / KAMELEON_PI;
|
||||
phi = (KAMELEON_PI + atan(cartesian.y, cartesian.x)) / (2.0 * KAMELEON_PI );
|
||||
theta = acos(cartesian.z / r) / VOLUME_PI;
|
||||
phi = (VOLUME_PI + atan(cartesian.y, cartesian.x)) / (2.0 * VOLUME_PI );
|
||||
}
|
||||
return vec3(r * KAMELEON_SQRT1_3, theta, phi);
|
||||
return vec3(r * VOLUME_SQRT1_3, theta, phi);
|
||||
}
|
||||
@@ -31,6 +31,20 @@ uniform int nClips_#{id};
|
||||
uniform vec3 clipNormals_#{id}[8];
|
||||
uniform vec2 clipOffsets_#{id}[8];
|
||||
|
||||
uniform float opacity_#{id} = 10.0;
|
||||
|
||||
// Value remapping:
|
||||
// Linearly remap volume values of zero to x and one to y
|
||||
// before using the values to sample the transfer function.
|
||||
uniform vec2 valueRemapping_#{id} = vec2(0.0, 1.0);
|
||||
|
||||
// Normalization factor x for radius r [0, 1].
|
||||
// value *= 1/(r^x)
|
||||
// only working for volumes given in spherical coordianates.
|
||||
// Applied after any linear value remapping.
|
||||
uniform float rNormalization_#{id} = 0.0;
|
||||
|
||||
uniform float rUpperBound_#{id} = 1.0;
|
||||
|
||||
void sample#{id}(vec3 samplePos, vec3 dir, inout vec3 accumulatedColor,
|
||||
inout vec3 accumulatedAlpha, inout float stepSize)
|
||||
@@ -38,7 +52,7 @@ void sample#{id}(vec3 samplePos, vec3 dir, inout vec3 accumulatedColor,
|
||||
|
||||
vec3 transformedPos = samplePos;
|
||||
if (gridType_#{id} == 1) {
|
||||
transformedPos = kameleon_cartesianToSpherical(samplePos);
|
||||
transformedPos = volume_cartesianToSpherical(samplePos);
|
||||
}
|
||||
|
||||
float clipAlpha = 1.0;
|
||||
@@ -52,14 +66,23 @@ void sample#{id}(vec3 samplePos, vec3 dir, inout vec3 accumulatedColor,
|
||||
clipAlpha *= smoothstep(clipBegin, clipEnd, dot(centerToPos, clipNormal));
|
||||
}
|
||||
|
||||
clipAlpha *= 1.0 - smoothstep(rUpperBound_#{id} - 0.01, rUpperBound_#{id} + 0.01, transformedPos.x);
|
||||
|
||||
if (clipAlpha > 0) {
|
||||
float val = texture(volumeTexture_#{id}, transformedPos).r;
|
||||
|
||||
val = mix(valueRemapping_#{id}.x, valueRemapping_#{id}.y, val);
|
||||
|
||||
if (rNormalization_#{id} > 0 && gridType_#{id} == 1) {
|
||||
val *= pow(transformedPos.x, rNormalization_#{id});
|
||||
}
|
||||
|
||||
vec4 color = texture(transferFunction_#{id}, val);
|
||||
vec3 backColor = color.rgb;
|
||||
vec3 backAlpha = color.aaa;
|
||||
|
||||
backColor *= stepSize * clipAlpha;
|
||||
backAlpha *= stepSize * clipAlpha;
|
||||
backColor *= stepSize*opacity_#{id} * clipAlpha;
|
||||
backAlpha *= stepSize*opacity_#{id} * clipAlpha;
|
||||
|
||||
backColor = clamp(backColor, 0.0, 1.0);
|
||||
backAlpha = clamp(backAlpha, 0.0, 1.0);
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <unordered_map>
|
||||
|
||||
namespace openspace {
|
||||
namespace volume {
|
||||
|
||||
template <typename Type>
|
||||
class TextureSliceVolumeReader {
|
||||
@@ -53,6 +54,7 @@ private:
|
||||
bool _initialized;
|
||||
};
|
||||
|
||||
} // namespace volume
|
||||
} // namespace openspace
|
||||
|
||||
#include "textureslicevolumereader.inl"
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <ghoul/io/texture/texturereader.h>
|
||||
|
||||
namespace openspace {
|
||||
namespace volume {
|
||||
|
||||
template <typename VoxelType>
|
||||
VoxelType TextureSliceVolumeReader<VoxelType>::get(const glm::ivec3& coordinates) const {
|
||||
@@ -81,4 +82,5 @@ ghoul::opengl::Texture& TextureSliceVolumeReader<VoxelType>::getSlice(int sliceI
|
||||
return *_cache.get(sliceIndex).get();
|
||||
}
|
||||
|
||||
} // namespace volume
|
||||
} // namespace openspace
|
||||
|
||||
48
modules/volume/volumegridtype.cpp
Normal file
48
modules/volume/volumegridtype.cpp
Normal file
@@ -0,0 +1,48 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/volume/volumegridtype.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace openspace {
|
||||
namespace volume {
|
||||
|
||||
VolumeGridType parseGridType(const std::string& gridType) {
|
||||
if (gridType == "Cartesian") {
|
||||
return VolumeGridType::Cartesian;
|
||||
}
|
||||
if (gridType == "Spherical") {
|
||||
return VolumeGridType::Spherical;
|
||||
}
|
||||
throw InvalidGridTypeError(gridType);
|
||||
}
|
||||
|
||||
InvalidGridTypeError::InvalidGridTypeError(std::string gt)
|
||||
: RuntimeError("Invalid grid type: '" + gt + "'")
|
||||
, gridType(std::move(gt))
|
||||
{}
|
||||
|
||||
} // namespace volume
|
||||
} // namespace openspace
|
||||
@@ -25,13 +25,24 @@
|
||||
#ifndef __OPENSPACE_MODULE_VOLUME___VOLUMEGRIDTYPE_H__
|
||||
#define __OPENSPACE_MODULE_VOLUME___VOLUMEGRIDTYPE_H__
|
||||
|
||||
#include <ghoul/misc/exception.h>
|
||||
|
||||
namespace openspace {
|
||||
namespace volume {
|
||||
|
||||
enum class VolumeGridType : int {
|
||||
Cartesian = 0,
|
||||
Spherical = 1
|
||||
};
|
||||
|
||||
struct InvalidGridTypeError : public ghoul::RuntimeError {
|
||||
explicit InvalidGridTypeError(std::string gridType);
|
||||
std::string gridType;
|
||||
};
|
||||
|
||||
VolumeGridType parseGridType(const std::string& gridType);
|
||||
|
||||
} // namespace volume
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_VOLUME___VOLUMEGRIDTYPE_H__
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/volume/volumemodule.h>
|
||||
#include <modules/volume/rendering/renderabletimevaryingvolume.h>
|
||||
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
@@ -31,6 +32,14 @@
|
||||
|
||||
namespace openspace {
|
||||
|
||||
VolumeModule::VolumeModule() : OpenSpaceModule(Name) {}
|
||||
using namespace volume;
|
||||
|
||||
VolumeModule::VolumeModule() : OpenSpaceModule(Name) {}
|
||||
|
||||
void VolumeModule::internalInitialize() {
|
||||
auto fRenderable = FactoryManager::ref().factory<Renderable>();
|
||||
ghoul_assert(fRenderable, "No renderable factory existed");
|
||||
fRenderable->registerClass<RenderableTimeVaryingVolume>("RenderableTimeVaryingVolume");
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -33,6 +33,7 @@ class VolumeModule : public OpenSpaceModule {
|
||||
public:
|
||||
constexpr static const char* Name = "Volume";
|
||||
|
||||
void internalInitialize() override;
|
||||
VolumeModule();
|
||||
};
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#define __OPENSPACE_MODULE_VOLUME___VOLUMESAMPLER___H__
|
||||
|
||||
namespace openspace {
|
||||
namespace volume {
|
||||
|
||||
template <typename VolumeType>
|
||||
class VolumeSampler {
|
||||
@@ -40,6 +41,7 @@ private:
|
||||
const VolumeType* _volume;
|
||||
};
|
||||
|
||||
} // namespace volume
|
||||
} // namespace openspace
|
||||
|
||||
#include "volumesampler.inl"
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
****************************************************************************************/
|
||||
|
||||
namespace openspace {
|
||||
namespace volume {
|
||||
|
||||
template <typename VolumeType>
|
||||
VolumeSampler<VolumeType>::VolumeSampler(const VolumeType& volume, const glm::vec3& filterSize) {
|
||||
@@ -78,4 +79,5 @@ typename VolumeType::VoxelType VolumeSampler<VolumeType>::sample(const glm::vec3
|
||||
return value;
|
||||
}
|
||||
|
||||
} // namespace volume
|
||||
} // namespace openspace
|
||||
|
||||
@@ -24,8 +24,9 @@
|
||||
|
||||
#include "volumeutils.h"
|
||||
|
||||
namespace openspace::volumeutils {
|
||||
|
||||
namespace openspace {
|
||||
namespace volume {
|
||||
|
||||
size_t coordsToIndex(const glm::uvec3& coords, const glm::uvec3& dims) {
|
||||
size_t w = dims.x;
|
||||
size_t h = dims.y;
|
||||
@@ -48,5 +49,6 @@ glm::uvec3 indexToCoords(size_t index, const glm::uvec3& dims) {
|
||||
|
||||
return glm::uvec3(x, y, z);
|
||||
}
|
||||
|
||||
} // namespace openspace::volumeutils
|
||||
|
||||
} // namespace volume
|
||||
} // namespace openspace
|
||||
|
||||
@@ -27,11 +27,13 @@
|
||||
|
||||
#include <ghoul/glm.h>
|
||||
|
||||
namespace openspace::volumeutils {
|
||||
namespace openspace {
|
||||
namespace volume {
|
||||
|
||||
size_t coordsToIndex(const glm::uvec3& coords, const glm::uvec3& dimensions);
|
||||
glm::uvec3 indexToCoords(size_t index, const glm::uvec3& dimensions);
|
||||
|
||||
} // namespace openspace::volumeutils
|
||||
} // namespace volume
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_VOLUME___VOLUMEUTILS___H__
|
||||
|
||||
@@ -35,14 +35,13 @@ return {
|
||||
-- Scene = "${SCENE}/rosetta.scene",
|
||||
-- Scene = "${SCENE}/osirisrex.scene",
|
||||
|
||||
Task = "${TASKS}/default.task",
|
||||
TasksRoot = "${OPENSPACE_DATA}/tasks",
|
||||
|
||||
Paths = {
|
||||
SCRIPTS = "${BASE_PATH}/scripts",
|
||||
SHADERS = "${BASE_PATH}/shaders",
|
||||
OPENSPACE_DATA = "${BASE_PATH}/data",
|
||||
SCENE = "${OPENSPACE_DATA}/scene",
|
||||
TASKS = "${OPENSPACE_DATA}/tasks",
|
||||
SPICE = "${OPENSPACE_DATA}/spice",
|
||||
MODULES = "${BASE_PATH}/modules",
|
||||
TESTDIR = "${BASE_PATH}/tests",
|
||||
|
||||
@@ -159,6 +159,7 @@ set(OPENSPACE_SOURCE
|
||||
${OPENSPACE_BASE_DIR}/src/util/histogram.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/task.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/taskloader.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/threadpool.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/time.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/timeline.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/timemanager.cpp
|
||||
@@ -296,6 +297,10 @@ set(OPENSPACE_HEADER
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/blockplaneintersectiongeometry.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/boxgeometry.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/camera.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/concurrentjobmanager.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/concurrentjobmanager.inl
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/concurrentqueue.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/concurrentqueue.inl
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/factorymanager.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/factorymanager.inl
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/keys.h
|
||||
@@ -318,6 +323,7 @@ set(OPENSPACE_HEADER
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/timerange.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/updatestructures.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/transformationmanager.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/threadpool.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/histogram.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/gpudata.h
|
||||
)
|
||||
|
||||
@@ -59,7 +59,7 @@ const string ConfigurationManager::KeyKeyboardShortcuts = "KeyboardShortcuts";
|
||||
const string ConfigurationManager::KeyDocumentation = "Documentation";
|
||||
const string ConfigurationManager::KeyFactoryDocumentation = "FactoryDocumentation";
|
||||
const string ConfigurationManager::KeyConfigScene = "Scene";
|
||||
const string ConfigurationManager::KeyConfigTask = "Task";
|
||||
const string ConfigurationManager::KeyConfigTasksRoot = "TasksRoot";
|
||||
|
||||
const string ConfigurationManager::KeyLogging = "Logging";
|
||||
const string ConfigurationManager::PartLogDir = "LogDir";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*****************************************************************************************
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
@@ -53,7 +53,7 @@ documentation::Documentation ConfigurationManager::Documentation() {
|
||||
"the Scene documentation."
|
||||
},
|
||||
{
|
||||
ConfigurationManager::KeyConfigTask,
|
||||
ConfigurationManager::KeyConfigTasksRoot,
|
||||
new StringAnnotationVerifier(
|
||||
"A valid task file as described in the Task documentation"
|
||||
),
|
||||
|
||||
@@ -216,8 +216,8 @@ bool Renderable::isEnabled() const {
|
||||
}
|
||||
|
||||
void Renderable::onEnabledChange(std::function<void(bool)> callback) {
|
||||
_enabled.onChange([&] () {
|
||||
callback(isEnabled());
|
||||
_enabled.onChange([this, c{ std::move(callback) }]() {
|
||||
c(isEnabled());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -109,8 +109,7 @@ void TransferFunction::setTextureFromTxt() {
|
||||
in.open(_filepath.c_str());
|
||||
|
||||
if (!in.is_open()) {
|
||||
LERROR("Could not open file " << _filepath);
|
||||
return;
|
||||
throw ghoul::FileNotFoundError(_filepath);
|
||||
}
|
||||
|
||||
int width = 512;
|
||||
|
||||
@@ -46,7 +46,7 @@ std::vector<std::unique_ptr<Task>> TaskLoader::tasksFromDictionary(const ghoul::
|
||||
std::string taskName;
|
||||
ghoul::Dictionary subTask;
|
||||
if (tasksDictionary.getValue(key, taskName)) {
|
||||
std::string path = "${TASKS}/" + taskName + ".task";
|
||||
std::string path = taskName + ".task";
|
||||
std::vector<std::unique_ptr<Task>> subTasks = tasksFromFile(path);
|
||||
std::move(subTasks.begin(), subTasks.end(), std::back_inserter(tasks));
|
||||
} else if (tasksDictionary.getValue(key, subTask)) {
|
||||
@@ -75,10 +75,10 @@ std::vector<std::unique_ptr<Task>> TaskLoader::tasksFromFile(const std::string&
|
||||
ghoul::lua::loadDictionaryFromFile(
|
||||
absTasksFile,
|
||||
tasksDictionary
|
||||
);
|
||||
} catch (...) {
|
||||
);
|
||||
} catch (const ghoul::RuntimeError& e) {
|
||||
LERROR("Could not load tasks file '" << absTasksFile << "'. " <<
|
||||
"Lua parse error");
|
||||
"Lua error: " << e.message << ": " << e.component);
|
||||
return std::vector<std::unique_ptr<Task>>();
|
||||
}
|
||||
return tasksFromDictionary(tasksDictionary);
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/globebrowsing/other/threadpool.h>
|
||||
#include <openspace/util/threadpool.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
namespace openspace {
|
||||
|
||||
Worker::Worker(ThreadPool& pool) : pool(pool) {}
|
||||
|
||||
@@ -103,4 +103,4 @@ void ThreadPool::clearTasks() {
|
||||
} // release lock
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
} // namespace openspace
|
||||
@@ -34,7 +34,10 @@ using datamessagestructures::TimeKeyframe;
|
||||
void TimeManager::preSynchronization(double dt) {
|
||||
// double now = OsEng.runTime();
|
||||
removeKeyframesBefore(_latestConsumedTimestamp);
|
||||
if (_timeline.nKeyframes() == 0) {
|
||||
if (_shouldSetTime) {
|
||||
time().setTime(_timeNextFrame.j2000Seconds());
|
||||
_shouldSetTime = false;
|
||||
} else if (_timeline.nKeyframes() == 0) {
|
||||
time().advanceTime(dt);
|
||||
} else {
|
||||
consumeKeyframes(dt);
|
||||
@@ -141,6 +144,11 @@ void TimeManager::clearKeyframes() {
|
||||
_timeline.clearKeyframes();
|
||||
}
|
||||
|
||||
void TimeManager::setTimeNextFrame(Time t) {
|
||||
_shouldSetTime = true;
|
||||
_timeNextFrame = t;
|
||||
}
|
||||
|
||||
size_t TimeManager::nKeyframes() const {
|
||||
return _timeline.nKeyframes();
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ function (handle_applications)
|
||||
|
||||
get_application_attribute_default(${app_dir} is_default_application)
|
||||
if (${is_default_application})
|
||||
set(OPENSPACE_APPLICATION_${upper_app} ON CACHE BOOL "Build ${app} application" FORCE)
|
||||
option(OPENSPACE_APPLICATION_${upper_app} "Build ${app} application" ${is_default_application})
|
||||
endif ()
|
||||
|
||||
if (OPENSPACE_APPLICATION_${upper_app})
|
||||
|
||||
@@ -139,7 +139,7 @@ function (set_openspace_compile_settings project)
|
||||
"-Wredundant-move"
|
||||
"-Wreorder"
|
||||
"-Wsemicolon-before-method-body"
|
||||
"-Wshadow-field"
|
||||
# "-Wshadow-field"
|
||||
"-Wshadow-field-in-constructor"
|
||||
# "-Wshadow-all" Add this again once the Properties don't throw warnings --abock
|
||||
"-Wshift-sign-overflow"
|
||||
|
||||
@@ -81,6 +81,10 @@
|
||||
//#include <test_iswamanager.inl>
|
||||
#endif
|
||||
|
||||
#ifdef OPENSPACE_MODULE_VOLUME_ENABLED
|
||||
#include <test_rawvolumeio.inl>
|
||||
#endif
|
||||
|
||||
#include <test_scriptscheduler.inl>
|
||||
|
||||
#include <test_documentation.inl>
|
||||
|
||||
@@ -22,7 +22,11 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/globebrowsing/other/concurrentjobmanager.h>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <openspace/util/concurrentjobmanager.h>
|
||||
|
||||
#include <ghoul/misc/threadpool.h>
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
@@ -31,7 +35,7 @@
|
||||
|
||||
class ConcurrentJobManagerTest : public testing::Test {};
|
||||
|
||||
struct TestJob : public openspace::globebrowsing::Job<int> {
|
||||
struct TestJob : public openspace::Job<int> {
|
||||
TestJob(int jobExecutingTime)
|
||||
: _jobExecutingTime(jobExecutingTime)
|
||||
{}
|
||||
@@ -56,8 +60,8 @@ private:
|
||||
|
||||
|
||||
TEST_F(ConcurrentJobManagerTest, Basic) {
|
||||
using namespace openspace::globebrowsing;
|
||||
|
||||
using namespace openspace;
|
||||
|
||||
ConcurrentJobManager<int> jobManager(ThreadPool(1));
|
||||
|
||||
auto testJob1 = std::shared_ptr<TestJob>(new TestJob(20));
|
||||
@@ -97,7 +101,7 @@ struct VerboseProduct {
|
||||
};
|
||||
|
||||
|
||||
struct VerboseJob : public openspace::globebrowsing::Job<VerboseProduct>{
|
||||
struct VerboseJob : public openspace::Job<VerboseProduct>{
|
||||
VerboseJob(int jobExecutingTime)
|
||||
: _jobExecutingTime(jobExecutingTime) {
|
||||
std::cout << "VerboseTestJob constructor" << std::endl;
|
||||
@@ -124,7 +128,7 @@ struct VerboseJob : public openspace::globebrowsing::Job<VerboseProduct>{
|
||||
};
|
||||
|
||||
TEST_F(ConcurrentJobManagerTest, JobCreation) {
|
||||
using namespace openspace::globebrowsing;
|
||||
using namespace openspace;
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
|
||||
|
||||
@@ -22,7 +22,9 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/globebrowsing/other/concurrentqueue.h>
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <openspace/util/concurrentqueue.h>
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
@@ -31,7 +33,7 @@
|
||||
class ConcurrentQueueTest : public testing::Test {};
|
||||
|
||||
TEST_F(ConcurrentQueueTest, Basic) {
|
||||
using namespace openspace::globebrowsing;
|
||||
using namespace openspace;
|
||||
|
||||
ConcurrentQueue<int> q1;
|
||||
q1.push(4);
|
||||
|
||||
93
tests/test_rawvolumeio.inl
Normal file
93
tests/test_rawvolumeio.inl
Normal file
@@ -0,0 +1,93 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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 "gtest/gtest.h"
|
||||
|
||||
#include <openspace/util/timeline.h>
|
||||
#include <openspace/util/time.h>
|
||||
|
||||
#include <modules/volume/rawvolume.h>
|
||||
#include <modules/volume/rawvolumereader.h>
|
||||
#include <modules/volume/rawvolumewriter.h>
|
||||
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/glm.h>
|
||||
|
||||
using namespace openspace;
|
||||
|
||||
class RawVolumeIoTest : public testing::Test {};
|
||||
|
||||
TEST_F(RawVolumeIoTest, TinyInputOutput) {
|
||||
using namespace volume;
|
||||
|
||||
glm::uvec3 dims{ 1, 1, 1 };
|
||||
float value = 0.5;
|
||||
|
||||
RawVolume<float> vol(dims);
|
||||
|
||||
vol.set({ 0, 0, 0 }, value);
|
||||
ASSERT_EQ(vol.get({ 0, 0, 0 }), value);
|
||||
|
||||
std::string volumePath = absPath("${TESTDIR}/tinyvolume.rawvolume");
|
||||
|
||||
// Write the 1x1x1 volume to disk
|
||||
RawVolumeWriter<float> writer(volumePath);
|
||||
writer.write(vol);
|
||||
|
||||
// Read the 1x1x1 volume and make sure the value is the same.
|
||||
RawVolumeReader<float> reader(volumePath, dims);
|
||||
std::unique_ptr<RawVolume<float>> storedVolume = reader.read();
|
||||
ASSERT_EQ(storedVolume->get({ 0, 0, 0 }), value);
|
||||
}
|
||||
|
||||
TEST_F(RawVolumeIoTest, BasicInputOutput) {
|
||||
using namespace volume;
|
||||
|
||||
glm::uvec3 dims{ 2, 4, 8 };
|
||||
auto value = [dims](glm::uvec3 v) {
|
||||
return v.z * 8 * 4 + v.y * 4 + v.x;
|
||||
};
|
||||
|
||||
RawVolume<float> vol(dims);
|
||||
vol.forEachVoxel([&vol, &value](glm::uvec3 x, float v) {
|
||||
vol.set(x, value(x));
|
||||
});
|
||||
|
||||
vol.forEachVoxel([&value](glm::uvec3 x, float v) {
|
||||
ASSERT_EQ(v, value(x));
|
||||
});
|
||||
|
||||
std::string volumePath = absPath("${TESTDIR}/basicvolume.rawvolume");
|
||||
|
||||
// Write the 2x4x8 volume to disk
|
||||
RawVolumeWriter<float> writer(volumePath);
|
||||
writer.write(vol);
|
||||
|
||||
// Read the 2x4x8 volume and make sure the value is the same.
|
||||
RawVolumeReader<float> reader(volumePath, dims);
|
||||
std::unique_ptr<RawVolume<float>> storedVolume = reader.read();
|
||||
vol.forEachVoxel([&value](glm::uvec3 x, float v) {
|
||||
ASSERT_EQ(v, value(x));
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user