Commit be17daa3 authored by Christian Schulte zu Berge's avatar Christian Schulte zu Berge
Browse files

Further work on neuro project, making use of ViewportSplitter, fixing...

Further work on neuro project, making use of ViewportSplitter, fixing MultiVolumeMprRenderer shader.
parent 21e4db6d
......@@ -26,6 +26,7 @@ in vec3 geom_TexCoord;
noperspective in vec3 geom_EdgeDistance;
out vec4 out_Color;
out vec4 out_Picking;
#include "tools/texture3d.frag"
#include "tools/transferfunction.frag"
......@@ -65,11 +66,15 @@ void main() {
vec4 color3 = lookupTexture(geom_TexCoord, _volume3, _volumeParams3, _transferFunction3, _transferFunctionParams3);
out_Color = color1 + color2 + color3;
if (out_Color.w > 1.0)
out_Color /= out_Color.w;
if (out_Color.a > 1.0)
out_Color /= out_Color.a;
//out_Color = vec4(mix(out_Color.rgb, vec3(0.0, 0.0, 0.0), out_Color.a), 1.0);
out_Color = vec4(mix(out_Color.rgb, vec3(0.0, 0.0, 0.0), out_Color.a), max(out_Color.a, 1.0 - _transparency));
float maxElem = max(out_Color.x, max(out_Color.y, out_Color.z));
if (maxElem > 1.0)
out_Color.xyz /= maxElem;
float alpha = max(out_Color.a, 1.0 - _transparency);
out_Color = vec4(mix(vec3(0.0, 0.0, 0.0), out_Color.rgb, alpha), alpha);
#ifdef WIREFRAME_RENDERING
// Find the smallest distance to the edges
......@@ -81,4 +86,7 @@ void main() {
// Mix the surface color with the line color
out_Color = mix(vec4(1.0), out_Color, mixVal);
#endif
// write world position to picking target
out_Picking = vec4(geom_TexCoord, 1.0);
}
......@@ -44,21 +44,35 @@ namespace campvis {
, _ctReader()
, _t1Reader()
, _petReader()
, _mvmpr(&_canvasSize)
, _mvmpr2D(&_canvasSize)
, _mvmpr3D(&_canvasSize)
, _mvr(&_canvasSize)
, _rtc(&_canvasSize)
, _horizontalSplitter(2, ViewportSplitter::HORIZONTAL, &_canvasSize)
, _slicePositionEventHandler(&_mvmpr2D.p_planeDistance)
{
_tcp.addLqModeProcessor(&_mvr);
addEventListenerToBack(&_tcp);
addEventListenerToBack(&_horizontalSplitter);
addProcessor(&_lsp);
addProcessor(&_tcp);
addProcessor(&_ctReader);
addProcessor(&_t1Reader);
addProcessor(&_petReader);
addProcessor(&_mvmpr);
addProcessor(&_mvmpr2D);
addProcessor(&_mvmpr3D);
addProcessor(&_mvr);
addProcessor(&_rtc);
_horizontalSplitter.p_outputImageId.setValue("NeuroDemo");
_horizontalSplitter.setInputImageIdProperty(0, &_mvmpr2D.p_outputImageId);
_horizontalSplitter.setInputImageIdProperty(1, &_rtc.p_targetImageId);
_tcp.setViewportSizeProperty(&_horizontalSplitter.p_subViewViewportSize);
_mvmpr2D.setViewportSizeProperty(&_horizontalSplitter.p_subViewViewportSize);
_mvmpr3D.setViewportSizeProperty(&_horizontalSplitter.p_subViewViewportSize);
_mvr.setViewportSizeProperty(&_horizontalSplitter.p_subViewViewportSize);
_rtc.setViewportSizeProperty(&_horizontalSplitter.p_subViewViewportSize);
}
NeuroDemo::~NeuroDemo() {
......@@ -66,51 +80,71 @@ namespace campvis {
void NeuroDemo::init() {
AutoEvaluationPipeline::init();
_horizontalSplitter.init();
_horizontalSplitter.s_onEvent.connect(this, &NeuroDemo::onSplitterEvent);
_tcp.p_image.setValue("ct.image");
_renderTargetID.setValue("composed");
_renderTargetID.setValue("NeuroDemo");
_t1Reader.p_url.setValue(ShdrMgr.completePath("D:/Medical Data/K_Data/K_T1_bet04.GB306.am"));
_t1Reader.p_targetImageID.setValue("t1_tf.image");
_t1Reader.p_targetImageID.addSharedProperty(&_mvmpr.p_sourceImage1);
_t1Reader.p_targetImageID.addSharedProperty(&_mvmpr2D.p_sourceImage1);
_t1Reader.p_targetImageID.addSharedProperty(&_mvmpr3D.p_sourceImage1);
_t1Reader.p_targetImageID.addSharedProperty(&_mvr.p_sourceImage1);
_t1Reader.s_validated.connect(this, &NeuroDemo::onReaderValidated);
_ctReader.p_url.setValue(ShdrMgr.completePath("D:/Medical Data/K_Data/K_CT_CoregT1.am"));
_ctReader.p_targetImageID.setValue("ct.image");
_ctReader.p_targetImageID.addSharedProperty(&_mvmpr.p_sourceImage2);
_ctReader.p_targetImageID.addSharedProperty(&_mvmpr2D.p_sourceImage2);
_ctReader.p_targetImageID.addSharedProperty(&_mvmpr3D.p_sourceImage2);
_ctReader.p_targetImageID.addSharedProperty(&_mvr.p_sourceImage2);
_ctReader.s_validated.connect(this, &NeuroDemo::onReaderValidated);
_petReader.p_url.setValue(ShdrMgr.completePath("D:/Medical Data/K_Data/K_PET-CoregNMI_fl.am"));
_petReader.p_targetImageID.setValue("pet.image");
_petReader.p_targetImageID.addSharedProperty(&_mvmpr.p_sourceImage3);
_petReader.p_targetImageID.addSharedProperty(&_mvmpr2D.p_sourceImage3);
_petReader.p_targetImageID.addSharedProperty(&_mvmpr3D.p_sourceImage3);
_petReader.p_targetImageID.addSharedProperty(&_mvr.p_sourceImage3);
_petReader.s_validated.connect(this, &NeuroDemo::onReaderValidated);
Geometry1DTransferFunction* t1_tf = new Geometry1DTransferFunction(128, cgt::vec2(0.f, .05f));
t1_tf->addGeometry(TFGeometry1D::createQuad(cgt::vec2(.25f, .65f), cgt::col4(170, 170, 128, 64), cgt::col4(192, 192, 128, 64)));
_mvmpr.p_transferFunction1.replaceTF(t1_tf);
_mvmpr2D.p_transferFunction1.replaceTF(t1_tf);
_mvmpr3D.p_transferFunction1.replaceTF(t1_tf->clone());
_mvr.p_transferFunction1.replaceTF(t1_tf->clone());
Geometry1DTransferFunction* ct_tf = new Geometry1DTransferFunction(128, cgt::vec2(0.f, .05f));
ct_tf->addGeometry(TFGeometry1D::createQuad(cgt::vec2(.8f, 1.f), cgt::col4(0, 150, 225, 192), cgt::col4(0, 192, 255, 255)));
_mvmpr.p_transferFunction2.replaceTF(ct_tf);
_mvmpr2D.p_transferFunction2.replaceTF(ct_tf);
_mvmpr3D.p_transferFunction2.replaceTF(ct_tf->clone());
_mvr.p_transferFunction2.replaceTF(ct_tf->clone());
Geometry1DTransferFunction* pet_tf = new Geometry1DTransferFunction(128, cgt::vec2(0.f, .05f));
auto g = TFGeometry1D::createQuad(cgt::vec2(.8f, 1.0f), cgt::col4(255, 255, 0, 48), cgt::col4(255, 32, 192, 72));
g->addKeyPoint(.9f, cgt::col4(255, 32, 0, 72));
pet_tf->addGeometry(g);
_mvmpr.p_transferFunction3.replaceTF(pet_tf);
_mvmpr2D.p_transferFunction3.replaceTF(pet_tf);
_mvmpr3D.p_transferFunction3.replaceTF(pet_tf->clone());
_mvr.p_transferFunction3.replaceTF(pet_tf->clone());
_mvmpr.p_relativeToImageCenter.setValue(false);
_mvmpr.p_use2DProjection.setValue(false);
_mvmpr.p_planeSize.setValue(200.f);
_mvmpr.p_outputImageId.setValue("result.mpr");
_mvmpr.p_outputImageId.addSharedProperty(&_rtc.p_firstImageId);
_mvmpr.p_outputImageId.addSharedProperty(&_mvr.p_geometryImageId);
_mvmpr2D.p_relativeToImageCenter.setValue(false);
_mvmpr2D.p_use2DProjection.setValue(true);
_mvmpr2D.p_planeSize.setValue(200.f);
_mvmpr2D.p_showWireframe.setValue(false);
_mvmpr2D.p_transparency.setValue(0.f);
_mvmpr2D.p_outputImageId.setValue("result.mpr.2d");
_mvmpr2D.p_planeSize.addSharedProperty(&_mvmpr3D.p_planeSize);
_mvmpr2D.p_planeDistance.addSharedProperty(&_mvmpr3D.p_planeDistance);
_mvmpr2D.p_planeNormal.addSharedProperty(&_mvmpr3D.p_planeNormal);
_mvmpr3D.p_relativeToImageCenter.setValue(false);
_mvmpr3D.p_use2DProjection.setValue(false);
_mvmpr3D.p_outputImageId.setValue("result.mpr.3d");
_mvmpr3D.p_showWireframe.setValue(true);
_mvmpr3D.p_transparency.setValue(0.5f);
_mvmpr3D.p_outputImageId.addSharedProperty(&_rtc.p_firstImageId);
//_mvmpr3D.p_outputImageId.addSharedProperty(&_mvr.p_geometryImageId);
_mvr.p_outputImageId.setValue("result.rc");
_mvr.p_outputImageId.addSharedProperty(&_rtc.p_secondImageId);
......@@ -120,54 +154,93 @@ namespace campvis {
_rtc.p_targetImageId.setValue("composed");
}
void NeuroDemo::onReaderValidated(AbstractProcessor* p) {
void NeuroDemo::deinit() {
_horizontalSplitter.s_onEvent.disconnect(this);
_horizontalSplitter.deinit();
AutoEvaluationPipeline::deinit();
}
void NeuroDemo::onEvent(cgt::Event* e) {
if (typeid(*e) == typeid(cgt::MouseEvent)) {
cgt::MouseEvent* me = static_cast<cgt::MouseEvent*>(e);
if (me->action() == cgt::MouseEvent::PRESSED && me->modifiers() & cgt::Event::CTRL) {
// unproject mouse click through FirstHitPoint texture of raycaster
ScopedTypedData<RenderData> rd(getDataContainer(), _mvr.p_outputImageId.getValue());
if (rd != nullptr && rd->getNumColorTextures() == 3) {
const ImageRepresentationLocal* FHP = rd->getColorTexture(1)->getRepresentation<ImageRepresentationLocal>();
cgt::svec3 lookupPosition(me->x(), me->viewport().y - me->y(), 0);
void NeuroDemo::executePipeline() {
AutoEvaluationPipeline::executePipeline();
_horizontalSplitter.render(getDataContainer());
}
if (cgt::hand(cgt::lessThan(lookupPosition, FHP->getSize()))) {
LINFO("Lookup Position: " << lookupPosition);
void NeuroDemo::onReaderValidated(AbstractProcessor* p) {
}
cgt::vec3 worldPosition(0.f);
for (size_t i = 0; i < 3; ++i)
worldPosition[i] = FHP->getElementNormalized(lookupPosition, i);
void NeuroDemo::onSplitterEvent(size_t index, cgt::Event* e) {
LINFO("World Position: " << worldPosition);
if (typeid(*e) == typeid(cgt::MouseEvent)) {
cgt::MouseEvent* me = static_cast<cgt::MouseEvent*>(e);
// add to base points
if (! (me->modifiers() & cgt::Event::SHIFT))
_mprBasePoints.clear();
_mprBasePoints.push_back(worldPosition);
if (index == 0) {
if (me->action() == cgt::MouseEvent::PRESSED && me->modifiers() & cgt::Event::CTRL) {
// unproject mouse click through FirstHitPoint texture of raycaster
ScopedTypedData<RenderData> rd(getDataContainer(), _mvmpr2D.p_outputImageId.getValue());
if (rd != nullptr && rd->getNumColorTextures() >= 2) {
const ImageRepresentationLocal* FHP = rd->getColorTexture(1)->getRepresentation<ImageRepresentationLocal>();
cgt::svec3 lookupPosition(me->x(), me->viewport().y - me->y(), 0);
if (_mprBasePoints.size() > 2) {
const cgt::vec3& a = _mprBasePoints[_mprBasePoints.size() - 3];
const cgt::vec3& b = _mprBasePoints[_mprBasePoints.size() - 2];
const cgt::vec3& c = _mprBasePoints[_mprBasePoints.size() - 1];
if (cgt::hand(cgt::lessThan(lookupPosition, FHP->getSize()))) {
LINFO("Lookup Position: " << lookupPosition);
cgt::vec3 n = cgt::normalize(cgt::cross(b-a, c-a));
float d = cgt::dot(a, n);
cgt::vec3 worldPosition(0.f);
for (size_t i = 0; i < 3; ++i)
worldPosition[i] = FHP->getElementNormalized(lookupPosition, i);
_mvmpr.p_planeNormal.setValue(n);
_mvmpr.p_planeDistance.setValue(-d);
addBasePoint(!(me->modifiers() & cgt::Event::SHIFT), worldPosition);
}
}
}
me->accept();
else {
_slicePositionEventHandler.onEvent(e);
}
}
else if (index == 1) {
if (me->action() == cgt::MouseEvent::PRESSED && me->modifiers() & cgt::Event::CTRL) {
// unproject mouse click through FirstHitPoint texture of raycaster
ScopedTypedData<RenderData> rd(getDataContainer(), _mvr.p_outputImageId.getValue());
if (rd != nullptr && rd->getNumColorTextures() >= 2) {
const ImageRepresentationLocal* FHP = rd->getColorTexture(1)->getRepresentation<ImageRepresentationLocal>();
cgt::svec3 lookupPosition(me->x(), me->viewport().y - me->y(), 0);
if (cgt::hand(cgt::lessThan(lookupPosition, FHP->getSize()))) {
LINFO("Lookup Position: " << lookupPosition);
cgt::vec3 worldPosition(0.f);
for (size_t i = 0; i < 3; ++i)
worldPosition[i] = FHP->getElementNormalized(lookupPosition, i);
addBasePoint(!(me->modifiers() & cgt::Event::SHIFT), worldPosition);
}
}
}
else {
_tcp.onEvent(e);
}
}
}
}
void NeuroDemo::addBasePoint(bool clear, const cgt::vec3& position) {
LINFO("World Position: " << position);
// add to base points
if (clear)
_mprBasePoints.clear();
_mprBasePoints.push_back(position);
//if (e->isAccepted())
AutoEvaluationPipeline::onEvent(e);
if (_mprBasePoints.size() > 2) {
const cgt::vec3& a = _mprBasePoints[_mprBasePoints.size() - 3];
const cgt::vec3& b = _mprBasePoints[_mprBasePoints.size() - 2];
const cgt::vec3& c = _mprBasePoints[_mprBasePoints.size() - 1];
cgt::vec3 n = cgt::normalize(cgt::cross(b-a, c-a));
float d = cgt::dot(a, n);
_mvmpr2D.p_planeNormal.setValue(n);
_mvmpr2D.p_planeDistance.setValue(-d);
}
}
}
\ No newline at end of file
......@@ -25,7 +25,9 @@
#ifndef NEURODEMO_H__
#define NEURODEMO_H__
#include "core/eventhandlers/mwheeltonumericpropertyeventlistener.h"
#include "core/pipeline/autoevaluationpipeline.h"
#include "core/pipeline/viewportsplitter.h"
#include "modules/modulesapi.h"
#include "modules/pipelinefactory.h"
......@@ -52,17 +54,23 @@ namespace campvis {
/// \see AutoEvaluationPipeline::init()
virtual void init();
virtual void deinit();
/// \see AbstractPipeline::getName()
virtual const std::string getName() const { return getId(); };
/// \see AbstractPipeline::getId()
static const std::string getId() { return "NeuroDemo"; };
/// \see AbstractPipeline::executePipeline()
virtual void executePipeline();
protected:
void onReaderValidated(AbstractProcessor* p);
void onEvent(cgt::Event* e);
void onSplitterEvent(size_t index, cgt::Event* e);
void addBasePoint(bool clear, const cgt::vec3& position);
LightSourceProvider _lsp;
TrackballCameraProvider _tcp;
......@@ -70,10 +78,16 @@ namespace campvis {
GenericImageReader _t1Reader;
GenericImageReader _petReader;
neuro::MultiVolumeMprRenderer _mvmpr;
neuro::MultiVolumeMprRenderer _mvmpr2D;
neuro::MultiVolumeMprRenderer _mvmpr3D;
neuro::MultiVolumeRaycaster _mvr;
RenderTargetCompositor _rtc;
ViewportSplitter _horizontalSplitter;
MWheelToNumericPropertyEventListener _slicePositionEventHandler;
private:
std::vector<cgt::vec3> _mprBasePoints;
};
......
......@@ -57,7 +57,7 @@ namespace neuro {
, p_transferFunction2("TransferFunction2", "Transfer Function for Second image", new SimpleTransferFunction(256))
, p_transferFunction3("TransferFunction3", "Transfer Function for Third image", new SimpleTransferFunction(256))
, p_planeNormal("PlaneNormal", "Clipping Plane Normal", cgt::vec3(0.f, 0.f, 1.f), cgt::vec3(-1.f), cgt::vec3(1.f), cgt::vec3(.1f), cgt::ivec3(2))
, p_planeDistance("PlaneDistance", "Clipping Plane Distance", 0.f, -1000.f, 1000.f, 1.f, 1)
, p_planeDistance("PlaneDistance", "Clipping Plane Distance", 0.f, -1000.f, 1000.f, .5f, 1)
, p_planeSize("PlaneSize", "Clipping Plane Size", 100.f, 0.f, 1000.f, 1.f, 1)
, p_use2DProjection("Use3dRendering", "Use 3D Rendering instead of 2D", true)
, p_relativeToImageCenter("RelativeToImageCenter", "Construct Plane Relative to Image Center", true)
......@@ -150,8 +150,10 @@ namespace neuro {
// perform the rendering
glEnable(GL_DEPTH_TEST);
_shader->activate();
_shader->setUniform("_lineWidth", p_lineWidth.getValue());
_shader->setUniform("_transparency", p_transparency.getValue());
if (p_showWireframe.getValue()) {
_shader->setUniform("_lineWidth", p_lineWidth.getValue());
_shader->setUniform("_transparency", p_transparency.getValue());
}
// calculate viewport matrix for NDC -> viewport conversion
cgt::vec2 halfViewport = cgt::vec2(getEffectiveViewportSize()) / 2.f;
......@@ -187,12 +189,17 @@ namespace neuro {
p_transferFunction3.getTF()->bind(_shader, tf3Unit, "_transferFunction3", "_transferFunctionParams3");
FramebufferActivationGuard fag(this);
createAndAttachColorTexture();
createAndAttachTexture(GL_RGBA8);
createAndAttachTexture(GL_RGBA32F);
createAndAttachDepthTexture();
static const GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
glDrawBuffers(2, buffers);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
slice.render(GL_TRIANGLE_FAN);
glDrawBuffers(1, buffers);
_shader->deactivate();
cgt::TextureUnit::setZeroUnit();
glDisable(GL_DEPTH_TEST);
......
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