Commit 666fb04d authored by schultezub's avatar schultezub
Browse files

Implemented image representation conversion GL -> Local


git-svn-id: https://camplinux.in.tum.de/svn/campvis/trunk@461 bb408c1c-ae56-11e1-83d9-df6b3e0c105e
parent 207a1354
......@@ -284,6 +284,6 @@ namespace campvis {
tgtAssert(_treeModel != 0, "Failed creating TreeViewWidget model.");
setModel(_treeModel);
}
}
}
\ No newline at end of file
......@@ -37,6 +37,7 @@
#include "core/datastructures/imagedata.h"
#include "core/datastructures/imagerepresentationdisk.h"
#include "core/datastructures/imagerepresentationlocal.h"
#include "core/datastructures/imagerepresentationrendertarget.h"
#ifdef CAMPVIS_HAS_MODULE_ITK
#include "modules/itk/core/genericimagerepresentationitk.h"
#endif
......@@ -238,5 +239,12 @@ namespace campvis {
return _texture->getSizeOnGPU();
}
const WeaklyTypedPointer ImageRepresentationGL::getWeaklyTypedPointer() const {
if (_texture->getPixelData() == 0) {
_texture->downloadTexture();
}
return WeaklyTypedPointer(WeaklyTypedPointer::baseType(_texture->getDataType()), _texture->getNumChannels(), _texture->getPixelData());
}
}
\ No newline at end of file
......@@ -134,6 +134,15 @@ namespace campvis {
const tgt::Texture* getTexture() const;
/**
* Returns a WeaklyTypedPointer to the data of this representation.
* You do \b not own the pointer - do \b not modify its content!
* \note Make sure to call this method from a valid OpenGL context.
* \return A WeaklyTypedPointer to the data of this representation. Neither you own nor you may modify its data!
*/
const WeaklyTypedPointer getWeaklyTypedPointer() const;
protected:
/**
* Creates a new ImageRepresentationGL representation from a tgt::Texture.
......
......@@ -29,10 +29,14 @@
#include "imagerepresentationlocal.h"
#include "tgt/qt/qtcontextmanager.h"
#include "tbb/tbb.h"
#include "tbb/spin_mutex.h"
#include "core/datastructures/imagerepresentationdisk.h"
#include "core/datastructures/imagerepresentationgl.h"
#include "core/datastructures/genericimagerepresentationlocal.h"
#include "core/tools/opengljobprocessor.h"
#include "core/tools/job.h"
#ifdef CAMPVIS_HAS_MODULE_ITK
#include "modules/itk/core/genericimagerepresentationitk.h"
......@@ -118,7 +122,24 @@ namespace campvis {
// test source image type via dynamic cast
if (const ImageRepresentationDisk* tester = dynamic_cast<const ImageRepresentationDisk*>(source)) {
return convertToGenericLocal(tester);
return convertToGenericLocal(tester, tester->getImageData());
}
else if (const ImageRepresentationGL* tester = dynamic_cast<const ImageRepresentationGL*>(source)) {
tgt::GLCanvas* context = GLJobProc.iKnowWhatImDoingGetArbitraryContext();
ImageRepresentationLocal* toReturn = 0;
GLJobProc.pause();
try {
tbb::mutex::scoped_lock lock(CtxtMgr.getGlMutex());
context->getContext()->acquire();
WeaklyTypedPointer wtp = tester->getWeaklyTypedPointer();
toReturn = convertToGenericLocal(source, wtp);
CtxtMgr.releaseCurrentContext();
}
catch (...) {
LERROR("An unknown error occured during conversion...");
}
GLJobProc.resume();
return toReturn;
}
#ifdef CAMPVIS_HAS_MODULE_ITK
......@@ -197,9 +218,7 @@ namespace campvis {
tbb::parallel_for(tbb::blocked_range<size_t>(0, getNumElements()), IntensityHistogramGenerator(this, _intensityHistogram));
}
ImageRepresentationLocal* ImageRepresentationLocal::convertToGenericLocal(const ImageRepresentationDisk* source) {
WeaklyTypedPointer wtp = source->getImageData();
ImageRepresentationLocal* ImageRepresentationLocal::convertToGenericLocal(const AbstractImageRepresentation* source, const WeaklyTypedPointer& wtp) {
#define CONVERT_DISK_TO_GENERIC_LOCAL(baseType,numChannels) \
return GenericImageRepresentationLocal<baseType, numChannels>::create( \
const_cast<ImageData*>(source->getParent()), \
......@@ -207,7 +226,7 @@ namespace campvis {
#define DISPATCH_DISK_TO_GENERIC_LOCAL_CONVERSION(numChannels) \
if (source->getParent()->getNumChannels() == (numChannels)) { \
switch (source->getBaseType()) { \
switch (wtp._baseType) { \
case WeaklyTypedPointer::UINT8: \
CONVERT_DISK_TO_GENERIC_LOCAL(uint8_t, (numChannels)) \
case WeaklyTypedPointer::INT8: \
......@@ -238,6 +257,5 @@ namespace campvis {
}
}
}
\ No newline at end of file
......@@ -210,7 +210,8 @@ namespace campvis {
private:
static ImageRepresentationLocal* convertToGenericLocal(const ImageRepresentationDisk* source);
static ImageRepresentationLocal* convertToGenericLocal(const AbstractImageRepresentation* source, const WeaklyTypedPointer& wtp);
// We don't want this data to be copied - clone() must be enough
// (read: We are too lazy to implement a correct copy constructor / assignment-operator)
......
......@@ -38,6 +38,7 @@ namespace campvis {
OpenGLJobProcessor::OpenGLJobProcessor()
: _currentContext(0)
{
_pause = 0;
}
OpenGLJobProcessor::~OpenGLJobProcessor() {
......@@ -123,6 +124,13 @@ namespace campvis {
delete jobToDo;
}
}
while (_pause > 0) {
CtxtMgr.releaseCurrentContext();
_evaluationCondition.wait(lock);
_currentContext->getContext()->acquire();
hadWork = true;
}
if (! hadWork) {
CtxtMgr.releaseCurrentContext();
......@@ -135,6 +143,21 @@ namespace campvis {
CtxtMgr.releaseCurrentContext();
}
void OpenGLJobProcessor::pause() {
++_pause;
}
void OpenGLJobProcessor::resume() {
if (_pause == 0) {
tgtAssert(false, "Called resume on non-paused job processor!");
return;
}
--_pause;
if (_pause == 0)
_evaluationCondition.notify_all();
}
void OpenGLJobProcessor::enqueueJob(tgt::GLCanvas* canvas, AbstractJob* job, JobType priority) {
tbb::concurrent_hash_map<tgt::GLCanvas*, PerContextJobQueue*>::const_accessor a;
if (_contextQueueMap.find(a, canvas)) {
......@@ -184,5 +207,16 @@ namespace campvis {
}
}
tgt::GLCanvas* OpenGLJobProcessor::iKnowWhatImDoingGetArbitraryContext() {
if (_currentContext != 0)
return _currentContext;
else if (!_contexts.empty())
return _contexts.front();
else {
tgtAssert(false, "No Contexts registered!");
return 0;
}
}
}
......@@ -107,6 +107,16 @@ namespace campvis {
*/
void run();
/**
* Pauses the job processor as at the next possible moment.
*/
void pause();
/**
* Resume the execution of the job processor.
*/
void resume();
/**
* Enqueues the given Job with the given priority.
*
......@@ -118,6 +128,14 @@ namespace campvis {
void enqueueJob(tgt::GLCanvas* canvas, AbstractJob* job, JobType priority);
/**
* Returns an arbitrary registered OpenGL context.
* \note You can do really messy things with this. Do not use this method unless
* you know what you're doing and know that there is no other way...
*/
tgt::GLCanvas* iKnowWhatImDoingGetArbitraryContext();
protected:
/**
* Struct encapsulating the job queue for a single OpenGL context.
......@@ -162,6 +180,7 @@ namespace campvis {
tbb::concurrent_hash_map<tgt::GLCanvas*, PerContextJobQueue*> _contextQueueMap;
tbb::concurrent_vector<tgt::GLCanvas*> _contexts;
tbb::atomic<int> _pause;
std::condition_variable _evaluationCondition; ///< conditional wait to be used when there are currently no jobs to process
tgt::GLCanvas* _currentContext; ///< current active OpenGL context
......
......@@ -41,8 +41,8 @@ namespace campvis {
AdvancedUsVis::AdvancedUsVis()
: DigraphVisualizationPipeline()
, _camera("camera", "Camera")
, _usReader()
, _confidenceReader()
, _usReader(_effectiveRenderTargetSize)
, _confidenceReader(_effectiveRenderTargetSize)
, _confidenceGenerator()
, _gvg()
, _lhh()
......@@ -96,7 +96,8 @@ namespace campvis {
_camera.addSharedProperty(&_usDVR.p_camera);
//_usReader.p_url.setValue("D:\\Medical Data\\US Confidence Vis\\01\\BMode_01.mhd");
_usReader.p_url.setValue("D:\\Medical Data\\US Confidence Vis\\UltrasoundBoneData\\SynthesEvaluationUnterschenkel\\Athanasios\\US.csvd");
//_usReader.p_url.setValue("D:\\Medical Data\\US Confidence Vis\\UltrasoundBoneData\\SynthesEvaluationUnterschenkel\\Athanasios\\US.csvd");
_usReader.p_url.setValue("D:\\Medical Data\\US Confidence Vis\\transcranial\\us.png");
_usReader.p_targetImageID.setValue("us.image");
_usReader.p_targetImageID.connect(&_confidenceGenerator.p_sourceImageID);
_usReader.p_targetImageID.connect(&_usFusion1.p_usImageId);
......@@ -109,14 +110,19 @@ namespace campvis {
_usReader.p_targetImageID.connect(&_usDenoiseilter.p_sourceImageID);
//_confidenceReader.p_url.setValue("D:\\Medical Data\\US Confidence Vis\\01\\Confidence_01.mhd");
_confidenceReader.p_url.setValue("D:\\Medical Data\\US Confidence Vis\\UltrasoundBoneData\\SynthesEvaluationUnterschenkel\\Athanasios\\Map.csvd");
//_confidenceReader.p_url.setValue("D:\\Medical Data\\US Confidence Vis\\UltrasoundBoneData\\SynthesEvaluationUnterschenkel\\Athanasios\\Map.csvd");
_confidenceReader.p_url.setValue("D:\\Medical Data\\US Confidence Vis\\transcranial\\cm.png");
_confidenceReader.p_targetImageID.setValue("confidence.image.read");
_confidenceReader.p_targetImageID.connect(&_usFusion1.p_confidenceImageID);
_confidenceReader.p_targetImageID.connect(&_usFusion2.p_confidenceImageID);
_confidenceReader.p_targetImageID.connect(&_usFusion3.p_confidenceImageID);
_confidenceReader.p_targetImageID.connect(&_usFusion4.p_confidenceImageID);
_confidenceGenerator.p_targetImageID.setValue("confidence.image.generated");
_confidenceGenerator.p_targetImageID.connect(&_usFusion1.p_confidenceImageID);
_confidenceGenerator.p_targetImageID.connect(&_usFusion2.p_confidenceImageID);
_confidenceGenerator.p_targetImageID.connect(&_usFusion3.p_confidenceImageID);
_confidenceGenerator.p_targetImageID.connect(&_usFusion4.p_confidenceImageID);
//_confidenceGenerator.p_targetImageID.connect(&_usFusion1.p_confidenceImageID);
//_confidenceGenerator.p_targetImageID.connect(&_usFusion2.p_confidenceImageID);
//_confidenceGenerator.p_targetImageID.connect(&_usFusion3.p_confidenceImageID);
//_confidenceGenerator.p_targetImageID.connect(&_usFusion4.p_confidenceImageID);
_gvg.p_targetImageID.connect(&_lhh.p_gradientsId);
_gvg.p_targetImageID.connect(&_usFusion1.p_gradientImageID);
......
......@@ -35,6 +35,7 @@
#include "core/eventhandlers/transfuncwindowingeventhandler.h"
#include "core/eventhandlers/trackballnavigationeventhandler.h"
#include "core/pipeline/digraphvisualizationpipeline.h"
#include "modules/devil/processors/devilimagereader.h"
#include "modules/io/processors/mhdimagereader.h"
#include "modules/io/processors/csvdimagereader.h"
#include "modules/advancedusvis/processors/advancedusfusion.h"
......@@ -88,8 +89,8 @@ namespace campvis {
CameraProperty _camera;
CsvdImageReader _usReader;
CsvdImageReader _confidenceReader;
DevilImageReader _usReader;
DevilImageReader _confidenceReader;
ConfidenceMapGenerator _confidenceGenerator;
GradientVolumeGenerator _gvg;
......
......@@ -103,7 +103,7 @@ namespace campvis {
ImageRepresentationGL::ScopedRepresentation gradients(data, p_gradientImageID.getValue());
if (img != 0 && blurred != 0 && gradients != 0 && confidence != 0) {
if (img->getDimensionality() == 3) {
if (img->getDimensionality() >= 2) {
if (img.getDataHandle().getTimestamp() != _sourceImageTimestamp) {
// source DataHandle has changed
updateProperties(img.getDataHandle());
......
......@@ -52,10 +52,12 @@ namespace campvis {
: VisualizationProcessor(canvasSize)
, p_url("url", "Image URL", "")
, p_targetImageID("targetImageName", "Target Image ID", "DevilImageReader.output", DataNameProperty::WRITE)
, p_useRenderTarget("UseRenderTarget", "Read Into RenderTarget", false)
, _devilTextureReader(0)
{
addProperty(&p_url);
addProperty(&p_targetImageID);
addProperty(&p_useRenderTarget);
_devilTextureReader = new tgt::TextureReaderDevil();
}
......@@ -79,36 +81,44 @@ namespace campvis {
void DevilImageReader::process(DataContainer& data) {
tgt::Texture* tex = _devilTextureReader->loadTexture(p_url.getValue(), tgt::Texture::LINEAR, false, true, true, false);
if (tex != 0) {
ImageData id (2, tex->getDimensions(), tex->getNumChannels());
ImageRepresentationGL* image = ImageRepresentationGL::create(&id, tex);
std::pair<ImageData*, ImageRepresentationRenderTarget*> rt = ImageRepresentationRenderTarget::createWithImageData(_renderTargetSize.getValue());
glPushAttrib(GL_ALL_ATTRIB_BITS);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_ALWAYS);
_shader->activate();
_shader->setIgnoreUniformLocationError(true);
_shader->setUniform("_viewportSize", _renderTargetSize.getValue());
_shader->setUniform("_viewportSizeRCP", 1.f / tgt::vec2(_renderTargetSize.getValue()));
_shader->setIgnoreUniformLocationError(false);
tgt::TextureUnit texUnit;
image->bind(_shader, texUnit, "_colorTexture");
rt.second->activate();
LGL_ERROR;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
QuadRdr.renderQuad();
rt.second->deactivate();
_shader->deactivate();
tgt::TextureUnit::setZeroUnit();
glPopAttrib();
LGL_ERROR;
data.addData(p_targetImageID.getValue(), rt.first);
p_targetImageID.issueWrite();
if (p_useRenderTarget.getValue()) {
ImageData id (2, tex->getDimensions(), tex->getNumChannels());
ImageRepresentationGL* image = ImageRepresentationGL::create(&id, tex);
std::pair<ImageData*, ImageRepresentationRenderTarget*> rt = ImageRepresentationRenderTarget::createWithImageData(_renderTargetSize.getValue());
glPushAttrib(GL_ALL_ATTRIB_BITS);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_ALWAYS);
_shader->activate();
_shader->setIgnoreUniformLocationError(true);
_shader->setUniform("_viewportSize", _renderTargetSize.getValue());
_shader->setUniform("_viewportSizeRCP", 1.f / tgt::vec2(_renderTargetSize.getValue()));
_shader->setIgnoreUniformLocationError(false);
tgt::TextureUnit texUnit;
image->bind(_shader, texUnit, "_colorTexture");
rt.second->activate();
LGL_ERROR;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
QuadRdr.renderQuad();
rt.second->deactivate();
_shader->deactivate();
tgt::TextureUnit::setZeroUnit();
glPopAttrib();
LGL_ERROR;
data.addData(p_targetImageID.getValue(), rt.first);
p_targetImageID.issueWrite();
}
else {
ImageData* id = new ImageData(2, tex->getDimensions(), tex->getNumChannels());
ImageRepresentationGL::create(id, tex);
data.addData(p_targetImageID.getValue(), id);
p_targetImageID.issueWrite();
}
}
else {
LERROR("Could not load image.");
......
......@@ -80,6 +80,7 @@ namespace campvis {
StringProperty p_url; ///< URL for file to read
DataNameProperty p_targetImageID; ///< image ID for read image
BoolProperty p_useRenderTarget; ///< Flag whether to read into a render target
protected:
tgt::Shader* _shader;
......
......@@ -140,7 +140,7 @@ namespace campvis {
void ConfidenceMapGenerator::process(DataContainer& data) {
ImageRepresentationLocal::ScopedRepresentation input(data, p_sourceImageID.getValue());
if (input != 0 && input->getDimensionality() >= 2 && input->getParent()->getNumChannels() == 1) {
if (input != 0 && input->getDimensionality() >= 2 && input->getParent()->getNumChannels() >= 1) {
const tgt::svec3& imageSize = input->getSize();
size_t numElements = input->getNumElements();
float* outputValues = new float[numElements];
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment