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

Merge branch 'development' of /mnt/bigone/git/repositories/berge/campvis

parents e2fcc506 1c50f447
...@@ -28,24 +28,6 @@ ...@@ -28,24 +28,6 @@
// ================================================================================================ // ================================================================================================
#include "application/campvisapplication.h" #include "application/campvisapplication.h"
#include "modules/advancedusvis/pipelines/advancedusvis.h"
#include "modules/advancedusvis/pipelines/cmbatchgeneration.h"
#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"
#endif
#ifdef CAMPVIS_HAS_MODULE_SCR_MSK
#include "modules/scr_msk/pipelines/uscompounding.h"
#endif
#ifdef CAMPVIS_HAS_MODULE_COLUMBIA
#include "modules/columbia/pipelines/columbia1.h"
#endif
#ifdef Q_WS_X11 #ifdef Q_WS_X11
#include <X11/Xlib.h> #include <X11/Xlib.h>
...@@ -66,27 +48,6 @@ int main(int argc, char** argv) { ...@@ -66,27 +48,6 @@ int main(int argc, char** argv) {
#endif #endif
CampVisApplication app(argc, argv); CampVisApplication app(argc, argv);
//app.addVisualizationPipeline("Advanced Ultrasound Visualization", new AdvancedUsVis());
//app.addVisualizationPipeline("Confidence Map Generation", new CmBatchGeneration());
// app.addVisualizationPipeline("IXPV", new IxpvDemo());
//app.addVisualizationPipeline("SliceVis", new SliceVis());
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
#ifdef CAMPVIS_HAS_MODULE_SCR_MSK
//app.addVisualizationPipeline("US Compounding", new UsCompounding());
#endif
#ifdef CAMPVIS_HAS_MODULE_COLUMBIA
//app.addVisualizationPipeline("Columbia", new Columbia1());
#endif
app.init(); app.init();
int toReturn = app.run(); int toReturn = app.run();
app.deinit(); app.deinit();
......
...@@ -47,9 +47,10 @@ ...@@ -47,9 +47,10 @@
#include "application/gui/mainwindow.h" #include "application/gui/mainwindow.h"
#include "core/tools/opengljobprocessor.h" #include "core/tools/opengljobprocessor.h"
#include "core/tools/simplejobprocessor.h" #include "core/tools/simplejobprocessor.h"
#include "core/tools/stringutils.h"
#include "core/tools/quadrenderer.h" #include "core/tools/quadrenderer.h"
#include "core/pipeline/abstractpipeline.h" #include "core/pipeline/abstractpipeline.h"
#include "core/pipeline/visualizationpipeline.h" #include "modules/pipelinefactory.h"
namespace campvis { namespace campvis {
...@@ -78,17 +79,29 @@ namespace campvis { ...@@ -78,17 +79,29 @@ namespace campvis {
tgtAssert(_initialized == false, "Destructing initialized CampVisApplication, deinitialize first!"); tgtAssert(_initialized == false, "Destructing initialized CampVisApplication, deinitialize first!");
// delete everything in the right order: // delete everything in the right order:
for (std::vector< std::pair<VisualizationPipeline*, TumVisPainter*> >::iterator it = _visualizations.begin(); it != _visualizations.end(); ++it) { for (std::vector< std::pair<AbstractPipeline*, CampVisPainter*> >::iterator it = _visualizations.begin(); it != _visualizations.end(); ++it) {
delete it->second; delete it->second;
} }
for (std::vector<AbstractPipeline*>::iterator it = _pipelines.begin(); it != _pipelines.end(); ++it) { for (std::vector<AbstractPipeline*>::iterator it = _pipelines.begin(); it != _pipelines.end(); ++it) {
delete *it; delete *it;
} }
for (std::vector<DataContainer*>::iterator it = _dataContainers.begin(); it != _dataContainers.end(); ++it) {
delete *it;
}
} }
void CampVisApplication::init() { void CampVisApplication::init() {
tgtAssert(_initialized == false, "Tried to initialize CampVisApplication twice."); tgtAssert(_initialized == false, "Tried to initialize CampVisApplication twice.");
// parse argument list and create pipelines
QStringList pipelinesToAdd = this->arguments();
for (int i = 1; i < pipelinesToAdd.size(); ++i) {
DataContainer* dc = createAndAddDataContainer("DataContainer #" + StringUtils::toString(_dataContainers.size() + 1));
AbstractPipeline* p = PipelineFactory::getRef().createPipeline(pipelinesToAdd[i].toStdString(), dc);
if (p != 0)
addPipeline(pipelinesToAdd[i].toStdString(), p);
}
// Init TGT // Init TGT
tgt::InitFeature::Features featureset = tgt::InitFeature::ALL; tgt::InitFeature::Features featureset = tgt::InitFeature::ALL;
tgt::init(featureset); tgt::init(featureset);
...@@ -167,7 +180,7 @@ namespace campvis { ...@@ -167,7 +180,7 @@ namespace campvis {
} }
// Now init painters: // Now init painters:
for (std::vector< std::pair<VisualizationPipeline*, TumVisPainter*> >::iterator it = _visualizations.begin(); it != _visualizations.end(); ++it) { for (std::vector< std::pair<AbstractPipeline*, CampVisPainter*> >::iterator it = _visualizations.begin(); it != _visualizations.end(); ++it) {
it->second->init(); it->second->init();
} }
...@@ -190,7 +203,7 @@ namespace campvis { ...@@ -190,7 +203,7 @@ namespace campvis {
} }
// Now deinit painters: // Now deinit painters:
for (std::vector< std::pair<VisualizationPipeline*, TumVisPainter*> >::iterator it = _visualizations.begin(); it != _visualizations.end(); ++it) { for (std::vector< std::pair<AbstractPipeline*, CampVisPainter*> >::iterator it = _visualizations.begin(); it != _visualizations.end(); ++it) {
it->second->deinit(); it->second->deinit();
} }
...@@ -235,33 +248,57 @@ namespace campvis { ...@@ -235,33 +248,57 @@ namespace campvis {
return toReturn; return toReturn;
} }
void CampVisApplication::addPipeline(AbstractPipeline* pipeline) { void CampVisApplication::addPipeline(const std::string& name, AbstractPipeline* pipeline) {
tgtAssert(_initialized == false, "Adding pipelines after initialization is currently not supported.");
tgtAssert(pipeline != 0, "Pipeline must not be 0."); tgtAssert(pipeline != 0, "Pipeline must not be 0.");
_pipelines.push_back(pipeline);
// if CAMPVis is already fully initialized, we need to temporarily shut down its
// OpenGL job processor, since we need to create a new context.
if (_initialized) {
GLJobProc.pause();
{
tgt::QtThreadedCanvas* canvas = CtxtMgr.createContext(name, "CAMPVis", tgt::ivec2(512, 512));
tgt::GLContextScopedLock lock(canvas->getContext());
addPipelineImpl(canvas, name, pipeline);
}
GLJobProc.resume();
}
else {
tgt::QtThreadedCanvas* canvas = CtxtMgr.createContext(name, "CAMPVis", tgt::ivec2(512, 512));
addPipelineImpl(canvas, name, pipeline);
}
s_PipelinesChanged(); s_PipelinesChanged();
} }
void CampVisApplication::addVisualizationPipeline(const std::string& name, VisualizationPipeline* vp) { void CampVisApplication::addPipelineImpl(tgt::QtThreadedCanvas* canvas, const std::string& name, AbstractPipeline* pipeline) {
tgtAssert(_initialized == false, "Adding pipelines after initialization is currently not supported."); // create canvas and painter for the pipeline and connect all together
tgtAssert(vp != 0, "Pipeline must not be 0.");
// create canvas and painter for the VisPipeline and connect all together
tgt::QtThreadedCanvas* canvas = CtxtMgr.createContext(name, "CAMPVis", tgt::ivec2(512, 512));
GLJobProc.registerContext(canvas); GLJobProc.registerContext(canvas);
_mainWindow->addVisualizationPipelineWidget(name, canvas);
canvas->init(); canvas->init();
TumVisPainter* painter = new TumVisPainter(canvas, vp); CampVisPainter* painter = new CampVisPainter(canvas, pipeline);
canvas->setPainter(painter, false); canvas->setPainter(painter, false);
pipeline->setCanvas(canvas);
_visualizations.push_back(std::make_pair(vp, painter)); _visualizations.push_back(std::make_pair(pipeline, painter));
_pipelines.push_back(pipeline);
vp->setCanvas(canvas); if (_initialized) {
addPipeline(vp); LGL_ERROR;
pipeline->init();
LGL_ERROR;
painter->init();
LGL_ERROR;
}
CtxtMgr.releaseCurrentContext(); CtxtMgr.releaseCurrentContext();
_mainWindow->addVisualizationPipelineWidget(name, canvas);
// enable pipeline and invalidate all processors
pipeline->setEnabled(true);
for (std::vector<AbstractProcessor*>::const_iterator it = pipeline->getProcessors().begin(); it != pipeline->getProcessors().end(); ++it) {
(*it)->invalidate(AbstractProcessor::INVALID_RESULT);
}
} }
void CampVisApplication::registerDockWidget(Qt::DockWidgetArea area, QDockWidget* dock) { void CampVisApplication::registerDockWidget(Qt::DockWidgetArea area, QDockWidget* dock) {
...@@ -270,4 +307,12 @@ namespace campvis { ...@@ -270,4 +307,12 @@ namespace campvis {
_mainWindow->addDockWidget(area, dock); _mainWindow->addDockWidget(area, dock);
} }
DataContainer* CampVisApplication::createAndAddDataContainer(const std::string& name) {
DataContainer* dc = new DataContainer(name);
_dataContainers.push_back(dc);
s_DataContainersChanged();
return dc;
}
} }
...@@ -38,6 +38,8 @@ ...@@ -38,6 +38,8 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "core/datastructures/datacontainer.h"
namespace tgt { namespace tgt {
class QtThreadedCanvas; class QtThreadedCanvas;
} }
...@@ -45,8 +47,7 @@ namespace tgt { ...@@ -45,8 +47,7 @@ namespace tgt {
namespace campvis { namespace campvis {
class AbstractPipeline; class AbstractPipeline;
class MainWindow; class MainWindow;
class TumVisPainter; class CampVisPainter;
class VisualizationPipeline;
/** /**
* The CampVisApplication class wraps Pipelines, Evaluators and Painters all together and takes * The CampVisApplication class wraps Pipelines, Evaluators and Painters all together and takes
...@@ -89,25 +90,14 @@ namespace campvis { ...@@ -89,25 +90,14 @@ namespace campvis {
void deinit(); void deinit();
/** /**
* Adds a pipeline which doesn't need visualization (OpenGL) support. * Adds a pipeline to this CAMPVis application.
* Each pipeline will automatically get its own evaluator. * Each pipeline will automatically get its own OpenGL context, the corresponding CampvisPainter
* * and all necessary connections will be created.
* \note If you want to add a pipeline that needs a valid OpenGL context, use
* addVisualizationPipeline() instead.
* \param pipeline Pipeline to add, must not need OpenGL support.
*/
void addPipeline(AbstractPipeline* pipeline);
/**
* Adds a visualization pipeline (i.e. a pipeline that needs a OpenGL context).
* For each added pipeline, an OpenGL context will be created (for the evaluation
* and rendering).
* *
* \note You do \b not need to call addPipeline.
* \param name Name of the OpenGL context to create for the pipeline. * \param name Name of the OpenGL context to create for the pipeline.
* \param vp VisualizationPipeline to add. * \param vp AbstractPipeline to add.
*/ */
void addVisualizationPipeline(const std::string& name, VisualizationPipeline* vp); void addPipeline(const std::string& name, AbstractPipeline* pipeline);
/** /**
* Adds a dock widget to the main window. * Adds a dock widget to the main window.
...@@ -125,14 +115,30 @@ namespace campvis { ...@@ -125,14 +115,30 @@ namespace campvis {
*/ */
int run(); int run();
/**
* Creates a new DataContainer with the given name.
* \param name Name of the new DataContainer
* \return The newly created DataContainer
*/
DataContainer* createAndAddDataContainer(const std::string& name);
/// Signal emitted when the collection of pipelines has changed. /// Signal emitted when the collection of pipelines has changed.
sigslot::signal0<> s_PipelinesChanged; sigslot::signal0<> s_PipelinesChanged;
/// Signal emitted when the collection of DataContainers has changed.
sigslot::signal0<> s_DataContainersChanged;
private: private:
/// All pipelines (incuding VisualizationPipelines) void addPipelineImpl(tgt::QtThreadedCanvas* canvas, const std::string& name, AbstractPipeline* pipeline);
/// All pipelines
std::vector<AbstractPipeline*> _pipelines; std::vector<AbstractPipeline*> _pipelines;
/// All visualisations (i.e. VisualizationPipelines with their corresponding painters/canvases) /// All visualisations (i.e. Pipelines with their corresponding painters/canvases)
std::vector< std::pair<VisualizationPipeline*, TumVisPainter*> > _visualizations; std::vector< std::pair<AbstractPipeline*, CampVisPainter*> > _visualizations;
/// All DataContainers
std::vector<DataContainer*> _dataContainers;
/// A local OpenGL context used for initialization /// A local OpenGL context used for initialization
tgt::QtThreadedCanvas* _localContext; tgt::QtThreadedCanvas* _localContext;
......
...@@ -41,15 +41,15 @@ ...@@ -41,15 +41,15 @@
#include "core/datastructures/imagedata.h" #include "core/datastructures/imagedata.h"
#include "core/datastructures/renderdata.h" #include "core/datastructures/renderdata.h"
#include "core/pipeline/visualizationpipeline.h" #include "core/pipeline/abstractpipeline.h"
#include "core/tools/job.h" #include "core/tools/job.h"
#include "core/tools/opengljobprocessor.h" #include "core/tools/opengljobprocessor.h"
#include "core/tools/quadrenderer.h" #include "core/tools/quadrenderer.h"
namespace campvis { namespace campvis {
const std::string TumVisPainter::loggerCat_ = "CAMPVis.core.TumVisPainter"; const std::string CampVisPainter::loggerCat_ = "CAMPVis.core.CampVisPainter";
TumVisPainter::TumVisPainter(tgt::GLCanvas* canvas, VisualizationPipeline* pipeline) CampVisPainter::CampVisPainter(tgt::GLCanvas* canvas, AbstractPipeline* pipeline)
: Runnable() : Runnable()
, tgt::Painter(canvas) , tgt::Painter(canvas)
, _pipeline(0) , _pipeline(0)
...@@ -60,11 +60,11 @@ namespace campvis { ...@@ -60,11 +60,11 @@ namespace campvis {
setPipeline(pipeline); setPipeline(pipeline);
} }
TumVisPainter::~TumVisPainter() { CampVisPainter::~CampVisPainter() {
} }
void TumVisPainter::stop() { void CampVisPainter::stop() {
// we need to execute run() one more time to ensure correct release of the OpenGL context // we need to execute run() one more time to ensure correct release of the OpenGL context
_stopExecution = true; _stopExecution = true;
_renderCondition.notify_all(); _renderCondition.notify_all();
...@@ -72,7 +72,7 @@ namespace campvis { ...@@ -72,7 +72,7 @@ namespace campvis {
Runnable::stop(); Runnable::stop();
} }
void TumVisPainter::run() { void CampVisPainter::run() {
std::unique_lock<tbb::mutex> lock(CtxtMgr.getGlMutex()); std::unique_lock<tbb::mutex> lock(CtxtMgr.getGlMutex());
while (! _stopExecution) { while (! _stopExecution) {
...@@ -89,7 +89,7 @@ namespace campvis { ...@@ -89,7 +89,7 @@ namespace campvis {
CtxtMgr.releaseCurrentContext(); CtxtMgr.releaseCurrentContext();
} }
void TumVisPainter::paint() { void CampVisPainter::paint() {
if (getCanvas() == 0) if (getCanvas() == 0)
return; return;
...@@ -97,7 +97,7 @@ namespace campvis { ...@@ -97,7 +97,7 @@ namespace campvis {
glViewport(0, 0, size.x, size.y); glViewport(0, 0, size.x, size.y);
// try get Data // try get Data
DataContainer::ScopedTypedData<RenderData> rd(_pipeline->getDataContainer(), _pipeline->getRenderTargetID()); ScopedTypedData<RenderData> rd(_pipeline->getDataContainer(), _pipeline->getRenderTargetID());
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (rd != 0) { if (rd != 0) {
// activate shader // activate shader
...@@ -150,11 +150,11 @@ namespace campvis { ...@@ -150,11 +150,11 @@ namespace campvis {
getCanvas()->swap(); getCanvas()->swap();
} }
void TumVisPainter::sizeChanged(const tgt::ivec2& size) { void CampVisPainter::sizeChanged(const tgt::ivec2& size) {
_pipeline->setRenderTargetSize(size); _pipeline->setRenderTargetSize(size);
} }
void TumVisPainter::init() { void CampVisPainter::init() {
try { try {
// TODO: Remove hardcoded paths, and use ShdrMgr.addPath() at some central location // TODO: Remove hardcoded paths, and use ShdrMgr.addPath() at some central location
_copyShader = ShdrMgr.loadSeparate("core/glsl/passthrough.vert", "core/glsl/copyimage.frag", "", false); _copyShader = ShdrMgr.loadSeparate("core/glsl/passthrough.vert", "core/glsl/copyimage.frag", "", false);
...@@ -164,7 +164,7 @@ namespace campvis { ...@@ -164,7 +164,7 @@ namespace campvis {
} }
} }
void TumVisPainter::deinit() { void CampVisPainter::deinit() {
ShdrMgr.dispose(_copyShader); ShdrMgr.dispose(_copyShader);
if (_pipeline != 0) { if (_pipeline != 0) {
...@@ -175,7 +175,7 @@ namespace campvis { ...@@ -175,7 +175,7 @@ namespace campvis {
} }
} }
void TumVisPainter::setPipeline(VisualizationPipeline* pipeline) { void CampVisPainter::setPipeline(AbstractPipeline* pipeline) {
tgtAssert(pipeline != 0, "The given pipeline must not be 0."); tgtAssert(pipeline != 0, "The given pipeline must not be 0.");
if (_pipeline != 0) { if (_pipeline != 0) {
_pipeline->s_renderTargetChanged.disconnect(this); _pipeline->s_renderTargetChanged.disconnect(this);
...@@ -184,21 +184,21 @@ namespace campvis { ...@@ -184,21 +184,21 @@ namespace campvis {
} }
_pipeline = pipeline; _pipeline = pipeline;
_pipeline->s_renderTargetChanged.connect(this, &TumVisPainter::onRenderTargetChanged); _pipeline->s_renderTargetChanged.connect(this, &CampVisPainter::onRenderTargetChanged);
_pipeline->setRenderTargetSize(getCanvas()->getSize()); _pipeline->setRenderTargetSize(getCanvas()->getSize());
if (getCanvas()->getEventHandler() != 0) if (getCanvas()->getEventHandler() != 0)
getCanvas()->getEventHandler()->addEventListenerToFront(_pipeline); getCanvas()->getEventHandler()->addEventListenerToFront(_pipeline);
} }
void TumVisPainter::repaint() { void CampVisPainter::repaint() {
GLJobProc.enqueueJob(getCanvas(), makeJobOnHeap(this, &TumVisPainter::paint), OpenGLJobProcessor::PaintJob); GLJobProc.enqueueJob(getCanvas(), makeJobOnHeap(this, &CampVisPainter::paint), OpenGLJobProcessor::PaintJob);
} }
void TumVisPainter::onRenderTargetChanged() { void CampVisPainter::onRenderTargetChanged() {
repaint(); repaint();
} }
void TumVisPainter::setCanvas(tgt::GLCanvas* canvas) { void CampVisPainter::setCanvas(tgt::GLCanvas* canvas) {
tgtAssert(dynamic_cast<tgt::QtThreadedCanvas*>(canvas) != 0, "Canvas must be of type QtThreadedCanvas!"); tgtAssert(dynamic_cast<tgt::QtThreadedCanvas*>(canvas) != 0, "Canvas must be of type QtThreadedCanvas!");
Painter::setCanvas(canvas); Painter::setCanvas(canvas);
} }
......
...@@ -44,30 +44,30 @@ namespace tgt { ...@@ -44,30 +44,30 @@ namespace tgt {
} }
namespace campvis { namespace campvis {
class VisualizationPipeline; class AbstractPipeline;
/** /**
* Painter class for CAMPVis, rendering the render target of a VisualizationPipeline. * Painter class for CAMPVis, rendering the render target of an AbstractPipeline.
* This painter implements Runnable, hence, it runs in its own thread and the associated canvas * This painter implements Runnable, hence, it runs in its own thread and the associated canvas
* must be of type QtThreadedCanvas. * must be of type QtThreadedCanvas.
* Rendering is implemented using condidional wait - hence the canvas is only updated when * Rendering is implemented using condidional wait - hence the canvas is only updated when
* \a pipeline emits the s_RenderTargetChanged signal. * \a pipeline emits the s_RenderTargetChanged signal.
* *
* \sa Runnable, VisualizationPipeline * \sa Runnable, AbstractPipeline
*/ */
class TumVisPainter : public Runnable, public tgt::Painter, public sigslot::has_slots<> { class CampVisPainter : public Runnable, public tgt::Painter, public sigslot::has_slots<> {
public: public:
/** /**
* Creates a new TumVisPainter rendering the render target of \a pipeline on \a canvas. * Creates a new CampVisPainter rendering the render target of \a pipeline on \a canvas.
* \param canvas Canvas to render on * \param canvas Canvas to render on
* \param pipeline Pipeline to render * \param pipeline Pipeline to render
*/ */
TumVisPainter(tgt::GLCanvas* canvas, VisualizationPipeline* pipeline); CampVisPainter(tgt::GLCanvas* canvas, AbstractPipeline* pipeline);
/** /**
* Destructor, stops and waits for the rendering thread if it's still running. * Destructor, stops and waits for the rendering thread if it's still running.
*/ */
virtual ~TumVisPainter(); virtual ~CampVisPainter();
/// \see Runnable::stop /// \see Runnable::stop
void stop(); void stop();
...@@ -106,7 +106,7 @@ namespace campvis { ...@@ -106,7 +106,7 @@ namespace campvis {
* Pipeline with the render target to render. * Pipeline with the render target to render.
* \param pipeline Pipeline to render * \param pipeline Pipeline to render
*/ */
void setPipeline(VisualizationPipeline* pipeline); void setPipeline(AbstractPipeline* pipeline);
/** /**
* Slot being notified when the pipeline's render target changed. * Slot being notified when the pipeline's render target changed.
...@@ -121,7 +121,7 @@ namespace campvis { ...@@ -121,7 +121,7 @@ namespace campvis {
static const std::string loggerCat_; static const std::string loggerCat_;
VisualizationPipeline* _pipeline; ///< Pipeline to render AbstractPipeline* _pipeline; ///< Pipeline to render
tgt::Shader* _copyShader; ///< Shader for copying the render target to the framebuffer. tgt::Shader* _copyShader; ///< Shader for copying the render target to the framebuffer.
tbb::atomic<bool> _dirty; ///< Flag whether render result is dirty and needs to be rerendered. tbb::atomic<bool> _dirty; ///< Flag whether render result is dirty and needs to be rerendered.