2.12.2021, 9:00 - 11:00: Due to updates GitLab may be unavailable for some minutes between 09:00 and 11:00.

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

Refactoring pipeline concept #4: (Almost) got rid of hard pipeline definition...

Refactoring pipeline concept #4: (Almost) got rid of hard pipeline definition in campvis.cpp. Implemented console argument parsing in CampvisApplication dynamically adding the pipelines listed as arguments
parent 67cb4073
......@@ -66,27 +66,6 @@ int main(int argc, char** argv) {
#endif
CampVisApplication app(argc, argv);
// app.addVisualizationPipeline("Advanced Ultrasound Visualization", new AdvancedUsVis(app.getDataContainer()));
// app.addVisualizationPipeline("Confidence Map Generation", new CmBatchGeneration(app.getDataContainer()));
// app.addVisualizationPipeline("IXPV", new IxpvDemo(app.getDataContainer()));
app.addVisualizationPipeline("SliceVis", new SliceVis(app.getDataContainer()));
// app.addVisualizationPipeline("DVRVis", new DVRVis(app.getDataContainer()));
// app.addVisualizationPipeline("VolumeRendererDemo", new VolumeRendererDemo(app.getDataContainer()));
app.addVisualizationPipeline("VolumeExplorerDemo", new VolumeExplorerDemo(app.getDataContainer()));
#ifdef HAS_KISSCL
// app.addVisualizationPipeline("DVR with OpenCL", new OpenCLPipeline(app.getDataContainer()));
#endif
#ifdef CAMPVIS_HAS_MODULE_SCR_MSK
app.addVisualizationPipeline("US Compounding", new UsCompounding(app.getDataContainer()));
#endif
#ifdef CAMPVIS_HAS_MODULE_COLUMBIA
app.addVisualizationPipeline("Columbia", new Columbia1(app.getDataContainer()));
#endif
app.init();
int toReturn = app.run();
app.deinit();
......
......@@ -49,7 +49,6 @@
#include "core/tools/simplejobprocessor.h"
#include "core/tools/quadrenderer.h"
#include "core/pipeline/abstractpipeline.h"
#include "core/pipeline/autoevaluationpipeline.h"
#include "core/pipeline/pipelinefactory.h"
namespace campvis {
......@@ -79,7 +78,7 @@ namespace campvis {
tgtAssert(_initialized == false, "Destructing initialized CampVisApplication, deinitialize first!");
// delete everything in the right order:
for (std::vector< std::pair<AutoEvaluationPipeline*, CampVisPainter*> >::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;
}
for (std::vector<AbstractPipeline*>::iterator it = _pipelines.begin(); it != _pipelines.end(); ++it) {
......@@ -90,6 +89,14 @@ namespace campvis {
void CampVisApplication::init() {
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) {
AbstractPipeline* p = PipelineFactory::getRef().createPipeline(pipelinesToAdd[i].toStdString(), &_dataContainer);
if (p != 0)
addPipeline(pipelinesToAdd[i].toStdString(), p);
}
// Init TGT
tgt::InitFeature::Features featureset = tgt::InitFeature::ALL;
tgt::init(featureset);
......@@ -168,14 +175,12 @@ namespace campvis {
}
// Now init painters:
for (std::vector< std::pair<AutoEvaluationPipeline*, CampVisPainter*> >::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();
}
GLJobProc.start();
_initialized = true;
LINFO(PipelineFactory::getRef().toString());
}
void CampVisApplication::deinit() {
......@@ -193,7 +198,7 @@ namespace campvis {
}
// Now deinit painters:
for (std::vector< std::pair<AutoEvaluationPipeline*, CampVisPainter*> >::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();
}
......@@ -238,33 +243,25 @@ namespace campvis {
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.");
_pipelines.push_back(pipeline);
s_PipelinesChanged();
}
void CampVisApplication::addVisualizationPipeline(const std::string& name, AutoEvaluationPipeline* vp) {
tgtAssert(_initialized == false, "Adding pipelines after initialization is currently not supported.");
tgtAssert(vp != 0, "Pipeline must not be 0.");
// create canvas and painter for the VisPipeline and connect all together
// create canvas and painter for the pipeline and connect all together
tgt::QtThreadedCanvas* canvas = CtxtMgr.createContext(name, "CAMPVis", tgt::ivec2(512, 512));
GLJobProc.registerContext(canvas);
_mainWindow->addVisualizationPipelineWidget(name, canvas);
canvas->init();
CampVisPainter* painter = new CampVisPainter(canvas, vp);
CampVisPainter* painter = new CampVisPainter(canvas, pipeline);
canvas->setPainter(painter, false);
pipeline->setCanvas(canvas);
_visualizations.push_back(std::make_pair(vp, painter));
vp->setCanvas(canvas);
addPipeline(vp);
_visualizations.push_back(std::make_pair(pipeline, painter));
_pipelines.push_back(pipeline);
CtxtMgr.releaseCurrentContext();
s_PipelinesChanged();
}
void CampVisApplication::registerDockWidget(Qt::DockWidgetArea area, QDockWidget* dock) {
......
......@@ -48,7 +48,6 @@ namespace campvis {
class AbstractPipeline;
class MainWindow;
class CampVisPainter;
class AutoEvaluationPipeline;
/**
* The CampVisApplication class wraps Pipelines, Evaluators and Painters all together and takes
......@@ -91,25 +90,14 @@ namespace campvis {
void deinit();
/**
* Adds a pipeline which doesn't need visualization (OpenGL) support.
* Each pipeline will automatically get its own evaluator.
* Adds a pipeline to this CAMPVis application.
* 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 vp AutoEvaluationPipeline to add.
* \param vp AbstractPipeline to add.
*/
void addVisualizationPipeline(const std::string& name, AutoEvaluationPipeline* vp);
void addPipeline(const std::string& name, AbstractPipeline* pipeline);
/**
* Adds a dock widget to the main window.
......@@ -146,10 +134,10 @@ namespace campvis {
private:
/// The (currently) one and only DataContainer in CampvisApplication
DataContainer _dataContainer;
/// All pipelines (incuding VisualizationPipelines)
/// All pipelines
std::vector<AbstractPipeline*> _pipelines;
/// All visualisations (i.e. VisualizationPipelines with their corresponding painters/canvases)
std::vector< std::pair<AutoEvaluationPipeline*, CampVisPainter*> > _visualizations;
/// All visualisations (i.e. Pipelines with their corresponding painters/canvases)
std::vector< std::pair<AbstractPipeline*, CampVisPainter*> > _visualizations;
/// A local OpenGL context used for initialization
tgt::QtThreadedCanvas* _localContext;
......
......@@ -36,13 +36,36 @@ namespace campvis {
// declare one single symbol for the PipelineFactory singleton
tbb::atomic<PipelineFactory*> PipelineFactory::_singleton;
std::string PipelineFactory::toString() {
std::stringstream ss;
ss << _pipelineMap.size() << " Pipelines registered: ";
for (std::map< std::string, AbstractPipeline* (*)(DataContainer*) >::iterator it = _pipelineMap.begin(); it != _pipelineMap.end(); ++it) {
ss << it->first << ", ";
PipelineFactory& PipelineFactory::getRef() {
if (_singleton == 0) {
std::cout << "creating PipelineFactory...\n";
PipelineFactory* tmp = new PipelineFactory();
if (_singleton.compare_and_swap(tmp, 0) != 0) {
delete tmp;
}
}
return ss.str();
return *_singleton;
}
std::vector<std::string> PipelineFactory::getRegisteredPipelines() const {
tbb::spin_mutex::scoped_lock lock(_mutex);
std::vector<std::string> toReturn;
toReturn.reserve(_pipelineMap.size());
for (std::map<std::string, AbstractPipeline* (*)(DataContainer*)>::const_iterator it = _pipelineMap.begin(); it != _pipelineMap.end(); ++it)
toReturn.push_back(it->first);
return toReturn;
}
AbstractPipeline* PipelineFactory::createPipeline(const std::string& id, DataContainer* dc) const {
tbb::spin_mutex::scoped_lock lock(_mutex);
std::map<std::string, AbstractPipeline* (*)(DataContainer*)>::const_iterator it = _pipelineMap.find(id);
if (it == _pipelineMap.end())
return 0;
else
return (it->second)(dc);
}
}
\ No newline at end of file
......@@ -34,7 +34,7 @@
#include "tgt/singleton.h"
#include <tbb/atomic.h>
#include <tbb/mutex.h>
#include <tbb/spin_mutex.h>
#include <map>
#include <string>
......@@ -58,17 +58,11 @@ namespace campvis {
* Creates the singleton if necessary
* \return *_singleton
*/
static PipelineFactory& getRef() {
if (_singleton == 0) {
std::cout << "creating PipelineFactory...\n";
PipelineFactory* tmp = new PipelineFactory();
if (_singleton.compare_and_swap(tmp, 0) != 0) {
delete tmp;
}
}
static PipelineFactory& getRef();
return *_singleton;
}
std::vector<std::string> getRegisteredPipelines() const;
AbstractPipeline* createPipeline(const std::string& id, DataContainer* dc) const;
/**
* Statically registers the pipeline of type T using \a callee as factory method.
......@@ -78,19 +72,24 @@ namespace campvis {
*/
template<typename T>
size_t registerPipeline(AbstractPipeline* (* callee)(DataContainer*)) {
std::cout << "registering pipeline " << T::getId() << "...\n";
_pipelineMap[T::getId()] = callee;
//_pipelines.push_back(callee);
tbb::spin_mutex::scoped_lock lock(_mutex);
std::map<std::string, AbstractPipeline* (*)(DataContainer*)>::iterator it = _pipelineMap.lower_bound(T::getId());
if (it == _pipelineMap.end() || it->first != T::getId()) {
_pipelineMap.insert(it, std::make_pair(T::getId(), callee));
}
else {
tgtAssert(false, "Registered two pipelines with the same ID.");
}
return _pipelineMap.size();
}
/// just a simple test function
std::string toString();
private:
mutable tbb::spin_mutex _mutex;
static tbb::atomic<PipelineFactory*> _singleton; ///< the singleton object
std::vector< AbstractPipeline* (*)(DataContainer*) > _pipelines;
std::map< std::string, AbstractPipeline* (*)(DataContainer*) > _pipelineMap;
std::map<std::string, AbstractPipeline* (*)(DataContainer*)> _pipelineMap;
};
......
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