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

Work on VolumeExplorer macro processor

parent b34862f7
......@@ -33,6 +33,7 @@
#include "modules/vis/pipelines/ixpvdemo.h"
#include "modules/vis/pipelines/dvrvis.h"
#include "modules/vis/pipelines/volumerendererdemo.h"
#include "modules/vis/pipelines/volumeexplorerdemo.h"
#include "modules/vis/pipelines/slicevis.h"
#ifdef HAS_KISSCL
#include "modules/opencl/pipelines/openclpipeline.h"
......@@ -69,8 +70,9 @@ int main(int argc, char** argv) {
//app.addVisualizationPipeline("Confidence Map Generation", new CmBatchGeneration());
// app.addVisualizationPipeline("IXPV", new IxpvDemo());
//app.addVisualizationPipeline("SliceVis", new SliceVis());
app.addVisualizationPipeline("DVRVis", new DVRVis());
//app.addVisualizationPipeline("DVRVis", new DVRVis());
app.addVisualizationPipeline("VolumeRendererDemo", new VolumeRendererDemo());
app.addVisualizationPipeline("VolumeExplorerDemo", new VolumeExplorerDemo());
#ifdef HAS_KISSCL
//app.addVisualizationPipeline("DVR with OpenCL", new OpenCLPipeline());
#endif
......
......@@ -101,11 +101,13 @@ namespace campvis {
if (typeid(*e) == typeid(tgt::MouseEvent)) {
tgt::MouseEvent* me = static_cast<tgt::MouseEvent*>(e);
if (me->action() == tgt::MouseEvent::PRESSED) {
_parentPipeline->enableLowQualityMode();
if (_parentPipeline)
_parentPipeline->enableLowQualityMode();
_trackball->mousePressEvent(me);
}
else if (me->action() == tgt::MouseEvent::RELEASED) {
_parentPipeline->disableLowQualityMode();
if (_parentPipeline)
_parentPipeline->disableLowQualityMode();
_trackball->mouseReleaseEvent(me);
}
else if (me->action() == tgt::MouseEvent::MOTION)
......
......@@ -47,7 +47,7 @@ namespace campvis {
, p_entryImageID("entryImageID", "Input Entry Points Image", "", DataNameProperty::READ)
, p_exitImageID("exitImageID", "Input Exit Points Image", "", DataNameProperty::READ)
, p_camera("camera", "Camera")
, p_transferFunction("transferFunction", "Transfer Function", new SimpleTransferFunction(256))
, p_transferFunction("TransferFunction", "Transfer Function", new SimpleTransferFunction(256))
, p_samplingRate("SamplingRate", "Sampling Rate", 2.f, 0.1f, 10.f)
, p_jitterEntryPoints("jitterEntryPoints", "Jitter Entry Points", true)
, p_jitterStepSizeMultiplier("jitterStepSizeMultiplier", "Jitter Step Size Multiplier", .5f, .1f, 1.f)
......
......@@ -76,4 +76,8 @@ namespace campvis {
s_AfterTFReplace(_transferFunction);
}
void TransferFunctionProperty::addSharedProperty(AbstractProperty* prop) {
tgtAssert(false, "Sharing of TF properties not supported!");
}
}
......@@ -57,6 +57,9 @@ namespace campvis {
/// \see AbstractProperty::deinit()
virtual void deinit();
/// \see AbstractProperty::addSharedProperty()
virtual void addSharedProperty(AbstractProperty* prop);
/**
* Gets the TransferFunction of this property.
......
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012, all rights reserved,
// Christian Schulte zu Berge <christian.szb@in.tum.de>
// Chair for Computer Aided Medical Procedures
// Technische Universitt Mnchen
// Boltzmannstr. 3, 85748 Garching b. Mnchen, Germany
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
//
// The licensing of this softare is not yet resolved. Until then, redistribution in source or
// binary forms outside the CAMP chair is not permitted, unless explicitly stated in legal form.
// However, the names of the original authors and the above copyright notice must retain in its
// original state in any case.
//
// Legal disclaimer provided by the BSD license:
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// ================================================================================================
#include "volumeexplorerdemo.h"
#include "tgt/event/keyevent.h"
#include "tgt/glcontext.h"
#include "tgt/qt/qtcontextmanager.h"
#include "core/datastructures/imagedata.h"
#include "core/classification/geometry1dtransferfunction.h"
#include "core/classification/tfgeometry1d.h"
namespace campvis {
VolumeExplorerDemo::VolumeExplorerDemo()
: VisualizationPipeline()
, _camera("camera", "Camera")
, _imageReader()
, _ve(_effectiveRenderTargetSize)
{
addProperty(&_camera);
addProcessor(&_imageReader);
addProcessor(&_ve);
addEventHandler(&_ve);
}
VolumeExplorerDemo::~VolumeExplorerDemo() {
}
void VolumeExplorerDemo::init() {
VisualizationPipeline::init();
_imageReader.s_validated.connect(this, &VolumeExplorerDemo::onProcessorValidated);
_camera.addSharedProperty(&_ve.p_camera);
_ve.p_outputImage.setValue("combine");
_renderTargetID.setValue("combine");
_imageReader.p_url.setValue("D:\\Medical Data\\smallHeart.mhd");
_imageReader.p_targetImageID.setValue("reader.output");
_imageReader.p_targetImageID.connect(&_ve.p_inputVolume);
Geometry1DTransferFunction* dvrTF = new Geometry1DTransferFunction(128, tgt::vec2(0.f, .05f));
dvrTF->addGeometry(TFGeometry1D::createQuad(tgt::vec2(.1f, .125f), tgt::col4(255, 0, 0, 32), tgt::col4(255, 0, 0, 32)));
dvrTF->addGeometry(TFGeometry1D::createQuad(tgt::vec2(.4f, .5f), tgt::col4(0, 255, 0, 128), tgt::col4(0, 255, 0, 128)));
static_cast<TransferFunctionProperty*>(_ve.getProperty("TransferFunction"))->replaceTF(dvrTF);
_effectiveRenderTargetSize.s_changed.connect<VolumeExplorerDemo>(this, &VolumeExplorerDemo::onRenderTargetSizeChanged);
}
void VolumeExplorerDemo::deinit() {
_effectiveRenderTargetSize.s_changed.disconnect(this);
VisualizationPipeline::deinit();
}
const std::string VolumeExplorerDemo::getName() const {
return "VolumeExplorerDemo";
}
void VolumeExplorerDemo::onRenderTargetSizeChanged(const AbstractProperty* prop) {
}
void VolumeExplorerDemo::onProcessorValidated(AbstractProcessor* processor) {
}
}
\ No newline at end of file
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012, all rights reserved,
// Christian Schulte zu Berge <christian.szb@in.tum.de>
// Chair for Computer Aided Medical Procedures
// Technische Universität München
// Boltzmannstr. 3, 85748 Garching b. München, Germany
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
//
// The licensing of this softare is not yet resolved. Until then, redistribution in source or
// binary forms outside the CAMP chair is not permitted, unless explicitly stated in legal form.
// However, the names of the original authors and the above copyright notice must retain in its
// original state in any case.
//
// Legal disclaimer provided by the BSD license:
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// ================================================================================================
#ifndef VolumeExplorerDemo_H__
#define VolumeExplorerDemo_H__
#include "core/eventhandlers/trackballnavigationeventhandler.h"
#include "core/pipeline/visualizationpipeline.h"
#include "core/properties/cameraproperty.h"
#include "modules/io/processors/mhdimagereader.h"
#include "modules/vis/processors/volumeexplorer.h"
namespace campvis {
class VolumeExplorerDemo : public VisualizationPipeline {
public:
/**
* Creates a VisualizationPipeline.
*/
VolumeExplorerDemo();
/**
* Virtual Destructor
**/
virtual ~VolumeExplorerDemo();
/// \see VisualizationPipeline::init()
virtual void init();
/// \see VisualizationPipeline::deinit()
virtual void deinit();
/// \see AbstractPipeline::getName()
virtual const std::string getName() const;
void onRenderTargetSizeChanged(const AbstractProperty* prop);
protected:
/**
* Slot getting called when one of the observed processors got validated.
* Updates the camera properties, when the input image has changed.
* \param processor The processor that emitted the signal
*/
virtual void onProcessorValidated(AbstractProcessor* processor);
CameraProperty _camera;
MhdImageReader _imageReader;
VolumeExplorer _ve;
};
}
#endif // VolumeExplorerDemo_H__
......@@ -75,7 +75,7 @@ namespace campvis {
Geometry1DTransferFunction* dvrTF = new Geometry1DTransferFunction(128, tgt::vec2(0.f, .05f));
dvrTF->addGeometry(TFGeometry1D::createQuad(tgt::vec2(.1f, .125f), tgt::col4(255, 0, 0, 32), tgt::col4(255, 0, 0, 32)));
dvrTF->addGeometry(TFGeometry1D::createQuad(tgt::vec2(.4f, .5f), tgt::col4(0, 255, 0, 128), tgt::col4(0, 255, 0, 128)));
static_cast<TransferFunctionProperty*>(_vr.getProperty("transferFunction"))->replaceTF(dvrTF);
static_cast<TransferFunctionProperty*>(_vr.getProperty("TransferFunction"))->replaceTF(dvrTF);
_trackballEH->setViewportSize(_effectiveRenderTargetSize.getValue());
_effectiveRenderTargetSize.s_changed.connect<VolumeRendererDemo>(this, &VolumeRendererDemo::onRenderTargetSizeChanged);
......
......@@ -48,21 +48,26 @@ namespace campvis {
, p_xSlice("XSlice", "Slice in YZ Plane", 0, 0, 0, INVALID_RESULT | SLICES_INVALID)
, p_ySlice("YSlice", "Slice in XZ Plane", 0, 0, 0, INVALID_RESULT | SLICES_INVALID)
, p_zSlice("ZSlice", "Slice in XY Plane", 0, 0, 0, INVALID_RESULT | SLICES_INVALID)
, p_transferFunction("TransferFunction", "Transfer Function", new SimpleTransferFunction(128))
, p_outputImage("OutputImage", "Output Image", "ve.output", DataNameProperty::WRITE)
, _raycaster(canvasSize)
, _sliceExtractor(canvasSize)
, p_sliceRenderSize("SliceRenderSize", "Slice Render Size", tgt::ivec2(32), tgt::ivec2(0), tgt::ivec2(10000), AbstractProcessor::VALID)
, p_volumeRenderSize("VolumeRenderSize", "Volume Render Size", tgt::ivec2(32), tgt::ivec2(0), tgt::ivec2(10000), AbstractProcessor::VALID)
, _xSliceHandler(&p_xSlice)
, _ySliceHandler(&p_ySlice)
, _zSliceHandler(&p_zSlice)
, _windowingHandler(&_sliceExtractor.p_transferFunction)
, _trackballEH(0)
{
addProperty(&p_inputVolume);
addProperty(&p_camera);
addProperty(&p_xSlice);
addProperty(&p_ySlice);
addProperty(&p_zSlice);
addProperty(&p_transferFunction);
addProperty(&p_outputImage);
addProperty(&_sliceExtractor.p_transferFunction);
addProperty(_raycaster.getProperty("TransferFunction"));
p_inputVolume.addSharedProperty(&_raycaster.p_inputVolume);
p_inputVolume.addSharedProperty(&_sliceExtractor.p_sourceImageID);
......@@ -74,10 +79,17 @@ namespace campvis {
p_sliceRenderSize.addSharedProperty(&_sliceExtractor._renderTargetSize);
p_volumeRenderSize.addSharedProperty(&_raycaster._renderTargetSize);
addProperty(&p_sliceRenderSize);
addProperty(&p_volumeRenderSize);
// Event-Handlers
_trackballEH = new TrackballNavigationEventHandler(0, &_raycaster.p_camera, p_volumeRenderSize.getValue());
}
VolumeExplorer::~VolumeExplorer() {
delete _trackballEH;
}
void VolumeExplorer::init() {
......@@ -89,9 +101,6 @@ namespace campvis {
_shader->setAttributeLocation(0, "in_Position");
_shader->setAttributeLocation(1, "in_TexCoord");
p_transferFunction.addSharedProperty(_sliceExtractor.getProperty("TransferFunction"));
p_transferFunction.addSharedProperty(&_sliceExtractor.p_transferFunction);
_raycaster.s_invalidated.connect(this, &VolumeExplorer::onProcessorInvalidated);
std::vector<tgt::vec3> vertices, texCorods;
......@@ -107,6 +116,8 @@ namespace campvis {
_quad = new FaceGeometry(vertices, texCorods);
_quad->createGLBuffers();
_trackballEH->setViewportSize(p_volumeRenderSize.getValue());
}
void VolumeExplorer::deinit() {
......@@ -155,6 +166,10 @@ namespace campvis {
if (prop == &_renderTargetSize) {
p_sliceRenderSize.setValue(tgt::ivec2(_renderTargetSize.getValue().y / 3, _renderTargetSize.getValue().y / 3));
p_volumeRenderSize.setValue(tgt::ivec2(_renderTargetSize.getValue().x - _renderTargetSize.getValue().y / 3, _renderTargetSize.getValue().y));
_trackballEH->setViewportSize(p_volumeRenderSize.getValue());
float ratio = static_cast<float>(p_volumeRenderSize.getValue().x) / static_cast<float>(p_volumeRenderSize.getValue().y);
_raycaster.p_camera.setWindowRatio(ratio);
}
if (prop == &p_outputImage) {
_raycaster.p_outputImage.setValue(p_outputImage.getValue() + ".raycaster");
......@@ -182,8 +197,8 @@ namespace campvis {
_shader->activate();
tgt::vec2 rts(_renderTargetSize.getValue());
const tgt::ivec2 vrs = p_volumeRenderSize.getValue();
const tgt::ivec2 srs = p_sliceRenderSize.getValue();
const tgt::ivec2& vrs = p_volumeRenderSize.getValue();
const tgt::ivec2& srs = p_sliceRenderSize.getValue();
_shader->setUniform("_projectionMatrix", tgt::mat4::createOrtho(0, rts.x, rts.y, 0, -1, 1));
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
......@@ -226,12 +241,17 @@ namespace campvis {
if (processor == &_raycaster) {
invalidate(VR_INVALID);
}
if (processor == &_sliceExtractor) {
invalidate(SLICES_INVALID);
}
invalidate(AbstractProcessor::INVALID_RESULT);
}
void VolumeExplorer::updateProperties(DataHandle img) {
p_transferFunction.getTF()->setImageHandle(img);
_sliceExtractor.p_transferFunction.getTF()->setImageHandle(img);
static_cast<TransferFunctionProperty*>(_raycaster.getProperty("TransferFunction"))->getTF()->setImageHandle(img);
const tgt::svec3& imgSize = static_cast<const ImageData*>(img.getData())->getSize();
if (p_xSlice.getMaxValue() != imgSize.x - 1){
p_xSlice.setMaxValue(static_cast<int>(imgSize.x) - 1);
......@@ -242,6 +262,21 @@ namespace campvis {
if (p_zSlice.getMaxValue() != imgSize.z - 1){
p_zSlice.setMaxValue(static_cast<int>(imgSize.z) - 1);
}
tgt::Bounds volumeExtent = static_cast<const ImageData*>(img.getData())->getWorldBounds();
tgt::vec3 pos = volumeExtent.center() - tgt::vec3(0, 0, tgt::length(volumeExtent.diagonal()));
_trackballEH->setSceneBounds(volumeExtent);
_trackballEH->setCenter(volumeExtent.center());
_trackballEH->reinitializeCamera(pos, volumeExtent.center(), _raycaster.p_camera.getValue().getUpVector());
}
bool VolumeExplorer::accept(tgt::Event* e) {
return true;
}
void VolumeExplorer::execute(tgt::Event* e) {
_trackballEH->execute(e);
}
}
......
......@@ -30,6 +30,11 @@
#ifndef VOLUMEEXPLORER_H__
#define VOLUMEEXPLORER_H__
#include "core/eventhandlers/abstracteventhandler.h"
#include "core/eventhandlers/mwheeltonumericpropertyeventhandler.h"
#include "core/eventhandlers/trackballnavigationeventhandler.h"
#include "core/eventhandlers/transfuncwindowingeventhandler.h"
#include "core/pipeline/visualizationprocessor.h"
#include "core/properties/datanameproperty.h"
#include "core/properties/numericproperty.h"
......@@ -47,7 +52,7 @@ namespace campvis {
/**
* Combines a volume raycaster and 3 slice views for explorative volume visualization.
*/
class VolumeExplorer : public VisualizationProcessor {
class VolumeExplorer : public VisualizationProcessor, public AbstractEventHandler {
public:
/**
* Constructs a new VolumeExplorer Processor
......@@ -74,6 +79,11 @@ namespace campvis {
/// \see AbstractProcessor::getProcessorState()
virtual const ProcessorState getProcessorState() const { return AbstractProcessor::EXPERIMENTAL; };
/// \see AbstractEventHandler::accept()
virtual bool accept(tgt::Event* e);
/// \see AbstractEventHandler::execute()
virtual void execute(tgt::Event* e);
virtual void process(DataContainer& data);
DataNameProperty p_inputVolume; ///< image ID for first input image
......@@ -82,7 +92,6 @@ namespace campvis {
IntProperty p_xSlice;
IntProperty p_ySlice;
IntProperty p_zSlice;
TransferFunctionProperty p_transferFunction;
DataNameProperty p_outputImage; ///< image ID for output image
......@@ -120,6 +129,13 @@ namespace campvis {
IVec2Property p_sliceRenderSize;
IVec2Property p_volumeRenderSize;
MWheelToNumericPropertyEventHandler _xSliceHandler;
MWheelToNumericPropertyEventHandler _ySliceHandler;
MWheelToNumericPropertyEventHandler _zSliceHandler;
TransFuncWindowingEventHandler _windowingHandler;
TrackballNavigationEventHandler* _trackballEH;
static const std::string loggerCat_;
};
......
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